peerix - v0.6.0
    Preparing search index...

    Class SseDriver

    Server-Sent Events (SSE) signaling driver.

    SSE is a unidirectional communication protocol that allows servers to push real-time updates to clients over a single HTTP connection. This driver uses SSE to receive updates from the server. To send messages to the server, it uses standard HTTP POST requests. This protocol can be used as an alternative to WebSocket-based transport.

    %%{init:{"theme":"dark"}}%% sequenceDiagram participant A as Peer A participant S as SSE Server participant B as Peer B A->>S: GET /.well-known/mercure?topic=... (open SSE stream) B->>S: GET /.well-known/mercure?topic=... (open SSE stream) A->>S: POST /.well-known/mercure?topic=... (signal payload) S-->>B: SSE event: data: payload B->>S: POST /.well-known/mercure?topic=... (signal payload) S-->>A: SSE event: data: payload
    %%{init:{"theme":"default"}}%% sequenceDiagram participant A as Peer A participant S as SSE Server participant B as Peer B A->>S: GET /.well-known/mercure?topic=... (open SSE stream) B->>S: GET /.well-known/mercure?topic=... (open SSE stream) A->>S: POST /.well-known/mercure?topic=... (signal payload) S-->>B: SSE event: data: payload B->>S: POST /.well-known/mercure?topic=... (signal payload) S-->>A: SSE event: data: payload
    sequenceDiagram
      participant A as Peer A
      participant S as SSE Server
      participant B as Peer B
      A->>S: GET /.well-known/mercure?topic=... (open SSE stream)
      B->>S: GET /.well-known/mercure?topic=... (open SSE stream)
      A->>S: POST /.well-known/mercure?topic=... (signal payload)
      S-->>B: SSE event: data: payload
      B->>S: POST /.well-known/mercure?topic=... (signal payload)
      S-->>A: SSE event: data: payload

    This driver requires a Mercure server or compatible server-side implementation to work.

    Client-side code (browser with SSE support):

    const publisherJwtKey = "mercure-publisher-jwt-key";
    const driver = new SseDriver({
    url: "http://localhost:8080/.well-known/mercure",
    publisher: {
    headers: {
    Authorization: `Bearer ${publisherJwtKey}`,
    },
    },
    });

    You can use this JWT publisher key with the Mercure server's default configuration for testing purposes:

    eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiKiJdfX0.bVXdlWXwfw9ySx7-iV5OpUSHo34RkjUdVzDLBcc6l_g
    

    Running a local Mercure server for testing:

    docker run --rm -p 8080:80 \
    -e SERVER_NAME=':80' \
    -e MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
    -e MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
    dunglas/mercure:latest caddy run --config /etc/caddy/dev.Caddyfile

    Instead of using Mercure, you can use a Node.js server:

    const express = require("express");
    const cors = require("cors");

    const app = express();
    app.use(express.urlencoded({ extended: true }));
    app.use(cors({ origin: true, credentials: true }));

    const namespaces = new Map();

    // route for outgoing messages (subscribe/stream)
    app.get("/.well-known/mercure", (req, res) => {
    const { topic } = req.query;
    if (!topic) return res.status(400).end();
    // support multiple topics in a single request
    const topics = Array.isArray(topic) ? topic : [topic];
    for (const t of topics) {
    const clients = namespaces.get(t) || new Set();
    namespaces.set(t, clients);
    clients.add(res);
    }
    // set headers to establish the SSE stream
    res.setHeader("Content-Type", "text/event-stream");
    res.setHeader("Cache-Control", "no-cache");
    res.setHeader("Connection", "keep-alive");
    res.flushHeaders();
    // clean up if the browser closes the page or disconnects
    req.on("close", () => {
    for (const t of topics) {
    const clients = namespaces.get(t);
    if (clients) {
    clients.delete(res);
    if (!clients.size) namespaces.delete(t);
    }
    }
    res.end();
    });
    });

    // route for incoming messages (publish)
    app.post("/.well-known/mercure", (req, res) => {
    const { topic, data = "" } = req.body || {};
    if (topic) {
    const topics = Array.isArray(topic) ? topic : [topic];
    for (const t of topics) {
    const clients = namespaces.get(t);
    if (clients) {
    for (const client of clients) {
    client.write(`data: ${data}\n\n`);
    }
    }
    }
    }
    res.status(200).end();
    });

    app.listen(8080);

    Hierarchy (View Summary)

    Index
    • Creates a new instance of the driver.

      Parameters

      • Optionaloptions: { publisher: RequestInit; subscriber: EventSourceInit; url?: string }

        Optional configuration for the driver.

        • publisher: RequestInit

          Publisher options for the HTTP requests (fetch).

        • subscriber: EventSourceInit

          Subscriber options for the EventSource instance.

        • Optionalurl?: string

          URL to connect to via SSE. Defaults to "/.well-known/mercure".

      Returns SseDriver

    • get active(): boolean

      Indicates whether the driver is currently active.

      Returns boolean

    • set active(value: boolean): void

      Sets the active state of the driver and emits corresponding events.

      Parameters

      • value: boolean

      Returns void

    • Publishes a signaling message to the specified namespace.

      Parameters

      • namespace: string

        The namespace to publish the message to.

      • data: number[]

        The message data to publish.

      Returns Promise<void>

      Nothing directly; resolves once the message is delivered (async drivers may return a promise).

    • Subscribes to signaling messages for the specified namespace.

      Parameters

      • namespace: string

        The namespace to subscribe to.

      • handler: (data: number[]) => void

        The handler function to call when a message is received.

      Returns Promise<void>

      Nothing directly; resolves once the subscription is established (async drivers may return a promise).

    • Unsubscribes from signaling messages for the specified namespace.

      Parameters

      • namespace: string

        The namespace to unsubscribe from.

      • handler: (data: number[]) => void

        The handler function to remove.

      Returns Promise<void>

      Nothing directly; resolves once the unsubscription is confirmed (async drivers may return a promise).