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
ID
field inwebsocket.MessageConnect
contains 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
ID
field inwebsocket.MessageDisconnect
contains 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?