Skip to content

WebSocket — Getting Started

WebSocket connections allow real-time, bidirectional communication using the framework's binary FlatBuffers protocol.


run_websocket_service(port) — Starting a WebSocket Service

Starts a standalone WebSocket server on the given port. Clients connect using the framework's binary protocol.

cpp
#include <framework.hpp>

using namespace framework;

int main() {
    framework::app app;

    // Start WebSocket service on port 8081
    app.run_websocket_service(8081);

    app.run();
    return 0;
}
ParamDescription
portTCP port to listen on for WebSocket connections.

run_service(port) — Combined HTTP + WebSocket

Serves both HTTP and WebSocket on the same TCP port. The kernel detects the protocol during the handshake and routes accordingly.

cpp
app.run_service(8080);  // Both HTTP and WebSocket on port 8080

run_raw_websocket_service(port, handler) — Raw WebSocket

For full control over individual WebSocket connections. Each new connection calls your handler with a raw_connection object.

cpp
#include <framework.hpp>
#include <iostream>

using namespace framework;
using namespace framework::clients::websocket;

int main() {
    framework::app app;

    app.run_raw_websocket_service(8082,
        [](std::shared_ptr<raw_connection> conn) {
            std::cout << "Client connected: " << conn->get_id() << std::endl;

            conn->on_data([](auto conn, support::shared_buffer data) {
                std::cout << "Received " << data.size() << " bytes" << std::endl;
                conn->send(data);
            });

            conn->on_close([](auto conn) {
                std::cout << "Client disconnected" << std::endl;
            });
        }
    );

    app.run();
    return 0;
}

raw_connection API

MethodDescription
on_data(handler)Called when data arrives. Handler: (ptr, shared_buffer).
on_error(handler)Called on connection error.
on_close(handler)Called on connection close.
send(buffer)Send data (shared_buffer). Defaults to binary frame.
read_some(timeout)Trigger a read with optional timeout.
set_binary(bool)Set binary mode for outgoing frames.
set_text(bool)Set text mode for outgoing frames.
get_id()Returns the session UUID.
remote_endpoint()Returns the client's address.
get_metrics()Returns session metrics.

register_custom_handler(opcode, handler) — Custom Opcode Handlers

Register a handler for a custom opcode value (200+).

cpp
using namespace framework;
using namespace framework::clients::websocket;

app.register_custom_handler(200,
    [](const websocket_request& ctx) -> message_offset_t {
        // ctx.message_ — parsed FlatBuffers message
        // ctx.body_ — message payload
        // ctx.websocket_connection_ — the sending connection
        return helpers::make_empty_response(ctx, static_cast<protocol::fbs::Opcode>(200));
    }
);

Handler signature

cpp
using handler_t = std::function<message_offset_t(const websocket_request&)>;

The websocket_request struct

cpp
struct websocket_request {
    const std::shared_ptr<state::instance>& state_;            // App state
    const std::shared_ptr<websocket_connection>& websocket_connection_;  // Sending connection
    const protocol::fbs::Message* message_;                   // Parsed FlatBuffers message
    support::shared_buffer body_;                             // Message payload bytes
    flatbuffers::FlatBufferBuilder& builder_;                 // Builder for response messages
    std::pmr::memory_resource* resource_;                     // Memory resource for allocations
    boost::uuids::uuid trace_id_;                             // Distributed tracing ID
    uint64_t span_id_ = 0;                                    // Tracing span ID
    uint64_t parent_span_id_ = 0;                             // Parent tracing span ID
    support::quota_evaluation_result quota_result_;            // Rate limit evaluation result
};

The message_offset_t type

cpp
using message_offset_t = flatbuffers::Offset<protocol::fbs::Message>;

This is a FlatBuffers offset type. Use helpers::make_empty_response(ctx, opcode) to create a response, or build a response manually using the builder_ field from the request.

Frame Building Helpers

The websocket::helpers namespace provides functions to build message frames:

cpp
using namespace framework::clients::websocket;

// Build a publish frame for a channel
auto frame = helpers::build_ws_publish_frame(
    "room-general",           // channel name
    payload_data,             // vector<uint8_t> payload
    nullptr,                  // transaction_id (optional)
    false,                    // requires_ack
    token,                    // JWT token (optional)
    trace_id                  // tracing ID (optional)
);

// Build a send frame for a specific session
auto frame = helpers::build_ws_send_frame(
    receiver_id,              // target session UUID
    emitter_id,               // sending session UUID
    payload_data,             // payload
    nullptr,                  // transaction_id
    false                     // requires_ack
);

// Broadcast to all subscribers
auto frame = helpers::build_ws_broadcast_frame(
    payload_data,
    nullptr,
    false
);

websocket_connection API

For the built-in WebSocket service (not raw), the connection is managed internally:

MethodReturn TypeDescription
get_id()uuid&Connection UUID
get_node_id()optional<uuid>Owner node UUID
send(buffer)voidSend data to this connection
get_ip()stringClient IP address
get_port()uint16_tClient port
get_metrics()session_metrics&Connection metrics
stop()voidClose the connection

override_websocket_handler(opcode, handler) — Overriding Built-in Handlers

Replace a built-in opcode handler with your own implementation.

cpp
using namespace framework;

app.override_websocket_handler(
    protocol::fbs::Opcode_Ping,
    my_custom_ping_handler
);

Useful for adding custom logic to existing opcodes (e.g., logging, metrics, custom auth).