From acb1ec387129c91888fce7118228078804a91c6f Mon Sep 17 00:00:00 2001 From: Disy Date: Mon, 19 Feb 2024 13:54:09 +0800 Subject: [PATCH] feat: Asynchronous connect reverse websocket --- src/onebot11/ReconnectingWebsocket.ts | 26 +++------- src/onebot11/event/manager.ts | 2 +- src/onebot11/server.ts | 74 ++++++++++++++------------- src/renderer.ts | 8 +-- 4 files changed, 52 insertions(+), 58 deletions(-) diff --git a/src/onebot11/ReconnectingWebsocket.ts b/src/onebot11/ReconnectingWebsocket.ts index 5bb77e2..ecf5c5e 100644 --- a/src/onebot11/ReconnectingWebsocket.ts +++ b/src/onebot11/ReconnectingWebsocket.ts @@ -2,7 +2,7 @@ import {log} from "../common/utils"; const WebSocket = require("ws"); -class ReconnectingWebsocket { +export class ReconnectingWebsocket { private websocket; private readonly url: string; @@ -17,14 +17,6 @@ class ReconnectingWebsocket { public onclose = function () {} - private heartbeat() { - clearTimeout(this.websocket.pingTimeout); - - this.websocket.pingTimeout = setTimeout(() => { - this.websocket.terminate(); - }, 3000); - } - public send(msg) { if (this.websocket && this.websocket.readyState == WebSocket.OPEN) { this.websocket.send(msg); @@ -37,12 +29,12 @@ class ReconnectingWebsocket { perMessageDeflate: false }); - log("Trying to connect to the websocket server: " + this.url); + console.log("Trying to connect to the websocket server: " + this.url); const instance = this; this.websocket.on("open", function open() { - log("Connected to the websocket server: " + instance.url); + console.log("Connected to the websocket server: " + instance.url); instance.onopen(); }); @@ -52,15 +44,13 @@ class ReconnectingWebsocket { this.websocket.on("error", console.error); - this.websocket.on("ping", this.heartbeat); - this.websocket.on("close", function close() { - log("The websocket connection: " + instance.url + " closed, trying reconnecting..."); + console.log("The websocket connection: " + instance.url + " closed, trying reconnecting..."); instance.onclose(); - setTimeout(instance.reconnect, 3000); + setTimeout(() => { + instance.reconnect(); + }, 3000); // TODO: 重连间隔在配置文件中实现 }); } -} - -export default ReconnectingWebsocket; \ No newline at end of file +} \ No newline at end of file diff --git a/src/onebot11/event/manager.ts b/src/onebot11/event/manager.ts index 931b53d..93ce191 100644 --- a/src/onebot11/event/manager.ts +++ b/src/onebot11/event/manager.ts @@ -1,6 +1,6 @@ import * as websocket from "ws"; import {PostMsgType, wsReply} from "../server"; -import ReconnectingWebsocket from "../ReconnectingWebsocket"; +import {ReconnectingWebsocket} from "../ReconnectingWebsocket"; const websocketList = []; diff --git a/src/onebot11/server.ts b/src/onebot11/server.ts index 400b043..5ec0a83 100644 --- a/src/onebot11/server.ts +++ b/src/onebot11/server.ts @@ -8,7 +8,7 @@ import {OB11Message, OB11MessageData, OB11Return} from './types'; import {actionHandlers, actionMap} from "./actions"; import {OB11Response, OB11WebsocketResponse} from "./actions/utils"; import {callEvent, registerEventSender, unregisterEventSender} from "./event/manager"; -import ReconnectingWebsocket from "./ReconnectingWebsocket"; +import {ReconnectingWebsocket} from "./ReconnectingWebsocket"; import {ActionName} from "./actions/types"; import {OB11BaseMetaEvent} from "./event/meta/OB11BaseMetaEvent"; import {OB11BaseNoticeEvent} from "./event/notice/OB11BaseNoticeEvent"; @@ -216,49 +216,52 @@ export function initWebsocket(port: number) { }) } - initReverseWebsocket().then(); + initReverseWebsocket(); } -async function initReverseWebsocket() { +function initReverseWebsocket() { const config = getConfigUtil().getConfig(); if (config.enableWsReverse) { + console.log("Prepare to connect all reverse websockets..."); for (const url of config.wsHosts) { - try { - let wsClient = new ReconnectingWebsocket(url); - registerEventSender(wsClient); + new Promise(() => { + try { + let wsClient = new ReconnectingWebsocket(url); + registerEventSender(wsClient); - wsClient.onopen = function () { - wsReply(wsClient, new OB11LifeCycleEvent(LifeCycleSubType.CONNECT)); - } - - wsClient.onclose = function () { - unregisterEventSender(wsClient); - } - - wsClient.onmessage = async function (msg) { - let receiveData: { action: ActionName, params: any, echo?: string } = {action: null, params: {}} - let echo = "" - log("收到正向Websocket消息", msg.toString()) - try { - receiveData = JSON.parse(msg.toString()) - echo = receiveData.echo - } catch (e) { - return wsReply(wsClient, OB11WebsocketResponse.error("json解析失败,请检查数据格式", 1400, echo)) + wsClient.onopen = function () { + wsReply(wsClient, new OB11LifeCycleEvent(LifeCycleSubType.CONNECT)); } - const action: BaseAction = actionMap.get(receiveData.action); - if (!action) { - return wsReply(wsClient, OB11WebsocketResponse.error("不支持的api " + receiveData.action, 1404, echo)) + + wsClient.onclose = function () { + unregisterEventSender(wsClient); } - try { - let handleResult = await action.websocketHandle(receiveData.params, echo); - wsReply(wsClient, handleResult) - } catch (e) { - wsReply(wsClient, OB11WebsocketResponse.error(`api处理出错:${e}`, 1200, echo)) + + wsClient.onmessage = async function (msg) { + let receiveData: { action: ActionName, params: any, echo?: string } = {action: null, params: {}} + let echo = "" + log("收到正向Websocket消息", msg.toString()) + try { + receiveData = JSON.parse(msg.toString()) + echo = receiveData.echo + } catch (e) { + return wsReply(wsClient, OB11WebsocketResponse.error("json解析失败,请检查数据格式", 1400, echo)) + } + const action: BaseAction = actionMap.get(receiveData.action); + if (!action) { + return wsReply(wsClient, OB11WebsocketResponse.error("不支持的api " + receiveData.action, 1404, echo)) + } + try { + let handleResult = await action.websocketHandle(receiveData.params, echo); + wsReply(wsClient, handleResult) + } catch (e) { + wsReply(wsClient, OB11WebsocketResponse.error(`api处理出错:${e}`, 1200, echo)) + } } } - } - catch (e) { - console.log(e); - } + catch (e) { + log(e.stack); + } + }).then(); } } } @@ -298,7 +301,6 @@ export function postMsg(msg: PostMsgType) { } log("新消息事件ws上报", msg); - console.log("新消息事件ws上报", msg); callEvent(msg); } diff --git a/src/renderer.ts b/src/renderer.ts index fe2eee4..e673b44 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -155,13 +155,15 @@ async function onSettingWindowCreated(view: Element) { function addHostEle(type: string, initValue: string = "") { - let addressDoc = parser.parseFromString(createHttpHostEleStr(initValue), "text/html"); - let addressEle = addressDoc.querySelector("setting-item") - let hostItemsEle; + let addressEle, hostItemsEle; if (type === "ws") { + let addressDoc = parser.parseFromString(createWsHostEleStr(initValue), "text/html"); + addressEle = addressDoc.querySelector("setting-item") hostItemsEle = document.getElementById("wsHostItems"); } else { + let addressDoc = parser.parseFromString(createHttpHostEleStr(initValue), "text/html"); + addressEle = addressDoc.querySelector("setting-item") hostItemsEle = document.getElementById("httpHostItems"); }