Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
Publish MCP to npm / Build, test, and publish MCP (push) Waiting to run
Publish SDK to npm / Build, test, and publish SDK (push) Waiting to run
Sync action catalog to docs / sync (push) Waiting to run
Publish UI to npm / Build and publish UI (push) Waiting to run
Build and Release / preflight (push) Waiting to run
87 lines
4.2 KiB
Markdown
87 lines
4.2 KiB
Markdown
# OneBot HTTP event streams
|
|
|
|
An HTTP server can serve actions and Server-Sent Events on the same listener.
|
|
Enable **SSE** in the WebUI's HTTP API adapter, or set `enableSse: true` on an
|
|
entry in `networks.httpServers`. The default is `false`; existing HTTP and
|
|
WebSocket configurations keep their behavior. SSE and `enableWebSocket` may both
|
|
be enabled.
|
|
|
|
```json
|
|
{
|
|
"name": "web-client",
|
|
"host": "127.0.0.1",
|
|
"port": 3000,
|
|
"path": "/api",
|
|
"enableSse": true,
|
|
"accessToken": "replace-with-your-token",
|
|
"messageFormat": "array",
|
|
"reportSelfMessage": false
|
|
}
|
|
```
|
|
|
|
`GET /api/_events?access_token=<token>` opens the event stream. Actions continue
|
|
to use `POST /api/<action>` with a JSON parameter object. HTTP requests accept
|
|
`Authorization: Bearer <token>`, `Authorization: <token>` (for Stapxs QQ Lite), or
|
|
the `access_token` query parameter. The configured token and bind address still
|
|
apply. Empty tokens retain the existing unauthenticated HTTP behavior.
|
|
|
|
```js
|
|
const events = new EventSource(`api/_events?access_token=${encodeURIComponent(token)}`);
|
|
events.onmessage = ({ data }) => console.log(JSON.parse(data));
|
|
events.onerror = () =>
|
|
console.error('Event connection interrupted; check connection and authentication');
|
|
|
|
const response = await fetch('api/get_status', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json', Authorization: token },
|
|
body: JSON.stringify({}),
|
|
});
|
|
if (!response.ok) throw new Error(`Action failed: HTTP ${response.status}`);
|
|
console.log(await response.json());
|
|
// Close the stream when the owning page/component is disposed.
|
|
// events.close();
|
|
```
|
|
|
|
Configure Stapxs's SSE event address as `api/_events` and HTTP address as `api`
|
|
when both are exposed under that same-origin proxy prefix. Forward the request
|
|
path, query string, authorization and `Last-Event-ID` headers unchanged. SnowLuma
|
|
does not add cross-origin access grants. TLS and any additional proxy
|
|
authentication remain the proxy's responsibility.
|
|
|
|
Responses use `text/event-stream`, `Cache-Control: no-cache, no-transform`, and
|
|
`X-Accel-Buffering: no`. Events are ordinary unnamed `data:` frames containing
|
|
OneBot JSON. Connection lifecycle and current heartbeat events bootstrap each
|
|
subscription. Transport comments (`: ping`) are sent every 15 seconds; they are
|
|
not OneBot events. The browser's reconnect delay is 3 seconds.
|
|
|
|
## Reconnect and resource limits
|
|
|
|
Every broadcast event has an opaque `id`. A reconnect with `Last-Event-ID`
|
|
replays events after that cursor, in order, before connection bootstrap events
|
|
and subsequent live events. Native EventSource sends this header automatically
|
|
when reconnecting the same object. A new subscription without the header starts
|
|
at the present and does not receive old messages.
|
|
|
|
Each adapter retains at most 256 events and 8 MiB in memory, including while no
|
|
client is connected. This is a short reconnect window, not durable message
|
|
history. Accounts and adapter instances have independent histories. Event IDs
|
|
are invalidated on restart, shutdown, token rotation, report-policy changes or
|
|
disabling SSE. Neither replay nor live delivery bypasses `messageFormat` or
|
|
`reportSelfMessage`.
|
|
|
|
An invalid cursor returns HTTP 400. An expired, future or foreign cursor returns
|
|
HTTP 409 with `wording` explaining that replay is unavailable. There is no silent
|
|
fallback to live-only delivery. After reconciling the application's state/history,
|
|
close and recreate EventSource to subscribe without the old cursor. EventSource's
|
|
error callback does not expose the HTTP error body; fetch-based consumers can
|
|
inspect it directly. Bootstrap events can share the latest broadcast cursor and
|
|
must not be treated as newly persisted message events.
|
|
|
|
Each client's pending output is limited to 8 MiB. Slow readers are disconnected
|
|
with a warning instead of retaining unbounded events or blocking other clients.
|
|
A single frame exceeding this limit also disconnects that client. Reconnection
|
|
is subject to the same replay limits. Disconnect, hot reload and shutdown release
|
|
connections and heartbeat timers; rotating the token revokes existing streams.
|
|
|
|
Tests: `pnpm --filter @snowluma/onebot exec vitest run tests/http-server-sse.test.ts tests/http-sse-backpressure.test.ts tests/http-server-websocket-config.test.ts`.
|