WebSocket (Realtime)
Flamigo's realtime interface is built on WebSockets, allowing you to send or push updates from your backend to connected frontend clients — instantly and efficiently.
It integrates directly with the Realtime Event Bus, enabling seamless reaction to domain events and bidirectional communication with frontend applications.
WARNING
The config module refers to the initial setup configuration for enabling WebSocket support. It can only be enabled when initializing a new project because it requires specific scaffolding to be generated.
Setting Up WebSocket Communication
Follow these steps to enable and use WebSocket communication in your Flamigo project:
Enable WebSocket Support: Ensure the WebSocket module is enabled during project initialization. If not, you may need to reinitialize the project.
Define WebSocket Strategies: Create strategies to handle WebSocket messages. For example:
gofunc MyWebSocketStrategy(ctx flamigo.Context, payload map[string]interface{}) error { // Handle the WebSocket message return nil }
Subscribe Clients to Topics: In the
client.go
file, subscribe WebSocket clients to topics:goclient.Subscribe("app::strategy", MyWebSocketStrategy)
Frontend Integration: Use a WebSocket client library (e.g.,
native WebSocket
orsocket.io
) to connect to the backend:javascriptconst socket = new WebSocket("ws://your-backend-url"); socket.onmessage = (event) => { console.log("Message received:", event.data); };
Test the Connection: Send a test message from the frontend and verify the backend processes it correctly.
WebSocket Actor
In line with Flamigo’s actor-based architecture, each WebSocket connection is treated as an actor. This allows strategies and domain logic to understand and respond to who initiated a given action via WebSocket.
The WebSocket interface provides its own actor type to represent the client.
INFO
If the auth plugin is also enabled, the WebSocket actor will automatically implement the UserActor
interface — giving you access to user-specific logic out of the box.
Actor Claim Validators
To help you control behavior based on the type of actor, two claim validators are available:
IsWebsocket
– Passes only if the actor is a WebSocket actor.IsNotWebsocket
– Fails if the actor is a WebSocket actor.
These can be used in strategies or other actor-aware logic to adapt behavior to the connection type.
Authentication
If the authentication plugin is enabled, the WebSocket interface registers a dedicated authentication strategy:
app::websocket:auth
This strategy is triggered when a client connects and attempts to authenticate. You are expected to customize this strategy to match your authentication flow — e.g., validate session tokens, headers, or credentials from the client.
The WebSocket Client
Each WebSocket connection is represented by a WebSocket Client object. This client:
- Manages the connection’s state
- Tracks the associated user (if authenticated)
- Subscribes to topics on the Realtime Event Bus
By default, client setup is minimal — you are expected to manually subscribe clients to topics and customize the client logic as needed.
💡 See the
client.go
file for aTODO
section where you can hook in custom behavior.
Events
The WebSocket interface emits lifecycle events, including:
EventDisconnected
– Fired when a client disconnects from the server.
You can use this to clean up state, revoke sessions, or notify others.
WebSocket Communication
Communication between frontend and backend happens through structured WebSocket messages. Each message follows a standard format:
Sending a Request
{
"topic": "app::strategy",
"payload": {}
}
topic
: The strategy name to execute on the server.payload
: Arbitrary data to send as input.
Receiving Responses
To receive a response to a specific request, include an ackId
in the message:
{
"topic": "app::strategy",
"payload": {},
"ackId": "12345"
}
The response will be returned with the same ackId
:
{
"topic": "app::strategy",
"payload": {
"foo": "bar"
},
"ackId": "12345"
}
This lets the client match the response to the original request, which is especially useful for concurrent or asynchronous interactions.
Handling Errors
If a strategy fails or an error occurs, the server will respond with a message under the error
topic:
{
"topic": "error",
"payload": {
"message": "some error message",
"status": "status code",
"trace": "if provided, a trace"
},
"ackId": "12345"
}
This message includes:
- A descriptive error
message
- An optional
status
code - A
trace
(for debugging, if available) - The
ackId
to match the failed request
This structure allows the frontend to gracefully handle and display backend errors.