LogoPly
Features

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

OptionDefaultPurpose
HandshakeTimeout5sMaximum time for the upgrade
ReadBufferSize4096Read buffer size
WriteBufferSize4096Write buffer size
SubprotocolsnoneAccepted WebSocket subprotocols
CheckOriginsame-host checkValidates the Origin header
EnableCompressionfalseEnables per-message compression
ReadLimit1 MiBMaximum incoming message size
PingInterval30sServer ping interval
PongWait60sRead deadline refreshed by pongs
WriteWait10sWrite deadline
DisablePingfalseDisables 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

MethodPurpose
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.
  • ReadLimit protects 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.