Documentation
¶
Overview ¶
Package websocket is a lightweight yet robust client-only implementation of the WebSocket protocol (RFC 6455).
It focuses on continuous asynchronous reading of text/binary messages, and enables occasional writing.
It is designed primarily for ease of use and availability at scale. Additional design goals: reliability, maintainability, and efficiency.
How does this package optimize for availability at scale?
- In-memory map of active clients, keyed by (a secure hash of) their ID, to minimize the number of open connections per app
- Preemptively switch connections before each anticipated disconnection, to prevent downtime during reconnections
- Fast detection and recovery from unexpected disconnections
- Idiomatic, minimalistic, and modern code patterns
Note A: optimization 1 relies on Go channels to dispatch and potentially fan-out messages efficiently and reliably.
Note B: optimization 2 requires careful balancing of optimization 1 with ensuring state isolation, correct and efficient garbage collection, and ensuring that users of this package do not receive duplicate copies of messages while a client temporarily has an extra connection.
Note C: WebSocket extensions and subprotocols are not supported yet.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Client ¶ added in v0.2.0
type Client struct {
// contains filtered or unexported fields
}
Client is a long-running wrapper of connections to the same WebSocket server with the same credentials. It usually manages a single Conn, except when it gets disconnected, or is about to be, in which case the client automatically opens another Conn and switches to it seamlessly, to prevent or at least minimize downtime during reconnections.
func NewOrCachedClient ¶ added in v0.2.0
func (*Client) IncomingMessages ¶ added in v0.2.0
IncomingMessages returns the client's channel that publishes data [Message]s as they are received from the server.
func (*Client) RefreshConnectionIn ¶ added in v0.2.0
RefreshConnectionIn instructs the client to replace its underlying Conn seamlessly after the given duration of time. This prevents unnecessary downtime during normal reconnections, which is useful in connections where the disconnection time is known or coordinated in advance.
type Conn ¶
type Conn struct {
// contains filtered or unexported fields
}
Conn respresents the configuration and state of an open client connection to a WebSocket server.
func Dial ¶
Dial performs a WebSocket handshake to establish a connection to the given URL ("ws://..." or "wss://").
func (*Conn) Close ¶
func (c *Conn) Close(s StatusCode)
Close performs a WebSocket closing handshake to initiate the closure of an open connection.
func (*Conn) IncomingMessages ¶
IncomingMessages returns the connection's channel that publishes data [Message]s as they are received from the server.
func (*Conn) SendBinaryMessage ¶
SendBinaryMessage sends a binary message to the server.
This is done asynchronously, to manage isolation or safe multiplexing of multiple concurrent calls, including interleaved control frames. Despite that, this function enables the caller to block and/or handle errors, with the returned channel.
func (*Conn) SendTextMessage ¶
SendTextMessage sends a UTF-8 text message to the server.
This is done asynchronously, to manage isolation or safe multiplexing of multiple concurrent calls, including interleaved control frames. Despite that, this function enables the caller to block and/or handle errors, with the returned channel.
type DialOpt ¶ added in v0.2.0
type DialOpt func(*Conn)
func WithHTTPClient ¶
WithHTTPClient lets callers of Dial specify a custom http.Client to use for the WebSocket handshake, instead of http.DefaultClient.
Do not specify a custom timeout in the HTTP client! This will interfere with the long-lived WebSocket connection beyond the scope of its initial handshake. Instead, use context.WithTimeout with the context.Context passed to Dial.
func WithHTTPHeader ¶
WithHTTPHeader lets callers of Dial add a single HTTP header to the WebSocket handshake's HTTP request. Use WithHTTPHeaders to specify multiple ones.
func WithHTTPHeaders ¶
WithHTTPHeaders lets callers of Dial add multiple HTTP headers to the WebSocket handshake's HTTP request, instead of calling WithHTTPHeader multiple times.
type Message ¶ added in v0.2.0
WebSocket data message, from one or more (defragmented) data frames, as defined in https://datatracker.ietf.org/doc/html/rfc6455#section-5.6. Returned by the Go channel that is exposed by Conn.IncomingMessages.
type Opcode ¶
type Opcode int
Opcode denotes the type of a WebSocket frame, as defined in https://datatracker.ietf.org/doc/html/rfc6455#section-5.2 and https://datatracker.ietf.org/doc/html/rfc6455#section-11.8.
const ( OpcodeText Opcode OpcodeBinary )
type StatusCode ¶
type StatusCode int
StatusCode indicates a reason for the closure of an established WebSocket connection, as defined in https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.
See also https://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number.
Other status code ranges:
- 0-999: not used
- 3000-3999: reserved for use by libraries, frameworks, and applications
- 4000-4999: reserved for private use and thus can't be registered
const ( // The purpose for which the connection was established has been fulfilled. StatusNormalClosure StatusCode = iota + 1000 // An endpoint is "going away", such as a server going // down or a browser having navigated away from a page. StatusGoingAway // An endpoint is terminating the connection due to a protocol error. StatusProtocolError // An endpoint is terminating the connection because it has received a // type of data it cannot accept (e.g., an endpoint that understands // only text data MAY send this if it receives a binary message). StatusUnsupportedData // Reserved value, MUST NOT be set as a status code in a Close control // frame by an endpoint. It is designated for use in applications expecting // a status code to indicate that no status code was actually present. StatusNotReceived // Reserved value, MUST NOT be set as a status code in a Close control // frame by an endpoint. It is designated for use in applications expecting // a status code to indicate that the connection was closed abnormally, // e.g., without sending or receiving a Close control frame. StatusClosedAbnormally // An endpoint is terminating the connection because it has received data // within a message that was not consistent with the type of the message // (e.g., non-UTF-8 RFC 3629 data within a text message). StatusInvalidData // An endpoint is terminating the connection because it has received a message // that violates its policy. This is a generic status code that can be returned // when there is no other more suitable status code (e.g., 1003 or 1009) // or if there is a need to hide specific details about the policy. StatusPolicyViolation // An endpoint is terminating the connection because it has // received a message that is too big for it to process. StatusMessageTooBig // An endpoint (client) is terminating the connection because it has expected the // server to negotiate one or more extensions, but the server didn't return them in // the response message of the WebSocket handshake. The list of extensions that are // needed SHOULD appear in the /reason/ part of the Close frame. Note that this status // code is not used by the server, because it can fail the WebSocket handshake instead. StatusMandatoryExtension // A remote endpoint is terminating the connection because it encountered // an unexpected condition that prevented it from fulfilling the request. // See https://www.rfc-editor.org/errata_search.php?eid=3227. StatusInternalError // See https://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number. StatusServiceRestart // See https://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number. StatusTryAgainLater // See https://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number. StatusBadGateway // Reserved value, MUST NOT be set as a status code in a Close control frame // by an endpoint. It is designated for use in applications expecting a status // code to indicate that the connection was closed due to a failure to perform // a TLS handshake (e.g., the server certificate can't be verified). StatusTLSHandshake )
func (StatusCode) String ¶
func (s StatusCode) String() string
String returns the status code's name, or its number if it's unrecognized.