websocket
API reference for the websocket package, generated from Go doc comments.
import "github.com/grx-gql/grx/websocket"Package websocket provides an RFC 6455 WebSocket implementation tailored for GraphQL subscription transports. It implements core.Transport for both the modern graphql-transport-ws subprotocol and the legacy graphql-ws (Apollo subscriptions-transport-ws) subprotocol.
Index
- Constants
- func IsTimeout(err error) bool
- func IsUpgrade(r *http.Request) bool
- type Config
- type Conn
- type WebSocketTransport
Constants
OpcodeContinuation
Frame opcodes from RFC 6455 §5.2. Exported so callers can inspect the frames produced by the transport.
const (
OpcodeContinuation byte = 0x0
OpcodeText byte = 0x1
OpcodeBinary byte = 0x2
OpcodeClose byte = 0x8
OpcodePing byte = 0x9
OpcodePong byte = 0xA
)DefaultMaxMessageSize
Default values applied when the corresponding Config field is left zero.
const (
DefaultMaxMessageSize = 1 << 20 // 1 MiB
DefaultConnectionInitTimeout = 3 * time.Second
)Subprotocol
Subprotocol is the only WebSocket subprotocol this transport speaks. The legacy Apollo subscriptions-transport-ws ("graphql-ws") protocol is intentionally not supported; it was deprecated in 2021 and clients that have not migrated should upgrade rather than be carried indefinitely.
const Subprotocol = "graphql-transport-ws"func IsTimeout
func IsTimeout(err error) boolIsTimeout reports whether err originated from a deadline exceeded on the underlying connection. The dispatcher uses this to map a missed connection_init into the correct close code.
func IsUpgrade
func IsUpgrade(r *http.Request) boolIsUpgrade reports whether r is a well-formed WebSocket upgrade request.
type Config
Config tunes WebSocketTransport. All fields are optional; zero values fall back to safe production defaults documented per field.
type Config struct {
// ConnectionInitTimeout is the maximum time the dispatcher waits for a
// ConnectionInit message after the WebSocket handshake completes. Once
// exceeded, the connection is closed with code 4408. Zero defaults to
// DefaultConnectionInitTimeout (3s); a negative value disables the
// timeout.
ConnectionInitTimeout time.Duration
// ReadIdleTimeout caps the time the dispatcher will wait for any next
// frame from the peer once the connection is initialised. The deadline
// resets after each successful ReadMessage. Zero disables the timeout.
ReadIdleTimeout time.Duration
// WriteTimeout caps a single frame write. Slow consumers that fail to
// drain a frame within the deadline are closed; this is the primary
// backpressure protection. Zero disables the timeout.
WriteTimeout time.Duration
// MaxMessageSize bounds the total decoded payload of a single
// (potentially fragmented) message. Zero defaults to
// DefaultMaxMessageSize. A negative value disables the limit.
MaxMessageSize int64
// CheckOrigin authorises the Origin header during the handshake.
// Returning false fails the upgrade with HTTP 403. nil accepts every
// origin and should not be used for browser-facing deployments.
CheckOrigin func(r *http.Request) bool
// OnConnect is invoked when the first ConnectionInit message arrives.
// It receives the request-scoped context and the raw init payload
// (typically containing auth tokens). Implementations may either:
//
// - Return a derived context (used as the parent for every
// subscription on the connection) and an optional ack payload.
// A nil ack payload omits the payload from the ack message.
//
// - Return an error to reject the connection. The socket is closed
// with code 4403 Forbidden.
OnConnect func(ctx context.Context, payload json.RawMessage) (context.Context, json.RawMessage, error)
// PingInterval, when non-zero, makes the server send application-level
// ping messages on this cadence. The peer is expected to respond with
// pong; absence of pong combined with ReadIdleTimeout causes the
// connection to close.
PingInterval time.Duration
}type Conn
Conn is a server-side WebSocket connection. Reads are single-threaded and happen on the dispatcher goroutine; writes are guarded by a mutex so concurrent goroutines (e.g. subscription dispatchers, server-side ping) can push frames safely.
type Conn struct {
// contains filtered or unexported fields
}func (*Conn) Close
func (c *Conn) Close() errorClose terminates the underlying network connection.
func (*Conn) ReadMessage
func (c *Conn) ReadMessage() (opcode byte, payload []byte, err error)ReadMessage reads the next text or binary message from the peer, reassembling fragmented frames and responding to ping and close control frames automatically. It enforces the RFC 6455 framing rules: control frames must be unfragmented and ≤125 bytes, reserved bits must be zero, continuation frames must follow an in-flight data message, and text messages must be valid UTF-8.
func (*Conn) SendClose
func (c *Conn) SendClose(code uint16, reason string)SendClose sends a WebSocket close frame with the given code and reason and marks the connection as closed for further writes.
func (*Conn) SetReadDeadline
func (c *Conn) SetReadDeadline(t time.Time) errorSetReadDeadline sets the absolute time after which a pending read will fail. A zero value disables the deadline. Dispatchers use it to enforce the connection_init timeout and the read idle timeout.
func (*Conn) Subprotocol
func (c *Conn) Subprotocol() stringSubprotocol returns the negotiated WebSocket subprotocol, or the empty string if no subprotocol was agreed upon.
func (*Conn) WriteText
func (c *Conn) WriteText(payload []byte) errorWriteText writes a complete UTF-8 text frame to the peer. Concurrent writes are serialised through the connection's mutex; the configured write deadline (if any) protects against slow consumers.
type WebSocketTransport
WebSocketTransport implements core.Transport for the graphql-transport-ws subprotocol. Construct with New; the zero value also works and applies all defaults.
type WebSocketTransport struct {
// contains filtered or unexported fields
}func New
func New(cfg ...Config) *WebSocketTransportNew returns a WebSocketTransport ready to be registered with the server.
func (*WebSocketTransport) Match
func (*WebSocketTransport) Match(r *http.Request) boolMatch reports whether r is a WebSocket upgrade request.
func (*WebSocketTransport) Serve
func (t *WebSocketTransport) Serve(w http.ResponseWriter, r *http.Request, executor core.Executor)Serve performs the WebSocket handshake, verifies that the negotiated subprotocol is graphql-transport-ws, and runs the dispatcher loop for the lifetime of the session.
Generated by gomarkdoc
Last updated on