Chore: Compress websocket messages once per broadcast to improve performance (#695)

This commit is contained in:
Ralph Slooten
2026-06-11 20:09:42 +12:00
parent ddfeab89d9
commit 8747cd81f9
2 changed files with 10 additions and 4 deletions

View File

@@ -47,7 +47,7 @@ type Client struct {
conn *websocket.Conn
// Buffered channel of outbound messages.
send chan []byte
send chan *websocket.PreparedMessage
}
// ReadPump is used here solely to monitor the connection, not to actually receive messages.
@@ -90,7 +90,7 @@ func (c *Client) writePump() {
return
}
if err := c.conn.WriteMessage(websocket.TextMessage, message); err != nil {
if err := c.conn.WritePreparedMessage(message); err != nil {
return
}
case <-ticker.C:
@@ -124,7 +124,7 @@ func ServeWs(hub *Hub, w http.ResponseWriter, r *http.Request) {
return
}
client := &Client{hub: hub, conn: conn, send: make(chan []byte, 256)}
client := &Client{hub: hub, conn: conn, send: make(chan *websocket.PreparedMessage, 256)}
client.hub.register <- client
// Allow collection of memory referenced by the caller by doing all work in new goroutines.

View File

@@ -6,6 +6,7 @@ import (
"sync/atomic"
"github.com/axllent/mailpit/internal/logger"
"github.com/gorilla/websocket"
)
// Hub maintains the set of active clients and broadcasts messages to the
@@ -61,9 +62,14 @@ func (h *Hub) Run() {
h.clientCount.Add(-1)
}
case message := <-h.Broadcast:
prepared, err := websocket.NewPreparedMessage(websocket.TextMessage, message)
if err != nil {
logger.Log().Errorf("[websocket] error preparing message: %s", err.Error())
continue
}
for client := range h.Clients {
select {
case client.send <- message:
case client.send <- prepared:
default:
close(client.send)
delete(h.Clients, client)