I have simple client - server websocket communication and I want to know if it's possible to enable message compression for the websockets. I am using Golang library gorila/websocket.
And there are configurations like EnableCompression bool or EnableWriteCompression(bool) method, but it does not working as expected or maybe I cannot figure out how to use it.
Expected behaviour:
I am expecting to send for example - 50kb message and to be compressed to 10-20kb or something like this. But it seems that EnableWriteCompression is not working as expected or I am not using it in the right way.
The code:
server.go:
package main
import (
"fmt"
"github.com/gorilla/websocket"
"log"
"net/http"
)
var upgrader = websocket.Upgrader{}
func socketHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
conn.EnableWriteCompression(true)
if err != nil {
log.Print("Error during upgrade:", err)
return
}
defer conn.Close()
n := 0
for n <= 10 {
messageType, message, err := conn.ReadMessage()
if err != nil {
log.Println("Error during message reading:", err)
break
}
log.Printf("Received: %s", message)
err = conn.WriteMessage(messageType, message)
if err != nil {
log.Println("Error during message writing:", err)
break
}
n++
}
}
func home(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Index Page")
}
func main() {
http.HandleFunc("/socket", socketHandler)
http.HandleFunc("/", home)
log.Fatal(http.ListenAndServe("localhost:8080", nil))
}
client.go:
// client.go
package main
import (
"log"
"os"
"os/signal"
"time"
"github.com/gorilla/websocket"
)
var done chan interface{}
var interrupt chan os.Signal
func receiveHandler(connection *websocket.Conn) {
defer close(done)
for {
_, msg, err := connection.ReadMessage()
if err != nil {
log.Println("Error in receive:", err)
return
}
log.Printf("Received: %s\n", msg)
}
}
func main() {
done = make(chan interface{}) // Channel to indicate that the receiverHandler is done
interrupt = make(chan os.Signal) // Channel to listen for interrupt signal to terminate gracefully
signal.Notify(interrupt, os.Interrupt) // Notify the interrupt channel for SIGINT
socketUrl := "ws://localhost:8080" + "/socket"
conn, _, err := websocket.DefaultDialer.Dial(socketUrl, nil)
if err != nil {
log.Fatal("Error connecting to Websocket Server:", err)
}
defer conn.Close()
go receiveHandler(conn)
// Our main loop for the client
// We send our relevant packets here
for {
select {
case <-time.After(time.Duration(1) * time.Millisecond * 1000):
conn.EnableWriteCompression(true)
conn.SetCompressionLevel(1)
err := conn.WriteMessage(websocket.TextMessage, []byte("Some message to send!"))
if err != nil {
log.Println("Error during writing to websocket:", err)
return
}
case <-interrupt:
log.Println("Received SIGINT interrupt signal. Closing all pending connections")
err := conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println(err)
return
}
select {
case <-done:
log.Println("Exiting....")
case <-time.After(time.Duration(1) * time.Second):
log.Println("Exiting....")
}
return
}
}
}