NapCatQQ/packages/napcat-onebot/network/http-server-sse.ts
手瓜一十雪 a2450b72be Refactor network adapter activation and message handling
Introduces isActive property to network adapters for more accurate activation checks, refactors message dispatch logic to use only active adapters, and improves heartbeat management for WebSocket adapters. Also sets default enableWebsocket to false in config and frontend forms, and adds a security dialog for missing tokens in the web UI.
2026-01-14 18:53:31 +08:00

49 lines
1.4 KiB
TypeScript

import { OB11EmitEventContent } from './index';
import { Request, Response } from 'express';
import { OB11HttpServerAdapter } from './http-server';
export class OB11HttpSSEServerAdapter extends OB11HttpServerAdapter {
private sseClients: Response[] = [];
override get isActive (): boolean {
return this.isEnable && (this.sseClients.length > 0 || super.isActive);
}
override async handleRequest (req: Request, res: Response) {
if (req.path === '/_events') {
this.createSseSupport(req, res);
} else {
super.httpApiRequest(req, res, true);
}
}
private async createSseSupport (req: Request, res: Response) {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.flushHeaders();
this.sseClients.push(res);
req.on('close', () => {
this.sseClients = this.sseClients.filter((client) => client !== res);
});
}
override async onEvent<T extends OB11EmitEventContent> (event: T) {
super.onEvent(event);
const promises: Promise<void>[] = [];
this.sseClients.forEach((res) => {
promises.push(new Promise<void>((resolve, reject) => {
res.write(`data: ${JSON.stringify(event)}\n\n`, (err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
}));
});
await Promise.allSettled(promises);
}
}