From 703327ed4105861d8aacbfd3627049acd5ffdd5e Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sat, 30 Mar 2024 12:20:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0SSE=E8=AE=A2=E9=98=85?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E8=BF=87=E6=BB=A4=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/modules/openApi/index.ts | 65 +++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/src/main/modules/openApi/index.ts b/src/main/modules/openApi/index.ts index f897bf0c..4c4da444 100644 --- a/src/main/modules/openApi/index.ts +++ b/src/main/modules/openApi/index.ts @@ -1,4 +1,5 @@ import http from 'node:http' +import querystring from 'node:querystring' import type { Socket } from 'node:net' let status: LX.OpenAPI.Status = { @@ -7,14 +8,42 @@ let status: LX.OpenAPI.Status = { address: '', } +type SubscribeKeys = keyof LX.Player.Status + let httpServer: http.Server let sockets = new Set() -let responses = new Set>() +let responses = new Map, SubscribeKeys[]>() + +const parseFilter = (filter: any) => { + const keys = Object.keys(global.lx.player_status) as SubscribeKeys[] + if (typeof filter != 'string') return keys + filter = filter.split(',') + const subKeys = keys.filter(k => filter.includes(k)) + return subKeys.length ? subKeys : keys +} +const handleSubscribePlayerStatus = (req: http.IncomingMessage, res: http.ServerResponse, query?: string) => { + res.writeHead(200, { + 'Content-Type': 'text/event-stream', + Connection: 'keep-alive', + 'Cache-Control': 'no-cache', + }) + req.socket.setTimeout(0) + req.on('close', () => { + res.end('OK') + responses.delete(res) + }) + const keys = parseFilter(querystring.parse(query ?? '').filter) + responses.set(res, keys) + for (const [k, v] of Object.entries(global.lx.player_status)) { + if (!keys.includes(k as SubscribeKeys)) continue + res.write(`event: ${k}\n`) + res.write(`data: ${JSON.stringify(v)}\n\n`) + } +} const handleStartServer = async(port = 9000, ip = '127.0.0.1') => new Promise((resolve, reject) => { - httpServer = http.createServer((req, res) => { - // console.log(req.url) - const endUrl = `/${req.url?.split('/').at(-1) ?? ''}` + httpServer = http.createServer((req, res): void => { + const [endUrl, query] = `/${req.url?.split('/').at(-1) ?? ''}`.split('?') let code let msg switch (endUrl) { @@ -83,22 +112,15 @@ const handleStartServer = async(port = 9000, ip = '127.0.0.1') => new Promise { - res.end('OK') - responses.delete(res) - }) - for (const [k, v] of Object.entries(global.lx.player_status)) { - res.write(`event: ${k}\n`) - res.write(`data: ${JSON.stringify(v)}\n\n`) + try { + handleSubscribePlayerStatus(req, res, query) + return + } catch (err) { + console.log(err) + code = 500 + msg = 'Error' } - responses.add(res) - return + break default: code = 401 msg = 'Forbidden' @@ -149,8 +171,9 @@ const handleStopServer = async() => new Promise((resolve, reject) => { const sendStatus = (status: Partial) => { if (!responses.size) return - for (const [k, v] of Object.entries(status)) { - for (const resp of responses) { + for (const [resp, keys] of responses) { + for (const [k, v] of Object.entries(status)) { + if (!keys.includes(k as SubscribeKeys)) continue resp.write(`event: ${k}\n`) resp.write(`data: ${JSON.stringify(v)}\n\n`) }