wsclient

package
v0.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package wsclient implements a minimal RFC 6455 WebSocket client on the standard library alone: client role only, no extensions, no compression, no subprotocol negotiation. Its first consumer is the Discord Gateway adapter.

Concurrency contract: exactly one goroutine calls Conn.ReadMessage; Conn.WriteText, Conn.WriteClose, and the automatic pong replies are serialized by an internal mutex and are safe from any goroutine. Heartbeats are the caller's job — this layer is protocol-only. After any error the Conn is dead; callers reconnect rather than recover.

Index

Constants

View Source
const (
	// OpText identifies a UTF-8 text message.
	OpText = 1
	// OpBinary identifies a binary message.
	OpBinary = 2
)

Data opcodes returned by Conn.ReadMessage. Control opcodes (close, ping, pong) are handled internally and never surface to the caller.

Variables

This section is empty.

Functions

This section is empty.

Types

type CloseError

type CloseError struct {
	// Code is the close status code. 1005 means the peer's close frame
	// carried no code; 1006 never travels on the wire and is synthesized
	// locally on abnormal TCP loss.
	Code int
	// Reason is the close reason, possibly empty.
	Reason string
}

CloseError is the error returned by Conn.ReadMessage when the connection ends with a close frame, or with a locally synthesized code on abnormal transport loss.

func (*CloseError) Error

func (e *CloseError) Error() string

Error implements the error interface.

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is a WebSocket client connection established by Dial. See the package comment for the concurrency contract.

func Dial

func Dial(ctx context.Context, rawURL string, header http.Header, opts *Options) (*Conn, error)

Dial opens a WebSocket connection to rawURL (ws or wss scheme), performs the RFC 6455 opening handshake with the extra request headers in header (which may be nil), and returns the established connection. ctx bounds the whole dial: TCP connect, TLS, and the HTTP handshake.

ponytail: no proxy, redirect, or subprotocol support, and no permessage-deflate — the Discord gateway needs none of it.

func (*Conn) Close

func (c *Conn) Close() error

Close tears down the TCP connection immediately, without a close handshake (the peer observes an abnormal closure, 1006). It is idempotent and safe from any goroutine.

func (*Conn) ReadMessage

func (c *Conn) ReadMessage(ctx context.Context) (opcode int, payload []byte, err error)

ReadMessage reads the next complete data message, transparently handling control frames: pings are answered with pongs, pongs are dropped, and a close frame ends the connection and returns a *CloseError. Fragmented messages are reassembled before returning; opcode is OpText or OpBinary. Exactly one goroutine may call ReadMessage. Cancelling ctx interrupts a blocked read and returns ctx.Err(); as after any other error, the Conn is then unusable.

func (*Conn) WriteClose

func (c *Conn) WriteClose(code int, reason string) error

WriteClose sends a close frame with the given status code and reason (at most 123 bytes) and marks the connection closing; later writes fail. The caller should keep calling ReadMessage until it returns the peer's *CloseError, then call Conn.Close. Calling WriteClose after a close frame was already sent is a no-op.

func (*Conn) WriteText

func (c *Conn) WriteText(data []byte) error

WriteText sends data as a single masked, unfragmented text frame. It is safe to call from any goroutine and fails once a close frame was sent.

ponytail: no WriteBinary, WritePing, or fragmented writes — Discord sends only whole text frames; add them when a consumer needs them.

type Options

type Options struct {
	// MaxMessageSize caps the size in bytes of a reassembled incoming
	// message. A larger message fails the connection with close code 1009.
	// Default 4 MiB.
	MaxMessageSize int64
	// WriteTimeout is the per-frame write deadline. Default 10s.
	WriteTimeout time.Duration
	// TLSConfig overrides the TLS configuration for wss URLs, e.g. to trust
	// a test server certificate. Nil uses defaults, with ServerName taken
	// from the URL.
	TLSConfig *tls.Config
}

Options configures Dial. A nil *Options selects every default.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL