WebSocket
This package implements functionality for working with WebSocket connections through two meta-processes: WebSocket Handler (for handling HTTP requests to create WebSocket connections) and WebSocket Connection (for managing the established WebSocket connection). This implementation depends on the external library https://github.com/gorilla/websocket, which is why it is placed in a separate package "ergo.services/meta/websocket". You can find the source code in the additional meta-process library repository at https://github.com/ergo-services/meta.
WebSocket Handler
To handle incoming WebSocket connections, use the CreateHandler function. This function returns an object implementing gen.MetaProcess and http.Handler, needed for launching the meta-process and processing HTTP requests. It accepts websocket.HandlerOptions as arguments:
ProcessPool: Specifies a list of process names to handle WebSocket messages.HandshakeTimeout: Limits the time for the upgrade process.EnableCompression: Enables compression for WebSocket connections.CheckOrigin: Allows setting a function to verify the request's origin.
After creation, start the meta-process with SpawnMeta. Each connection launches a new WebSocket Connection meta-process for handling.
WebSocket Connection
This package implements the functionality of a meta-process for handling a WebSocket connection. It also allows initiating a WebSocket connection. To initiate a connection, use the CreateConnection function, which takes websocket.ConnectionOptions as an argument:
type ConnectionOptions struct {
Process gen.Atom
URL url.URL
HandshakeTimeout time.Duration
EnableCompression bool
}This structure is similar to websocket.HandlerOptions but includes an additional field, URL, where the WebSocket server address must be specified. For example:
opt := websocket.ClientOptions{
URL: url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/ws"},
}During the execution of the CreateConnection function, it attempts to establish a WebSocket connection with the specified server.
After creating the meta-process, you must launch it using the SpawnMeta method from the gen.Process interface. If an error occurs while launching the meta-process, you need to call the Terminate method from the gen.MetaBehavior interface to close the WebSocket connection created by CreateConnection:
func(a *MyActor) HandleMessage(from gen.PID, message any) error {
// ...
opt := websocket.ConnectionOptions{
URL: url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/ws"},
}
wsconn, err := websocket.CreateConnection(opt)
if err != nil {
a.Log().Error("unable to connect to %s: %s", opt.URL.String(), err)
return nil
}
id, err := a.SpawnMeta(wsconn, gen.MetaOptions{})
if err != nil {
// unable to spawn meta-process. need to close the connection
wsconn.Terminate(err)
a.Log().Error("unable to spawn meta-process: %s", err)
return nil
}
a.Log().Info("spawned meta-process %s to handle connection with %s", id, opt.URL.String())
// ...
return nil
}WebSocket messages
When working with WebSocket connections, three types of messages are used:
websocket.MessageConnect- Sent to the process when the meta-process handling the WebSocket connection is started:type MessageConnect struct { ID gen.Alias RemoteAddr net.Addr LocalAddr net.Addr }The
IDfield inwebsocket.MessageConnectcontains the identifier of the meta-process handling the WebSocket connectionwebsocket.MessageDisconnect- is sent to the process when a WebSocket connection is disconnected:type MessageDisconnect struct { ID gen.Alias }The
IDfield inwebsocket.MessageDisconnectcontains the identifier of the meta-process that handled the WebSocket connection. After the connection is terminated, the meta-process finishes its work and sends this message during its termination phase, signaling that the WebSocket connection has been closedwebsocket.Message- is used for both receiving and sending WebSocket messages:type Message struct { ID gen.Alias Type MessageType Body []byte }ID- identifier of the meta-process handling the WebSocket connection.Body- the message's body.Type- type of WebSocket message, according to the WebSocket specification. Several message types are available:const ( MessageTypeText MessageType = 1 MessageTypeBinary MessageType = 2 MessageTypeClose MessageType = 8 MessageTypePing MessageType = 9 MessageTypePong MessageType = 10 )
If the meta-process fails to send a message to the process, the WebSocket connection is terminated, and the meta-process itself also terminates.
Sending a WebSocket-message
To send a message over a WebSocket connection, use the Send (or SendAlias) method from the gen.Process interface. The recipient should be the gen.Alias of the meta-process handling the WebSocket connection.
The message must be of type websocket.Message. If the Type field is not explicitly set, the default is websocket.MessageTypeText. The websocket.Message.ID field is ignored when sending (it's used only for incoming messages).
For a complete implementation of a WebSocket server, see the project in the repository https://github.com/ergo-services/examples, the websocket project:

Last updated
Was this helpful?