Crate axum_cometd

Source
Expand description

This crate aims to make ability to use CometD protocol in servers written in Rust.

This project is in progress and might change a lot from version to version.

§Table of contents

§Server endpoints

Server have 4 endpoints:

  1. /handshake – to register and get clientId;
  2. / – to subscribe on channels;
  3. /connect – to receiving or publish messages;
  4. /disconnect – to say to server clean data for clientId;

You can change base part of these endpoints through RouterBuilder::handshake_base_path, RouterBuilder::subscribe_base_path, RouterBuilder::connect_base_path, RouterBuilder::disconnect_base_path. For example, to make /node/0/handshake and /node/1/connect you can do this:

use std::sync::Arc;
use axum_cometd::{LongPollingServiceContextBuilder, RouterBuilder};

let context = LongPollingServiceContextBuilder::new()
    .build();

let router = RouterBuilder::new()
    .handshake_base_path("/node/0")
    .connect_base_path("/node/1")
    .build(Arc::clone(&context));

clientId and BAYEUX_BROWSER cookie is 40-character length hex string, with possibility of leading zeroes. Server will return ‘402::session_unknown’ error if it will be not. To get some uniquity first 8 bytes is taken from Unix timestamp, and for randomness last part filled with random numbers.

§How server works

BAYEUX_BROWSER cookie will be generated and set at /handshake request, if there isn’t one already.

At others endpoints ([Server endpoints]) server check clientId and BAYEUX_BROWSER cookie (in case of publish messages to /connect it will be check each clientId). If clientId will be used with different BAYEUX_BROWSER cookie, server will return ‘402::session_unknown’ error.

§How get server events

Server have 3 events:

  1. Event::SessionAdded
  2. Event::Subscribe
  3. Event::SessionRemoved
  4. Event::CustomData

SessionAdded and Subscribe can contain additional data, which will be attached through axum::Extension. To get those events, you must use get receive channel LongPollingServiceContext::rx. Server do not use Event::CustomData, it user custom message which can be received in receiver.

use std::sync::Arc;
use axum::Extension;
use axum_cometd::{LongPollingServiceContextBuilder, RouterBuilder};

#[derive(Debug, Clone)]
struct ContextData {
    server_name: Arc<str>,
}

use std::time::Duration;
use axum_cometd::Event;
let context = LongPollingServiceContextBuilder::new()
    .build::<ContextData, &'static str>();

let app = RouterBuilder::new()
    .build_with_additional_data(Arc::clone(&context))
    .layer(Extension(ContextData {
        server_name: std::env::var("SERVER_NAME")
            .map(Arc::from)
            .unwrap_or_else(|_| Arc::from("Skalica")),
    }));

let tx = context.tx();
let mut rx = context.rx();

tokio::task::spawn(async move {
    loop {
        tx.send("CUSTOM_DATA").await;
        tokio::time::sleep(Duration::from_secs(1)).await;
    }
});

while let Some(event) = rx.recv().await {
    match *event {
        Event::SessionAdded{
            client_id,
            ref headers,
            ref data,
        } => {
            println!("sessionAdded with clientId({client_id}), headers({headers:?}), data({data:?})");
        }
        Event::Subscribe{
            client_id,
            ref headers,
            ref channels,
            ref data,
        } => {
            println!("subscribed on channels({channels:?}) with clientId({client_id}), headers({headers:?}), data({data:?})");
        }
        Event::SessionRemoved{
            client_id,
        } => println!("clientId({client_id}) session removed"),
        Event::CustomData(msg) => println!("got CustomData({msg})"),
    }
}

Modules§

error
Contains errors.
messages
Contains cometd Message struct.

Structs§

ClientId
CometD ClientId.
CometdCustomDataSender
Sender channel to send custom data.
CometdEventReceiver
Event channel receiver.
LongPollingServiceContext
Context for sending messages to channels.
LongPollingServiceContextBuilder
A builder to construct LongPoolingServiceContext.
RouterBuilder
A builder to construct axum::Route of CometD server.

Enums§

Event
SendError
Error returned by the LongPoolingServiceContext::send.