Documentation
¶
Index ¶
- Constants
- func IsReservedEvent(eventName string) bool
- type Client
- type ClientChannel
- func (c ClientChannel) Emit(ctx context.Context, arguments ...any) error
- func (c ClientChannel) Name() string
- func (c ClientChannel) On(eventName string, handler any) ClientChannel
- func (c ClientChannel) Once(eventName string, handler any) ClientChannel
- func (c ClientChannel) Request(ctx context.Context, arguments ...any) (response any, err error)
- type ClientError
- type CloseHandler
- type Conn
- type ErrorHandler
- type HandlerContextFunc
- type Message
- type MessageHandler
- type OpenHandler
- type Server
- type ServerChannel
- type StatusCode
Examples ¶
Constants ¶
const ( EventOpen = "open" EventConnect = "connect" EventError = "error" EventMessage = "message" EventClose = "close" EventDisconnect = "disconnect" )
List of reserved event names. It is an error to send or receive events on the main channel with these event names.
const ClientKey = contextKey("client")
ClientKey is the value to be passed to the context's Value method to return the *wrapper.Client object that emitted the event.
Variables ¶
This section is empty.
Functions ¶
func IsReservedEvent ¶
IsReservedEvent checks if the event name is a reserved event name
Types ¶
type Client ¶
type Client struct { ClientChannel // the "main" client channel with no name // contains filtered or unexported fields }
Client represents a WebSocket client
func ClientFromContext ¶ added in v1.1.0
ClientFromContext returns the WebSocket client from the given context. Returns nil if not available.
func (*Client) Close ¶
func (c *Client) Close(status StatusCode, reason string) error
Close closes the client connection and removes it from the list of clients connected to the server.
func (*Client) Of ¶
func (c *Client) Of(name string) ClientChannel
Of returns a channel for the given name
type ClientChannel ¶
type ClientChannel struct {
// contains filtered or unexported fields
}
ClientChannel is a channel on which events can be sent and received. Events emitted or requests sent are sent to the specific client's channel on the remote end. See ClientChannel.On for more information about how received events are handled.
func (ClientChannel) Emit ¶
func (c ClientChannel) Emit(ctx context.Context, arguments ...any) error
Emit sends an event to the client on the specified channel. The passed context can be used to cancel writing the message to the client. The second argument is the event name that tells the remote end which event handler to call. Returns an error if there was an error sending the message to the client.
func (ClientChannel) Name ¶
func (c ClientChannel) Name() string
Name returns the name of the channel
func (ClientChannel) On ¶
func (c ClientChannel) On(eventName string, handler any) ClientChannel
On adds an event handler for the specified event to the channel. When an event or request is received from a client, only a single handler is called. The priority of handlers called is as follows:
1. Handlers added via ClientChannel.Once
2. Handlers added via ClientChannel.On
3. Handlers added via ServerChannel.Once
4. Handlers added via ServerChannel.On
Therefore, if a handler is added to a ClientChannel, the corresponding handler on the ServerChannel will never be called for that particular client.
handler must be a function with arbitrary parameters, but it must return one or two values: a request result and an error. The request result is optional and may be of any type, but the error is required and must implement the error interface. When the event handler is called, the arguments of the event are converted to the types expected by handler. If an argument is not convertible to its parameter type (see reflect.Type.ConvertibleTo), the handler is not called and an error is returned to the client; however, there are some notable exceptions to this rule:
if the argument is a `nil` interface type and the parameter is a type that can accept `nil`, then `nil` is supplied as the argument
if the parameter is a pointer type, the address of the argument will be taken after type conversion
if the argument and parameters are slices of convertible types, each element in the slice will be converted into a new slice and supplied as the argument
Optionally, the handler can provide an additional parameter for the context.Context of the request. Call ClientFromContext(ctx) to return the *Client object for the client that emitted the event.
There are also reserved events can occur on the main channel of a client:
"error" - called when an error occurs on the client. The handler is passed the error as a single argument and has the form `func(*Client, error)`
"message" - called when a message is received from the client. The handler is passed the Message as a single argument and has the form `func(*Client, Message)`. The handler may not modify the message; this event is primarily for logging purposes.
"close" or "disconnect" - called when the client disconnects. The handler is passed the status code and reason and has the form `func(*Client, StatusCode, string)`
The reserved events that can occur on the main channel of a server include:
"open" or "connect" - called when a new client connects. The handler is passed the client and has the form `func(*Client)`
"error"
"close" or "disconnect" - called when any client disconnects.
If event handlers do not conform to the expected function signature, On will panic.
If On is called multiple times for the same event name, the last handler will be used. If handler is nil, the event handler is removed.
func (ClientChannel) Once ¶
func (c ClientChannel) Once(eventName string, handler any) ClientChannel
Once adds a one-time event handler for the specified event to the channel. See ClientChannel.On for more information about how event handlers are called.
type ClientError ¶
type ClientError struct { Client *Client // contains filtered or unexported fields }
ClientError is an error for a specific client
func (ClientError) Error ¶
func (ce ClientError) Error() string
type CloseHandler ¶
type CloseHandler = func(*Client, StatusCode, string)
type Conn ¶
type Conn interface { // ReadMessage reads a message from the WebSocket connection. The context // is used to cancel the read operation. ReadMessage(ctx context.Context, msg *Message) error // WriteMessage writes a message to the WebSocket connection. The context // is used to cancel the write operation. WriteMessage(ctx context.Context, msg *Message) error // Close closes the WebSocket connection with the given status code and // reason. Close(statusCode StatusCode, reason string) error // CloseNow closes the WebSocket connection immediately without waiting for // any pending operations to complete. CloseNow() error }
Conn represents a WebSocket connection that can read and write messages. ReadMessage may not be called concurrently, and one must always read from the connection to properly handle control frames.
type ErrorHandler ¶
type HandlerContextFunc ¶
type HandlerContextFunc func( ctx context.Context, channel string, eventName string, ) (context.Context, context.CancelFunc)
HandlerContextFunc is a function that can modify the context passed to every registered event handler before it is called.
type Message ¶
type Message struct { Channel string `json:"c,omitempty"` Arguments []any `json:"a,omitempty"` // Arguments[0] is the event name RequestID *int `json:"i,omitempty"` ResponseData any `json:"d,omitempty"` ResponseError any `json:"e,omitempty"` ResponseJSError bool `json:"_,omitempty"` IgnoreIfFalse *bool `json:"ws-wrapper,omitempty"` // contains filtered or unexported fields }
Message is a ws-wrapper JSON-encoded message. See https://github.com/bminer/ws-wrapper/blob/master/README.md#protocol
func (Message) EventName ¶
EventName returns the name of the event or empty string if the message is invalid
func (Message) HandlerArguments ¶
HandlerArguments returns the arguments for the event handler
type MessageHandler ¶
type Server ¶
type Server struct { ServerChannel // the "main" server channel with no name // contains filtered or unexported fields }
Server represents a server that accepts WebSocket connections, handles inbound messages, and sends messages to connected clients. Rather than listening for connections itself, the Accept method takes any connection that implements the Conn interface. This allows the server to be used with any WebSocket library. Various adapter libraries are available in the adapters subdirectory.
Example (Echo) ¶
This example shows how to use create a ws-server-wrapper that echoes a string sent to the "echo" event handler.
// Create ws-wrapper-server and "echo" event handler. Note that the event // handler function may optionally have a context as its first argument, // it must always return 2 values, and the second value must implement // error. wsServer := NewServer() wsServer.On("echo", func(s string) (string, error) { // If a ws-server client sends a "echo" request, it will receive the // echoed response. return s, nil }) // Create HTTP handler function that upgrades the HTTP connection to a // WebSocket using the github.com/coder/websocket package. h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // 1. Use your favorite WebSocket library to upgrade the HTTP request to // a WebSocket connection... // 2. Use an adapter (or write your own) to write and parse ws-wrapper // messages. // 3. Call `wsServer.Accept` to attach the underlying WebSocket // connection to `wsServer`. It will start listening for inbound // messages. // See full example in the coder adapter. }) // Start the HTTP server log.Fatal(http.ListenAndServe("localhost:8080", h))
func (*Server) Accept ¶
Accept adds a new client connection to the server. conn only needs to implement the Conn interface. If the server has been closed, Accept will return an error and close conn.
func (*Server) Close ¶
Close closes the server and all connected clients. Returns the first error encountered while closing clients.
func (*Server) Of ¶
func (s *Server) Of(name string) *ServerChannel
Of returns a channel for the given name
func (*Server) SetHandlerContext ¶
func (s *Server) SetHandlerContext(f HandlerContextFunc)
SetHandlerContext sets the handler context function. This function is called before every event handler is called and is used to modify the context passed to every event handler. It can be used to implement timeouts for individual event handlers, for example.
type ServerChannel ¶
type ServerChannel struct {
// contains filtered or unexported fields
}
ServerChannel is a channel on which events can be sent and received. Events emitted or requests sent are sent to all connected clients to the channel of the same name on the remote end. See ClientChannel.On for more information about how received events are handled.
func (ServerChannel) Emit ¶
func (c ServerChannel) Emit( ctx context.Context, arguments ...any, ) (errs []ClientError)
Emit sends an event to all clients on the specified channel. The passed context can be used to cancel writing the message to the client. The second argument is the event name that tells the remote end which event handler to call. Returns a slice of ClientErrors that contains an entry if an error occurred when sending the message to a specific client.
func (ServerChannel) Name ¶
func (c ServerChannel) Name() string
Name returns the name of the channel
func (ServerChannel) On ¶
func (c ServerChannel) On(eventName string, handler any) ServerChannel
On adds an event handler for the specified event to the channel. See ClientChannel.On for more information about how event handlers are called.
func (ServerChannel) Once ¶
func (c ServerChannel) Once(eventName string, handler any) ServerChannel
Once adds a one-time event handler for the specified event to the channel. See ClientChannel.On for more information about how event handlers are called.
type StatusCode ¶
type StatusCode int
StatusCode represents a WebSocket status code. https://tools.ietf.org/html/rfc6455#section-7.4
const ( StatusNormalClosure StatusCode = 1000 StatusGoingAway StatusCode = 1001 StatusProtocolError StatusCode = 1002 StatusUnsupportedData StatusCode = 1003 StatusInvalidFramePayloadData StatusCode = 1007 StatusPolicyViolation StatusCode = 1008 StatusMessageTooBig StatusCode = 1009 StatusMandatoryExtension StatusCode = 1010 StatusInternalError StatusCode = 1011 StatusServiceRestart StatusCode = 1012 StatusTryAgainLater StatusCode = 1013 StatusBadGateway StatusCode = 1014 )