WebSocket
Upgrade HTTP connections and exchange text, binary, or JSON messages.
WebSocket
The websocket package upgrades a Ply route and runs a connection handler.
import "github.com/Dziqha/ply/websocket"
app.Get("/ws", websocket.New().Handler(func(client *websocket.Client) {
for {
messageType, message, err := client.ReadMessage()
if err != nil {
return
}
if err := client.WriteMessage(messageType, message); err != nil {
return
}
}
}))The handler blocks for the lifetime of the connection. Return from it when the read loop ends so Ply can close the connection and stop its ping goroutine.
Options
| Option | Default | Purpose |
|---|---|---|
HandshakeTimeout | 5s | Maximum time for the upgrade |
ReadBufferSize | 4096 | Read buffer size |
WriteBufferSize | 4096 | Write buffer size |
Subprotocols | none | Accepted WebSocket subprotocols |
CheckOrigin | same-host check | Validates the Origin header |
EnableCompression | false | Enables per-message compression |
ReadLimit | 1 MiB | Maximum incoming message size |
PingInterval | 30s | Server ping interval |
PongWait | 60s | Read deadline refreshed by pongs |
WriteWait | 10s | Write deadline |
DisablePing | false | Disables the ping loop |
CheckOrigin receives the fasthttp request context:
CheckOrigin: func(ctx *fasthttp.RequestCtx) bool {
origin := string(ctx.Request.Header.Peek("Origin"))
return origin == "https://app.example.com"
},The default check rejects an Origin whose host does not match the request
host. Keep it enabled unless the application has a specific cross-origin
requirement.
Reading and writing
| Method | Purpose |
|---|---|
ReadMessage() | Returns the message type and bytes |
ReadJSON(dest) | Decodes one JSON message |
WriteMessage(type, data) | Writes text or binary data |
WriteText(data) | Writes a text message |
WriteBinary(data) | Writes a binary message |
WriteJSON(value) | Encodes and writes one JSON message |
Ping(data) | Sends a ping control frame |
Close() | Closes the connection |
CloseWith(code, text) | Closes with a status code and reason |
WriteMessage, WriteText, WriteBinary, WriteJSON, Ping, and
CloseWith serialize writes internally. A handler can still read from one
goroutine and write from another.
Raw() exposes the underlying *websocket.Conn for features not covered by
Client. Do not write through Raw() while another goroutine writes through
Client.
Authentication
Middleware runs before the upgrade, so the connection can be protected like any other route:
app.Get("/ws", authMiddleware, websocket.New().Handler(handleConnection))If authentication needs a token from the first WebSocket message instead, close the connection with an application close code when validation fails.
Reverse proxies
An HTTP proxy must forward the Upgrade and Connection headers. For nginx:
location /ws {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}WebSocket connections are long-lived. Apply connection and message limits at the proxy for public endpoints.
Notes
- A single process keeps each connection in memory. Use a shared pub/sub layer when clients connected to different instances must receive the same event.
ReadLimitprotects the process from oversized messages. Set it to the largest payload the application expects.- The server ping keeps idle connections alive and detects dead peers. The ping loop stops when the handler returns or a ping fails.

Ply