coder/websocket

repository·master·Indexed 26 days ago

https://github.com/coder/websocket

A Go implementation for WebSocket communication focusing on efficient message handling through Reader and Writer interfaces. It provides functionality for dialing and accepting connections, managing cross-origin authorization via OriginPatterns, and configuring permessage-deflate compression modes. The library includes the wsjson subpackage for JSON and Protobuf messages, and a NetConn wrapper to tunnel arbitrary protocols over WebSockets by converting a *websocket.Conn into a net.Conn.

Tokens
4.2K
Snippets
1
Records
38
Agent score
89%

What's inside coder/websocket

  1. Wasm client-side caveats

    master

    When compiling the client side to WebAssembly (Wasm), the library wraps the browser WebSocket API. Be aware of the following limitations in the Wasm environment:

    • Accept always returns an error.
    • Conn.Ping is a no-op.
    • Conn.CloseNow performs a Close(StatusGoingAway, "").
    • HTTPClient, HTTPHeader, and CompressionMode in DialOptions are no-ops.
    • A successful Dial returns an *http.Response that is an empty struct (&http.Response{}) with a 101 status code.
  2. Authorize cross-origin WebSockets using OriginPatterns

    master

    By default, Accept rejects cross-origin requests. To allow specific origins, use the OriginPatterns field in AcceptOptions. Each pattern is matched case-insensitively using path.Match.

    Example: If a client running on example.com wants to connect to a server at chat.example.com, you would set OriginPatterns to []string{"example.com"} to authorize it.

  3. Configure AcceptOptions for WebSocket handshakes

    master

    The AcceptOptions struct allows you to customize the WebSocket handshake behavior.

    Key configuration fields:

    • Subprotocols: A list of WebSocket subprotocols to negotiate. The empty subprotocol is always negotiated per RFC 6455.
    • InsecureSkipVerify: If true, disables origin verification. Use with caution as it can expose the server to CSRF attacks.
    • OriginPatterns: A list of host patterns (matched via path.Match) used to authorize cross-origin requests. If a pattern contains ://, it is matched against scheme://host.
    • CompressionMode: Controls whether and how message compression is used. Defaults to CompressionDisabled.
    • CompressionThreshold: The minimum message size (in bytes) required before compression is applied. Defaults to 512 bytes for CompressionNoContextTakeover and 128 bytes for CompressionContextTakeover.
    • OnPingReceived: A synchronous callback invoked when a ping frame is received. Returning false prevents the subsequent pong frame from being sent.
    • OnPongReceived: A synchronous callback invoked when a pong frame is received.
  4. Extract the status code from a CloseError

    master

    When a connection is closed, the error may be a CloseError. Use CloseStatus(err error) to safely extract the StatusCode.

    • Returns the StatusCode if the error is a CloseError.
    • Returns -1 if the error is nil or not a CloseError.
  5. Accept a WebSocket connection with Accept()

    master
    Use Accept to upgrade an incoming http.Request to a WebSocket connection. This function handles the handshake, validates the request, negotiates subprotocols and compression, and performs origin verification. If an error occurs during the handshake, Accept will automatically write an appropriate error response to the http.ResponseWriter.
  6. Stream a message using Writer()

    master

    For large messages or streaming data, use the Writer method. It returns an io.WriteCloser that allows you to write data in chunks.

    Important constraints:

    • You must call Close() on the returned writer once the entire message has been written.
    • Only one writer can be open at a time; subsequent calls to Writer will block until the previous writer is closed.
  7. Dial a WebSocket connection in WebAssembly

    master

    Use Dial to establish a new WebSocket connection to a given URL. In a WebAssembly environment, this function wraps the browser's WebSocket API. The returned *http.Response is a mock used to maintain API compatibility with the core library.

    Pass a context.Context to bound the time spent waiting for the connection to open. You can provide DialOptions to negotiate subprotocols.

  8. Close a WebSocket connection with a handshake

    master

    Use Conn.Close(code StatusCode, reason string) to perform a graceful WebSocket close handshake.

    • It writes a close frame with a 5s timeout.
    • It waits up to 5s for the peer to respond with a close frame.
    • All data messages received during the handshake are discarded.
    • The reason string must not exceed 125 bytes.
    • Additional calls to Close are no-ops.
    • This method unblocks all goroutines interacting with the connection once complete.
  9. Send a Ping and wait for a Pong

    master

    The Ping(ctx context.Context) method sends a ping frame to the peer and waits for a pong response. This is useful for measuring latency or ensuring the peer is still responsive.

    Important: Ping must be called concurrently with a Reader (or a call to Read). Ping itself does not read from the connection; it relies on the active reader to process the incoming pong frame.

  10. Read messages from a WebSocket connection

    master

    Use Read to retrieve the next message from the connection. It returns the MessageType (Text or Binary), the message payload as a byte slice, and an error if the read fails or the context is canceled.

    To read messages as an io.Reader, use the Reader method instead.

  11. Write messages to a WebSocket connection

    master

    Use Write to send a message of a specific MessageType to the connection. In WebAssembly, this operation is non-blocking.

    Alternatively, use Writer to get an io.WriteCloser. The Writer buffers the entire message in memory and sends it only when Close() is called.