Skip to content

WebSocket

@ws(cPath, fOnConnect, fOnMessage, fOnDisconnect)

Register event-driven WebSocket endpoint with callbacks. Pass "" for any callback you don’t need.

@ws("/chat",
    func {
        id = $bolt.wsClientId()
        $bolt.wsRoomJoin("chat", id)
        $bolt.wsSendTo(id, "Welcome!")
    },
    func {
        id = $bolt.wsClientId()
        msg = $bolt.wsEventMessage()
        $bolt.wsRoomBroadcast("chat", "[" + id + "] " + msg)
    },
    func {
        $bolt.wsBroadcast("User left: " + $bolt.wsClientId())
    }
)

Event Context (use inside callbacks)

$bolt.wsClientId()        # Current client's UUID
$bolt.wsEventType()       # "connect", "message", or "disconnect"
$bolt.wsEventMessage()    # Message text (on_message only)
$bolt.wsEventIsBinary()   # 1 if binary message, 0 otherwise
$bolt.wsEventBinary()     # Binary data as base64 string
$bolt.wsEventPath()       # WebSocket route path
$bolt.wsParam(cName)      # Route parameter from WebSocket event

Per-Client Send

$bolt.wsSendTo(cClientId, cMessage)             # Send text to specific client
$bolt.wsSendBinaryTo(cClientId, cBase64Data)    # Send binary to specific client
$bolt.wsCloseClient(cClientId)                   # Close a client's connection
$bolt.wsClientList()                             # List of connected client IDs

Rooms

$bolt.wsRoomJoin(cRoom, cClientId)              # Join a room
$bolt.wsRoomLeave(cRoom, cClientId)             # Leave a room
$bolt.wsRoomBroadcast(cRoom, cMessage)          # Send text to all in room
$bolt.wsRoomBroadcastBinary(cRoom, cBase64Data) # Send binary to all in room
$bolt.wsRoomMembers(cRoom)                       # List of client IDs in room
$bolt.wsRoomCount(cRoom)                         # Number of clients in room

Global Broadcast

$bolt.wsBroadcast(cMessage)     # Send to ALL connected clients
$bolt.wsConnectionCount()       # Total active connections
$bolt.wsDroppedCount()          # Number of messages dropped due to VM channel overflow

wsDroppedCount() returns a cumulative count of WebSocket messages that were dropped because the VM event channel was full. This can happen under high load when message events are produced faster than the VM can process them. Monitor this counter to detect backpressure issues.

Event Abort (use in before middleware)

$bolt.wsEventAbort()            # Abort current WS event, skip handler and after middleware

Use inside a before middleware to conditionally reject WebSocket events:

@ws("/chat", "on_connect", "on_message", "on_disconnect")
before("ws_auth_check")

func ws_auth_check
    if $bolt.wsEventMessage() = "unauthorized"
        $bolt.wsEventAbort()
    ok
end