mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
feat: support reverse websocket
This commit is contained in:
parent
f02b0bdcad
commit
018ec07082
43
package-lock.json
generated
43
package-lock.json
generated
@ -13,12 +13,14 @@
|
|||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"express-ws": "^5.0.2",
|
"express-ws": "^5.0.2",
|
||||||
"json-bigint": "^1.0.0",
|
"json-bigint": "^1.0.0",
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1",
|
||||||
|
"ws": "^8.16.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/preset-env": "^7.23.2",
|
"@babel/preset-env": "^7.23.2",
|
||||||
"@types/express": "^4.17.20",
|
"@types/express": "^4.17.20",
|
||||||
"@types/uuid": "^9.0.8",
|
"@types/uuid": "^9.0.8",
|
||||||
|
"@types/ws": "^8.5.10",
|
||||||
"babel-loader": "^9.1.3",
|
"babel-loader": "^9.1.3",
|
||||||
"ts-loader": "^9.5.0",
|
"ts-loader": "^9.5.0",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
@ -2200,6 +2202,15 @@
|
|||||||
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
|
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/ws": {
|
||||||
|
"version": "8.5.10",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@types/ws/-/ws-8.5.10.tgz",
|
||||||
|
"integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@webassemblyjs/ast": {
|
"node_modules/@webassemblyjs/ast": {
|
||||||
"version": "1.11.6",
|
"version": "1.11.6",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
|
||||||
@ -3138,6 +3149,26 @@
|
|||||||
"express": "^4.0.0 || ^5.0.0-alpha.1"
|
"express": "^4.0.0 || ^5.0.0-alpha.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/express-ws/node_modules/ws": {
|
||||||
|
"version": "7.5.9",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz",
|
||||||
|
"integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": "^5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
@ -4707,15 +4738,15 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "7.5.9",
|
"version": "8.16.0",
|
||||||
"resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz",
|
"resolved": "https://registry.npmmirror.com/ws/-/ws-8.16.0.tgz",
|
||||||
"integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
|
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.3.0"
|
"node": ">=10.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"bufferutil": "^4.0.1",
|
"bufferutil": "^4.0.1",
|
||||||
"utf-8-validate": "^5.0.2"
|
"utf-8-validate": ">=5.0.2"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"bufferutil": {
|
"bufferutil": {
|
||||||
|
@ -21,12 +21,14 @@
|
|||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"express-ws": "^5.0.2",
|
"express-ws": "^5.0.2",
|
||||||
"json-bigint": "^1.0.0",
|
"json-bigint": "^1.0.0",
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1",
|
||||||
|
"ws": "^8.16.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/preset-env": "^7.23.2",
|
"@babel/preset-env": "^7.23.2",
|
||||||
"@types/express": "^4.17.20",
|
"@types/express": "^4.17.20",
|
||||||
"@types/uuid": "^9.0.8",
|
"@types/uuid": "^9.0.8",
|
||||||
|
"@types/ws": "^8.5.10",
|
||||||
"babel-loader": "^9.1.3",
|
"babel-loader": "^9.1.3",
|
||||||
"ts-loader": "^9.5.0",
|
"ts-loader": "^9.5.0",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
|
@ -49,6 +49,10 @@ export function isGIF(path: string) {
|
|||||||
return buffer.toString() === 'GIF8'
|
return buffer.toString() === 'GIF8'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sleep(ms: number): Promise<void> {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 定义一个异步函数来检查文件是否存在
|
// 定义一个异步函数来检查文件是否存在
|
||||||
export function checkFileReceived(path: string, timeout: number=3000): Promise<void> {
|
export function checkFileReceived(path: string, timeout: number=3000): Promise<void> {
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import {BrowserWindow} from 'electron';
|
import {BrowserWindow} from 'electron';
|
||||||
import {log} from "../common/utils";
|
import {log, sleep} from "../common/utils";
|
||||||
import {NTQQApi, NTQQApiClass, sendMessagePool} from "./ntcall";
|
import {NTQQApi, NTQQApiClass, sendMessagePool} from "./ntcall";
|
||||||
import {Group, GroupMember, RawMessage, User} from "./types";
|
import {Group, GroupMember, RawMessage, User} from "./types";
|
||||||
import {addHistoryMsg, friends, groups, msgHistory} from "../common/data";
|
import {addHistoryMsg, friends, groups, msgHistory} from "../common/data";
|
||||||
import {v4 as uuidv4} from 'uuid';
|
import {v4 as uuidv4} from 'uuid';
|
||||||
import {callEvent, EventType} from "../onebot11/event";
|
import {callEvent, EventType} from "../onebot11/event/manager";
|
||||||
import {OB11Message} from "../onebot11/types";
|
import {OB11Message} from "../onebot11/types";
|
||||||
import {OB11Constructor} from "../onebot11/constructor";
|
import {OB11Constructor} from "../onebot11/constructor";
|
||||||
|
import BaseMessageEvent from "../onebot11/event/BaseMessageEvent";
|
||||||
|
import GroupDecreaseEvent from "../onebot11/event/GroupDecreaseEvent";
|
||||||
|
import GroupIncreaseEvent from "../onebot11/event/GroupIncreaseEvent";
|
||||||
|
|
||||||
export let hookApiCallbacks: Record<string, (apiReturn: any) => void> = {}
|
export let hookApiCallbacks: Record<string, (apiReturn: any) => void> = {}
|
||||||
|
|
||||||
@ -120,18 +123,10 @@ async function processGroupEvent(payload) {
|
|||||||
let existGroup = groups.find(g => g.groupCode == group.groupCode);
|
let existGroup = groups.find(g => g.groupCode == group.groupCode);
|
||||||
if (existGroup) {
|
if (existGroup) {
|
||||||
if (existGroup.memberCount > group.memberCount) {
|
if (existGroup.memberCount > group.memberCount) {
|
||||||
console.log("群人数减少力!");
|
|
||||||
const oldMembers = existGroup.members;
|
const oldMembers = existGroup.members;
|
||||||
console.log("旧群人员:");
|
|
||||||
for (const member of oldMembers) {
|
|
||||||
console.log(member.nick);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
await sleep(200); // 如果请求QQ API的速度过快,通常无法正确拉取到最新的群信息,因此这里人为引入一个延时
|
||||||
const newMembers = await NTQQApi.getGroupMembers(group.groupCode);
|
const newMembers = await NTQQApi.getGroupMembers(group.groupCode);
|
||||||
console.log("新群人员:");
|
|
||||||
for (const member of newMembers) {
|
|
||||||
console.log(member.nick);
|
|
||||||
}
|
|
||||||
|
|
||||||
group.members = newMembers;
|
group.members = newMembers;
|
||||||
const newMembersSet = new Set<string>(); // 建立索引降低时间复杂度
|
const newMembersSet = new Set<string>(); // 建立索引降低时间复杂度
|
||||||
@ -142,35 +137,26 @@ async function processGroupEvent(payload) {
|
|||||||
|
|
||||||
for (const member of oldMembers) {
|
for (const member of oldMembers) {
|
||||||
if (!newMembersSet.has(member.uin)) {
|
if (!newMembersSet.has(member.uin)) {
|
||||||
console.log("减少的群员是:" + member.uin);
|
callEvent(new GroupDecreaseEvent(group.groupCode, parseInt(member.uin)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (existGroup.memberCount < group.memberCount) {
|
else if (existGroup.memberCount < group.memberCount) {
|
||||||
console.log("群人数增加力!");
|
const oldMembers = existGroup.members;
|
||||||
console.log("旧群人员:");
|
|
||||||
for (const member of existGroup.members) {
|
|
||||||
console.log(member.nick);
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldMembersSet = new Set<string>();
|
const oldMembersSet = new Set<string>();
|
||||||
for (const member of existGroup.members) {
|
for (const member of oldMembers) {
|
||||||
oldMembersSet.add(member.uin);
|
oldMembersSet.add(member.uin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await sleep(200);
|
||||||
const newMembers = await NTQQApi.getGroupMembers(group.groupCode);
|
const newMembers = await NTQQApi.getGroupMembers(group.groupCode);
|
||||||
|
|
||||||
console.log("新群人员:");
|
|
||||||
for (const member of newMembers) {
|
|
||||||
console.log(member.nick);
|
|
||||||
}
|
|
||||||
|
|
||||||
group.members = newMembers;
|
group.members = newMembers;
|
||||||
for (const member of newMembers) {
|
for (const member of newMembers) {
|
||||||
if (!oldMembersSet.has(member.uin)) {
|
if (!oldMembersSet.has(member.uin)) {
|
||||||
console.log("增加的群员是:" + member.uin);
|
callEvent(new GroupIncreaseEvent(group.groupCode, parseInt(member.uin)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,13 +217,13 @@ registerReceiveHook<{ msgList: Array<RawMessage> }>(ReceiveCmd.UPDATE_MSG, (payl
|
|||||||
registerReceiveHook<{ msgList: Array<RawMessage> }>(ReceiveCmd.NEW_MSG, (payload) => {
|
registerReceiveHook<{ msgList: Array<RawMessage> }>(ReceiveCmd.NEW_MSG, (payload) => {
|
||||||
for (const message of payload.msgList) {
|
for (const message of payload.msgList) {
|
||||||
// log("收到新消息,push到历史记录", message)
|
// log("收到新消息,push到历史记录", message)
|
||||||
|
addHistoryMsg(message)
|
||||||
|
|
||||||
OB11Constructor.message(message).then(
|
OB11Constructor.message(message).then(
|
||||||
function (message) {
|
function (message) {
|
||||||
callEvent<OB11Message>(EventType.MESSAGE, message);
|
callEvent<OB11Message>(new BaseMessageEvent(), message);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
addHistoryMsg(message)
|
|
||||||
}
|
}
|
||||||
const msgIds = Object.keys(msgHistory);
|
const msgIds = Object.keys(msgHistory);
|
||||||
if (msgIds.length > 30000) {
|
if (msgIds.length > 30000) {
|
||||||
|
64
src/onebot11/ReconnectingWebsocket.ts
Normal file
64
src/onebot11/ReconnectingWebsocket.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
const WebSocket = require("ws");
|
||||||
|
|
||||||
|
class ReconnectingWebsocket {
|
||||||
|
private websocket;
|
||||||
|
private readonly url: string;
|
||||||
|
|
||||||
|
public constructor(url: string) {
|
||||||
|
this.url = url;
|
||||||
|
this.reconnect()
|
||||||
|
}
|
||||||
|
|
||||||
|
public onopen = function (){}
|
||||||
|
|
||||||
|
public onmessage = function (msg){}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private reconnect() {
|
||||||
|
this.websocket = new WebSocket(this.url, {
|
||||||
|
handshakeTimeout: 2000,
|
||||||
|
perMessageDeflate: false
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Trying to connect to the websocket server: " + this.url);
|
||||||
|
|
||||||
|
const instance = this;
|
||||||
|
|
||||||
|
this.websocket.on("open", function open() {
|
||||||
|
console.log("Connected to the websocket server: " + instance.url);
|
||||||
|
instance.onopen();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.websocket.on("message", function message(data) {
|
||||||
|
instance.onmessage(data.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
this.websocket.on("error", console.error);
|
||||||
|
|
||||||
|
this.websocket.on("ping", this.heartbeat);
|
||||||
|
|
||||||
|
this.websocket.on("close", function close() {
|
||||||
|
console.log("The websocket connection: " + instance.url + " closed, trying reconnecting...");
|
||||||
|
instance.onclose();
|
||||||
|
|
||||||
|
setTimeout(instance.reconnect, 3000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ReconnectingWebsocket;
|
@ -13,7 +13,6 @@ import { SendMessageElement } from "../../ntqqapi/types";
|
|||||||
import { SendMsgElementConstructor } from "../../ntqqapi/constructor";
|
import { SendMsgElementConstructor } from "../../ntqqapi/constructor";
|
||||||
import { uri2local } from "../utils";
|
import { uri2local } from "../utils";
|
||||||
import { v4 as uuid4 } from 'uuid';
|
import { v4 as uuid4 } from 'uuid';
|
||||||
import { log } from "../../common/utils";
|
|
||||||
import BaseAction from "./BaseAction";
|
import BaseAction from "./BaseAction";
|
||||||
import { ActionName } from "./types";
|
import { ActionName } from "./types";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
|
10
src/onebot11/event/BaseEvent.ts
Normal file
10
src/onebot11/event/BaseEvent.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import {selfInfo} from "../../common/data";
|
||||||
|
import {EventType} from "./manager";
|
||||||
|
|
||||||
|
class BaseEvent {
|
||||||
|
time = new Date().getTime();
|
||||||
|
self_id = selfInfo.uin;
|
||||||
|
post_type: EventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BaseEvent;
|
8
src/onebot11/event/BaseMessageEvent.ts
Normal file
8
src/onebot11/event/BaseMessageEvent.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import BaseEvent from "./BaseEvent";
|
||||||
|
import {EventType} from "./manager";
|
||||||
|
|
||||||
|
class BaseMessageEvent extends BaseEvent {
|
||||||
|
post_type = EventType.MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BaseMessageEvent
|
20
src/onebot11/event/GroupDecreaseEvent.ts
Normal file
20
src/onebot11/event/GroupDecreaseEvent.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import BaseEvent from "./BaseEvent";
|
||||||
|
import {EventType} from "./manager";
|
||||||
|
|
||||||
|
class GroupDecreaseEvent extends BaseEvent {
|
||||||
|
post_type = EventType.NOTICE;
|
||||||
|
notice_type = "group_decrease";
|
||||||
|
subtype = "leave"; // TODO: 实现其他几种子类型的识别
|
||||||
|
group_id: number;
|
||||||
|
operate_id: number;
|
||||||
|
user_id: number;
|
||||||
|
|
||||||
|
constructor(groupId: number, userId: number) {
|
||||||
|
super();
|
||||||
|
this.group_id = groupId;
|
||||||
|
this.operate_id = userId; // 实际上不应该这么实现,但是现在还没有办法识别用户是被踢出的,还是自己主动退出的
|
||||||
|
this.user_id = userId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GroupDecreaseEvent
|
21
src/onebot11/event/GroupIncreaseEvent.ts
Normal file
21
src/onebot11/event/GroupIncreaseEvent.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import BaseEvent from "./BaseEvent";
|
||||||
|
import {EventType} from "./manager";
|
||||||
|
|
||||||
|
class GroupIncreaseEvent extends BaseEvent {
|
||||||
|
post_type = EventType.NOTICE;
|
||||||
|
notice_type = "group_increase";
|
||||||
|
subtype = "approve"; // TODO: 实现其他几种子类型的识别
|
||||||
|
group_id: number;
|
||||||
|
operate_id: number;
|
||||||
|
user_id: number;
|
||||||
|
|
||||||
|
constructor(groupId: number, userId: number) {
|
||||||
|
super();
|
||||||
|
this.group_id = groupId;
|
||||||
|
this.operate_id = userId; // 实际上不应该这么实现,但是现在还没有办法识别用户是被邀请的,还是主动加入的
|
||||||
|
this.user_id = userId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default GroupIncreaseEvent
|
@ -1,4 +1,5 @@
|
|||||||
import {selfInfo} from "../common/data";
|
import {selfInfo} from "../../common/data";
|
||||||
|
import BaseEvent from "./BaseEvent";
|
||||||
|
|
||||||
const websocketList = [];
|
const websocketList = [];
|
||||||
|
|
||||||
@ -20,19 +21,12 @@ export function unregisterEventSender(ws) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function callEvent<DataType>(type: EventType, data: DataType) {
|
export function callEvent<DataType>(event: BaseEvent, data: DataType = null) {
|
||||||
const basicEvent = {
|
|
||||||
time: new Date().getTime(),
|
|
||||||
self_id: selfInfo.uin,
|
|
||||||
post_type: type
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
const assignedEvent = (data == null ? event : Object.assign(event, data));
|
||||||
for (const ws of websocketList) {
|
for (const ws of websocketList) {
|
||||||
ws.send(
|
ws.send(
|
||||||
JSON.stringify(
|
JSON.stringify(assignedEvent)
|
||||||
Object.assign(basicEvent, data)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,10 +11,17 @@ import { selfInfo } from "../common/data";
|
|||||||
import { OB11Message, OB11Return, OB11MessageData } from './types';
|
import { OB11Message, OB11Return, OB11MessageData } from './types';
|
||||||
import {actionHandlers, actionMap} from "./actions";
|
import {actionHandlers, actionMap} from "./actions";
|
||||||
import {OB11Response, OB11WebsocketResponse} from "./actions/utils";
|
import {OB11Response, OB11WebsocketResponse} from "./actions/utils";
|
||||||
import {registerEventSender, unregisterEventSender} from "./event";
|
import {registerEventSender, unregisterEventSender} from "./event/manager";
|
||||||
|
import ReconnectingWebsocket from "./ReconnectingWebsocket";
|
||||||
|
|
||||||
|
|
||||||
// @SiberianHusky 2021-08-15
|
// @SiberianHusky 2021-08-15
|
||||||
|
enum WebsocketType {
|
||||||
|
API,
|
||||||
|
EVENT,
|
||||||
|
ALL
|
||||||
|
}
|
||||||
|
|
||||||
function checkSendMessage(sendMsgList: OB11MessageData[]) {
|
function checkSendMessage(sendMsgList: OB11MessageData[]) {
|
||||||
function checkUri(uri: string): boolean {
|
function checkUri(uri: string): boolean {
|
||||||
const pattern = /^(file:\/\/|http:\/\/|https:\/\/|base64:\/\/)/;
|
const pattern = /^(file:\/\/|http:\/\/|https:\/\/|base64:\/\/)/;
|
||||||
@ -92,17 +99,29 @@ export function startExpress(port: number) {
|
|||||||
export function startWebsocketServer(port: number) {
|
export function startWebsocketServer(port: number) {
|
||||||
const config = getConfigUtil().getConfig();
|
const config = getConfigUtil().getConfig();
|
||||||
if (config.enableWs) {
|
if (config.enableWs) {
|
||||||
expressWs(expressWsApp)
|
try {
|
||||||
expressWsApp.listen(getConfigUtil().getConfig().wsPort, function () {
|
expressWs(expressWsApp)
|
||||||
console.log(`llonebot websocket service started 0.0.0.0:${port}`);
|
expressWsApp.listen(getConfigUtil().getConfig().wsPort, function () {
|
||||||
});
|
console.log(`llonebot websocket service started 0.0.0.0:${port}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initWebsocket() {
|
export function initWebsocket() {
|
||||||
if (getConfigUtil().getConfig().enableWs) {
|
if (getConfigUtil().getConfig().enableWs) {
|
||||||
expressWsApp.ws("/api", initWebsocketServer);
|
expressWsApp.ws("/api", (ws, req) => {
|
||||||
expressWsApp.ws("/", initWebsocketServer);
|
initWebsocketServer(ws, req, WebsocketType.API);
|
||||||
|
});
|
||||||
|
expressWsApp.ws("/event", (ws, req) => {
|
||||||
|
initWebsocketServer(ws, req, WebsocketType.EVENT);
|
||||||
|
});
|
||||||
|
expressWsApp.ws("/", (ws, req) => {
|
||||||
|
initWebsocketServer(ws, req, WebsocketType.ALL);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initReverseWebsocket();
|
initReverseWebsocket();
|
||||||
@ -113,11 +132,12 @@ function initReverseWebsocket() {
|
|||||||
if (config.enableWsReverse) {
|
if (config.enableWsReverse) {
|
||||||
for (const url of config.wsHosts) {
|
for (const url of config.wsHosts) {
|
||||||
try {
|
try {
|
||||||
const wsClient = new WebSocket(url);
|
let wsClient = new ReconnectingWebsocket(url);
|
||||||
websocketClientConnections.push(wsClient);
|
websocketClientConnections.push(wsClient);
|
||||||
registerEventSender(wsClient);
|
registerEventSender(wsClient);
|
||||||
|
|
||||||
wsClient.onclose = function (ev) {
|
wsClient.onclose = function () {
|
||||||
|
console.log("The websocket connection: " + url + " closed, trying reconnecting...");
|
||||||
unregisterEventSender(wsClient);
|
unregisterEventSender(wsClient);
|
||||||
let index = websocketClientConnections.indexOf(wsClient);
|
let index = websocketClientConnections.indexOf(wsClient);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
@ -125,8 +145,8 @@ function initReverseWebsocket() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wsClient.onmessage = async function (ev) {
|
wsClient.onmessage = async function (message) {
|
||||||
let message = ev.data;
|
console.log(message);
|
||||||
if (typeof message === "string") {
|
if (typeof message === "string") {
|
||||||
try {
|
try {
|
||||||
let recv = JSON.parse(message);
|
let recv = JSON.parse(message);
|
||||||
@ -147,35 +167,43 @@ function initReverseWebsocket() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {}
|
catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function initWebsocketServer(ws, req) {
|
function initWebsocketServer(ws, req, type: WebsocketType) {
|
||||||
registerEventSender(ws);
|
if (type == WebsocketType.EVENT || type == WebsocketType.ALL) {
|
||||||
|
registerEventSender(ws);
|
||||||
|
}
|
||||||
|
|
||||||
ws.on("message", async function (message) {
|
ws.on("message", async function (message) {
|
||||||
try {
|
if (type == WebsocketType.API || type == WebsocketType.ALL) {
|
||||||
let recv = JSON.parse(message);
|
try {
|
||||||
let echo = recv.echo ?? "";
|
let recv = JSON.parse(message);
|
||||||
|
let echo = recv.echo ?? "";
|
||||||
|
|
||||||
if (actionMap.has(recv.action)) {
|
if (actionMap.has(recv.action)) {
|
||||||
let action = actionMap.get(recv.action)
|
let action = actionMap.get(recv.action)
|
||||||
const result = await action.websocketHandle(recv.params, echo);
|
const result = await action.websocketHandle(recv.params, echo);
|
||||||
ws.send(JSON.stringify(result));
|
ws.send(JSON.stringify(result));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ws.send(JSON.stringify(OB11WebsocketResponse.error("Bad Request", 1400, echo)));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log(e.stack);
|
||||||
|
ws.send(JSON.stringify(OB11WebsocketResponse.error(e.stack.toString(), 1200)));
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
ws.send(JSON.stringify(OB11WebsocketResponse.error("Bad Request", 1400, echo)));
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
log(e.stack);
|
|
||||||
ws.send(JSON.stringify(OB11WebsocketResponse.error(e.stack.toString(), 1200)));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ws.on("close", function (ev) {
|
ws.on("close", function (ev) {
|
||||||
unregisterEventSender(ws);
|
if (type == WebsocketType.EVENT || type == WebsocketType.ALL) {
|
||||||
|
unregisterEventSender(ws);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user