Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

muxio-tokio-rpc-server: WebSocket RPC Server

Loading…

muxio-tokio-rpc-server: WebSocket RPC Server

Relevant source files

The muxio-tokio-rpc-server crate provides a reference implementation of a Muxio RPC server using the Tokio runtime, Axum web framework, and WebSockets (via tokio-tungstenite). It enables high-performance, bidirectional RPC communication where the server can both handle requests from clients and initiate calls back to connected clients extensions/muxio-tokio-rpc-server/src/rpc_server.rs:1-6

Core Architecture

The server is built around the RpcServer struct, which manages an RpcServiceEndpoint for request dispatching and handles the lifecycle of WebSocket connections. Each connection is managed by two primary asynchronous tasks: a sender_task and a receiver_task extensions/muxio-tokio-rpc-server/src/rpc_server.rs:66-69 extensions/muxio-tokio-rpc-server/src/rpc_server.rs:183-191

Server-to-Code Entity Mapping

The following diagram illustrates how high-level server concepts map to specific structs and functions in the codebase.

Entity Relationship Diagram

graph TD
    subgraph "muxio-tokio-rpc-server"
        RpcServer["RpcServer (struct)"]
ConnectionContext["ConnectionContext (struct)"]
ConnectionContextHandle["ConnectionContextHandle (newtype)"]
WsSenderContext["WsSenderContext (type alias)"]
RpcServer -- "owns" --> RpcServiceEndpoint["RpcServiceEndpoint (from muxio-rpc-service-endpoint)"]
RpcServer -- "spawns" --> receiver_task["RpcServer::receiver_task (fn)"]
ConnectionContext -- "contains" --> RpcDispatcher["RpcDispatcher (from muxio-core)"]
ConnectionContext -- "contains" --> WsSenderContext
        ConnectionContextHandle -- "wraps" --> ConnectionContext
    end

    subgraph "External Dependencies"
        AxumRouter["axum::Router"]
TcpListener["tokio::net::TcpListener"]
end

    RpcServer -- "configures" --> AxumRouter
    RpcServer -- "binds" --> TcpListener

Sources: extensions/muxio-tokio-rpc-server/src/rpc_server.rs:48-69 extensions/muxio-tokio-rpc-server/src/rpc_server.rs:183-191

Key Components

RpcServer

The RpcServer is the entry point for starting the service. It allows for registering RPC handlers via its internal endpoint and provides methods for binding to network interfaces.

Connection Management

Every client connection is represented by a ConnectionContext. Because the server supports bidirectional calling, each connection maintains its own RpcDispatcher extensions/muxio-tokio-rpc-server/src/rpc_server.rs54

Data Flow & Task Architecture

The server utilizes a split-task architecture for every WebSocket connection to ensure full-duplex communication and independent heartbeat monitoring.

Connection Data Flow

sequenceDiagram
    participant Peer as "Remote Client"
    participant RX as "receiver_task"
    participant EP as "RpcServiceEndpoint"
    participant TX as "spawn_write_loop"
    participant MPSC as "Internal MPSC Channel"

    Note over RX, TX: Per-Connection Tasks
    
    Peer->>RX: WebSocket Message (Binary)
    RX->>EP: read_bytes(dispatcher, context, bytes, on_emit)
    EP->>EP: Stage 1: Decode & Identify
    EP->>EP: Stage 2: Concurrent Execute Handlers
    EP->>EP: Stage 3: Encode & Emit
    EP-->>MPSC: Response Frames
    MPSC->>TX: Internal Message
    TX->>Peer: WebSocket Message (Binary)

    loop Heartbeat
        RX->>Peer: Ping (Every 5s)
        Peer-->>RX: Pong
    end

Sources: extensions/muxio-tokio-rpc-server/src/rpc_server.rs:183-191 extensions/muxio-tokio-rpc-server/src/rpc_server.rs:35-40 extensions/muxio-rpc-service-caller/src/caller_interface.rs:123-163

sender_task (via spawn_write_loop)

The server uses muxio_rpc_service_caller::write_channel::spawn_write_loop to manage outgoing data extensions/muxio-tokio-rpc-server/src/rpc_server.rs:157-164

receiver_task & Heartbeats

The receiver_task processes incoming data and manages connection liveness:

Utility Functions

The crate includes utilities for managing TCP listeners, primarily used in testing or dynamic environment setups:

FunctionDescription
bind_tcp_listener_on_random_portBinds a TcpListener to 127.0.0.1:0 and returns the listener plus the OS-assigned port extensions/muxio-tokio-rpc-server/src/utils/mod.rs
tcp_listener_to_host_portExtracts the IpAddr and u16 port from an existing TcpListener extensions/muxio-tokio-rpc-server/src/utils/mod.rs

Sources: extensions/muxio-tokio-rpc-server/src/lib.rs5 extensions/muxio-tokio-rpc-server/src/rpc_server.rs:1-200

Implementation Notes

Sources: extensions/muxio-tokio-rpc-server/src/rpc_server.rs:1-200 extensions/muxio-rpc-service-caller/src/caller_interface.rs:25-53