mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
refactor: network
This commit is contained in:
parent
e8faa09f1d
commit
d392e653e1
@ -78,6 +78,7 @@ export const websocketClientDefaultConfigs = createDefaultAdapterConfig({
|
|||||||
url: 'ws://localhost:8082',
|
url: 'ws://localhost:8082',
|
||||||
messagePostFormat: 'array',
|
messagePostFormat: 'array',
|
||||||
reportSelfMessage: false,
|
reportSelfMessage: false,
|
||||||
|
reconnectInterval: 5000,
|
||||||
token: '',
|
token: '',
|
||||||
debug: false,
|
debug: false,
|
||||||
heartInterval: 30000,
|
heartInterval: 30000,
|
||||||
|
@ -110,14 +110,14 @@ export class NapCatOneBot11Adapter {
|
|||||||
for (const key of ob11Config.network.httpServers) {
|
for (const key of ob11Config.network.httpServers) {
|
||||||
if (key.enable) {
|
if (key.enable) {
|
||||||
this.networkManager.registerAdapter(
|
this.networkManager.registerAdapter(
|
||||||
new OB11PassiveHttpAdapter(key.name, key.port, key.token, this.core, this.actions)
|
new OB11PassiveHttpAdapter(key.name, key, this.core, this.actions)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const key of ob11Config.network.httpClients) {
|
for (const key of ob11Config.network.httpClients) {
|
||||||
if (key.enable) {
|
if (key.enable) {
|
||||||
this.networkManager.registerAdapter(
|
this.networkManager.registerAdapter(
|
||||||
new OB11ActiveHttpAdapter(key.name, key.url, key.token, this.core, this)
|
new OB11ActiveHttpAdapter(key.name, key, this.core, this, this.actions)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,10 +126,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
this.networkManager.registerAdapter(
|
this.networkManager.registerAdapter(
|
||||||
new OB11PassiveWebSocketAdapter(
|
new OB11PassiveWebSocketAdapter(
|
||||||
key.name,
|
key.name,
|
||||||
key.host,
|
key,
|
||||||
key.port,
|
|
||||||
key.heartInterval,
|
|
||||||
key.token,
|
|
||||||
this.core,
|
this.core,
|
||||||
this.actions
|
this.actions
|
||||||
)
|
)
|
||||||
@ -141,10 +138,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
this.networkManager.registerAdapter(
|
this.networkManager.registerAdapter(
|
||||||
new OB11ActiveWebSocketAdapter(
|
new OB11ActiveWebSocketAdapter(
|
||||||
key.name,
|
key.name,
|
||||||
key.url,
|
key,
|
||||||
5000,
|
|
||||||
key.heartInterval,
|
|
||||||
key.token,
|
|
||||||
this.core,
|
this.core,
|
||||||
this.actions
|
this.actions
|
||||||
)
|
)
|
||||||
@ -215,7 +209,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
const prevServer = prev.network.httpServers.find(s => s.name === server.name);
|
const prevServer = prev.network.httpServers.find(s => s.name === server.name);
|
||||||
if (prevServer && prevServer.enable !== server.enable) {
|
if (prevServer && prevServer.enable !== server.enable) {
|
||||||
if (server.enable) {
|
if (server.enable) {
|
||||||
let adapter = new OB11PassiveHttpAdapter(server.name, server.port, server.token, this.core, this.actions);
|
let adapter = new OB11PassiveHttpAdapter(server.name, server, this.core, this.actions);
|
||||||
adapter.open();
|
adapter.open();
|
||||||
this.networkManager.registerAdapter(
|
this.networkManager.registerAdapter(
|
||||||
adapter
|
adapter
|
||||||
@ -231,7 +225,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
const prevClient = prev.network.httpClients.find(c => c.name === client.name);
|
const prevClient = prev.network.httpClients.find(c => c.name === client.name);
|
||||||
if (prevClient && prevClient.enable !== client.enable) {
|
if (prevClient && prevClient.enable !== client.enable) {
|
||||||
if (client.enable) {
|
if (client.enable) {
|
||||||
let adapter = new OB11ActiveHttpAdapter(client.name, client.url, client.token, this.core, this);
|
let adapter = new OB11ActiveHttpAdapter(client.name, client, this.core, this,this.actions);
|
||||||
adapter.open();
|
adapter.open();
|
||||||
this.networkManager.registerAdapter(
|
this.networkManager.registerAdapter(
|
||||||
adapter
|
adapter
|
||||||
@ -249,10 +243,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
if (server.enable) {
|
if (server.enable) {
|
||||||
let adapter = new OB11PassiveWebSocketAdapter(
|
let adapter = new OB11PassiveWebSocketAdapter(
|
||||||
server.name,
|
server.name,
|
||||||
server.host,
|
server,
|
||||||
server.port,
|
|
||||||
server.heartInterval,
|
|
||||||
server.token,
|
|
||||||
this.core,
|
this.core,
|
||||||
this.actions
|
this.actions
|
||||||
);
|
);
|
||||||
@ -273,10 +264,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
if (client.enable) {
|
if (client.enable) {
|
||||||
let adapter = new OB11ActiveWebSocketAdapter(
|
let adapter = new OB11ActiveWebSocketAdapter(
|
||||||
client.name,
|
client.name,
|
||||||
client.url,
|
client,
|
||||||
5000,
|
|
||||||
client.heartInterval,
|
|
||||||
client.token,
|
|
||||||
this.core,
|
this.core,
|
||||||
this.actions
|
this.actions
|
||||||
)
|
)
|
||||||
@ -292,7 +280,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
// 注册新的 HTTP 服务器
|
// 注册新的 HTTP 服务器
|
||||||
for (const server of addedHttpServers) {
|
for (const server of addedHttpServers) {
|
||||||
if (server.enable) {
|
if (server.enable) {
|
||||||
let adapter = new OB11PassiveHttpAdapter(server.name, server.port, server.token, this.core, this.actions);
|
let adapter = new OB11PassiveHttpAdapter(server.name, server, this.core, this.actions);
|
||||||
adapter.open();
|
adapter.open();
|
||||||
this.networkManager.registerAdapter(adapter);
|
this.networkManager.registerAdapter(adapter);
|
||||||
}
|
}
|
||||||
@ -302,7 +290,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
for (const client of addedHttpClients) {
|
for (const client of addedHttpClients) {
|
||||||
|
|
||||||
if (client.enable) {
|
if (client.enable) {
|
||||||
let adapter = new OB11ActiveHttpAdapter(client.name, client.url, client.token, this.core, this);
|
let adapter = new OB11ActiveHttpAdapter(client.name, client, this.core, this,this.actions);
|
||||||
adapter.open();
|
adapter.open();
|
||||||
this.networkManager.registerAdapter(adapter);
|
this.networkManager.registerAdapter(adapter);
|
||||||
}
|
}
|
||||||
@ -313,10 +301,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
if (server.enable) {
|
if (server.enable) {
|
||||||
let adapter = new OB11PassiveWebSocketAdapter(
|
let adapter = new OB11PassiveWebSocketAdapter(
|
||||||
server.name,
|
server.name,
|
||||||
server.host,
|
server,
|
||||||
server.port,
|
|
||||||
server.heartInterval,
|
|
||||||
server.token,
|
|
||||||
this.core,
|
this.core,
|
||||||
this.actions
|
this.actions
|
||||||
);
|
);
|
||||||
@ -330,10 +315,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
if (client.enable) {
|
if (client.enable) {
|
||||||
let adapter = new OB11ActiveWebSocketAdapter(
|
let adapter = new OB11ActiveWebSocketAdapter(
|
||||||
client.name,
|
client.name,
|
||||||
client.url,
|
client,
|
||||||
5000,
|
|
||||||
client.heartInterval,
|
|
||||||
client.token,
|
|
||||||
this.core,
|
this.core,
|
||||||
this.actions
|
this.actions
|
||||||
)
|
)
|
||||||
|
@ -5,23 +5,27 @@ import { QuickAction, QuickActionEvent } from '../types';
|
|||||||
import { NapCatCore } from '@/core';
|
import { NapCatCore } from '@/core';
|
||||||
import { NapCatOneBot11Adapter } from '..';
|
import { NapCatOneBot11Adapter } from '..';
|
||||||
import { RequestUtil } from '@/common/request';
|
import { RequestUtil } from '@/common/request';
|
||||||
|
import { HttpClientConfig } from '../config/config';
|
||||||
|
import { ActionMap } from '../action';
|
||||||
|
|
||||||
export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter {
|
export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter {
|
||||||
logger: LogWrapper;
|
logger: LogWrapper;
|
||||||
isOpen: boolean = false;
|
isEnable: boolean = false;
|
||||||
|
config: HttpClientConfig;
|
||||||
constructor(
|
constructor(
|
||||||
public name: string,
|
public name: string,
|
||||||
public url: string,
|
config: HttpClientConfig,
|
||||||
public secret: string | undefined,
|
|
||||||
public core: NapCatCore,
|
public core: NapCatCore,
|
||||||
public obContext: NapCatOneBot11Adapter,
|
public obContext: NapCatOneBot11Adapter,
|
||||||
|
public actions: ActionMap,
|
||||||
) {
|
) {
|
||||||
this.logger = core.context.logger;
|
this.logger = core.context.logger;
|
||||||
|
this.config = structuredClone(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
onEvent<T extends OB11EmitEventContent>(event: T) {
|
onEvent<T extends OB11EmitEventContent>(event: T) {
|
||||||
if (!this.isOpen) {
|
if (!this.isEnable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
@ -29,13 +33,13 @@ export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter {
|
|||||||
'x-self-id': this.core.selfInfo.uin,
|
'x-self-id': this.core.selfInfo.uin,
|
||||||
};
|
};
|
||||||
const msgStr = JSON.stringify(event);
|
const msgStr = JSON.stringify(event);
|
||||||
if (this.secret && this.secret.length > 0) {
|
if (this.config.token && this.config.token.length > 0) {
|
||||||
const hmac = createHmac('sha1', this.secret);
|
const hmac = createHmac('sha1', this.config.token);
|
||||||
hmac.update(msgStr);
|
hmac.update(msgStr);
|
||||||
const sig = hmac.digest('hex');
|
const sig = hmac.digest('hex');
|
||||||
headers['x-signature'] = 'sha1=' + sig;
|
headers['x-signature'] = 'sha1=' + sig;
|
||||||
}
|
}
|
||||||
RequestUtil.HttpGetText(this.url, 'POST', msgStr, headers).then(async (res) => {
|
RequestUtil.HttpGetText(this.config.url, 'POST', msgStr, headers).then(async (res) => {
|
||||||
let resJson: QuickAction;
|
let resJson: QuickAction;
|
||||||
try {
|
try {
|
||||||
resJson = JSON.parse(res);
|
resJson = JSON.parse(res);
|
||||||
@ -57,10 +61,13 @@ export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open() {
|
open() {
|
||||||
this.isOpen = true;
|
this.isEnable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
this.isOpen = false;
|
this.isEnable = false;
|
||||||
|
}
|
||||||
|
async reload(config: HttpClientConfig){
|
||||||
|
this.config = structuredClone(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,23 +7,23 @@ import { OB11Response } from '@/onebot/action/OB11Response';
|
|||||||
import { LogWrapper } from '@/common/log';
|
import { LogWrapper } from '@/common/log';
|
||||||
import { ActionMap } from '@/onebot/action';
|
import { ActionMap } from '@/onebot/action';
|
||||||
import { LifeCycleSubType, OB11LifeCycleEvent } from '../event/meta/OB11LifeCycleEvent';
|
import { LifeCycleSubType, OB11LifeCycleEvent } from '../event/meta/OB11LifeCycleEvent';
|
||||||
|
import { WebsocketClientConfig } from '../config/config';
|
||||||
|
|
||||||
export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||||
isClosed: boolean = false;
|
isEnable: boolean = false;
|
||||||
logger: LogWrapper;
|
logger: LogWrapper;
|
||||||
private connection: WebSocket | null = null;
|
private connection: WebSocket | null = null;
|
||||||
private heartbeatRef: NodeJS.Timeout | null = null;
|
private heartbeatRef: NodeJS.Timeout | null = null;
|
||||||
|
config: WebsocketClientConfig;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public name: string,
|
public name: string,
|
||||||
public url: string,
|
confg: WebsocketClientConfig,
|
||||||
public reconnectIntervalInMillis: number,
|
|
||||||
public heartbeatIntervalInMillis: number,
|
|
||||||
private readonly token: string,
|
|
||||||
public core: NapCatCore,
|
public core: NapCatCore,
|
||||||
public actions: ActionMap,
|
public actions: ActionMap,
|
||||||
) {
|
) {
|
||||||
this.logger = core.context.logger;
|
this.logger = core.context.logger;
|
||||||
|
this.config = structuredClone(confg);
|
||||||
}
|
}
|
||||||
|
|
||||||
onEvent<T extends OB11EmitEventContent>(event: T) {
|
onEvent<T extends OB11EmitEventContent>(event: T) {
|
||||||
@ -36,23 +36,23 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
if (this.connection) {
|
if (this.connection) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.heartbeatIntervalInMillis > 0) {
|
if (this.config.heartInterval > 0) {
|
||||||
this.heartbeatRef = setInterval(() => {
|
this.heartbeatRef = setInterval(() => {
|
||||||
if (this.connection && this.connection.readyState === WebSocket.OPEN) {
|
if (this.connection && this.connection.readyState === WebSocket.OPEN) {
|
||||||
this.connection.send(JSON.stringify(new OB11HeartbeatEvent(this.core, this.heartbeatIntervalInMillis, this.core.selfInfo.online ?? true, true)));
|
this.connection.send(JSON.stringify(new OB11HeartbeatEvent(this.core, this.config.heartInterval, this.core.selfInfo.online ?? true, true)));
|
||||||
}
|
}
|
||||||
}, this.heartbeatIntervalInMillis);
|
}, this.config.heartInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.tryConnect();
|
await this.tryConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
if (this.isClosed) {
|
if (!this.isEnable) {
|
||||||
this.logger.logDebug('Cannot close a closed WebSocket connection');
|
this.logger.logDebug('Cannot close a closed WebSocket connection');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.isClosed = true;
|
this.isEnable = false;
|
||||||
if (this.connection) {
|
if (this.connection) {
|
||||||
this.connection.close();
|
this.connection.close();
|
||||||
this.connection = null;
|
this.connection = null;
|
||||||
@ -70,16 +70,16 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async tryConnect() {
|
private async tryConnect() {
|
||||||
if (!this.connection && !this.isClosed) {
|
if (!this.connection && this.isEnable) {
|
||||||
let isClosedByError = false;
|
let isClosedByError = false;
|
||||||
|
|
||||||
this.connection = new WebSocket(this.url, {
|
this.connection = new WebSocket(this.config.url, {
|
||||||
maxPayload: 1024 * 1024 * 1024,
|
maxPayload: 1024 * 1024 * 1024,
|
||||||
handshakeTimeout: 2000,
|
handshakeTimeout: 2000,
|
||||||
perMessageDeflate: false,
|
perMessageDeflate: false,
|
||||||
headers: {
|
headers: {
|
||||||
'X-Self-ID': this.core.selfInfo.uin,
|
'X-Self-ID': this.core.selfInfo.uin,
|
||||||
'Authorization': `Bearer ${this.token}`,
|
'Authorization': `Bearer ${this.config.token}`,
|
||||||
'x-client-role': 'Universal', // koishi-adapter-onebot 需要这个字段
|
'x-client-role': 'Universal', // koishi-adapter-onebot 需要这个字段
|
||||||
'User-Agent': 'OneBot/11',
|
'User-Agent': 'OneBot/11',
|
||||||
},
|
},
|
||||||
@ -104,21 +104,21 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
});
|
});
|
||||||
this.connection.once('close', () => {
|
this.connection.once('close', () => {
|
||||||
if (!isClosedByError) {
|
if (!isClosedByError) {
|
||||||
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 反向WebSocket (${this.url}) 连接意外关闭`);
|
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 反向WebSocket (${this.config.url}) 连接意外关闭`);
|
||||||
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.reconnectIntervalInMillis / 1000)} 秒后尝试重新连接`);
|
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.config.reconnectInterval / 1000)} 秒后尝试重新连接`);
|
||||||
if (!this.isClosed) {
|
if (this.isEnable) {
|
||||||
this.connection = null;
|
this.connection = null;
|
||||||
setTimeout(() => this.tryConnect(), this.reconnectIntervalInMillis);
|
setTimeout(() => this.tryConnect(), this.config.reconnectInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.connection.on('error', (err) => {
|
this.connection.on('error', (err) => {
|
||||||
isClosedByError = true;
|
isClosedByError = true;
|
||||||
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 反向WebSocket (${this.url}) 连接错误`, err);
|
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 反向WebSocket (${this.config.url}) 连接错误`, err);
|
||||||
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.reconnectIntervalInMillis / 1000)} 秒后尝试重新连接`);
|
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.config.reconnectInterval / 1000)} 秒后尝试重新连接`);
|
||||||
if (!this.isClosed) {
|
if (this.isEnable) {
|
||||||
this.connection = null;
|
this.connection = null;
|
||||||
setTimeout(() => this.tryConnect(), this.reconnectIntervalInMillis);
|
setTimeout(() => this.tryConnect(), this.config.reconnectInterval);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -154,4 +154,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
||||||
this.checkStateAndReply<any>({ ...retdata });
|
this.checkStateAndReply<any>({ ...retdata });
|
||||||
}
|
}
|
||||||
|
async reload(config: WebsocketClientConfig) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,17 @@ import { ActionMap } from '@/onebot/action';
|
|||||||
export type OB11EmitEventContent = OB11BaseEvent | OB11Message;
|
export type OB11EmitEventContent = OB11BaseEvent | OB11Message;
|
||||||
|
|
||||||
export interface IOB11NetworkAdapter {
|
export interface IOB11NetworkAdapter {
|
||||||
actions?: ActionMap;
|
actions: ActionMap;
|
||||||
name: string;
|
name: string;
|
||||||
|
isEnable: boolean;
|
||||||
|
|
||||||
onEvent<T extends OB11EmitEventContent>(event: T): void;
|
onEvent<T extends OB11EmitEventContent>(event: T): void;
|
||||||
|
|
||||||
open(): void | Promise<void>;
|
open(): void | Promise<void>;
|
||||||
|
|
||||||
close(): void | Promise<void>;
|
close(): void | Promise<void>;
|
||||||
|
|
||||||
|
reload(config: any): void | Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OB11NetworkManager {
|
export class OB11NetworkManager {
|
||||||
@ -34,7 +37,7 @@ export class OB11NetworkManager {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
async emitEventByNames(map:Map<string,OB11EmitEventContent>){
|
async emitEventByNames(map: Map<string, OB11EmitEventContent>) {
|
||||||
return Promise.all(Array.from(map.entries()).map(([name, event]) => {
|
return Promise.all(Array.from(map.entries()).map(([name, event]) => {
|
||||||
const adapter = this.adapters.get(name);
|
const adapter = this.adapters.get(name);
|
||||||
if (adapter) {
|
if (adapter) {
|
||||||
@ -71,6 +74,16 @@ export class OB11NetworkManager {
|
|||||||
await Promise.all(Array.from(this.adapters.values()).map(adapter => adapter.close()));
|
await Promise.all(Array.from(this.adapters.values()).map(adapter => adapter.close()));
|
||||||
this.adapters.clear();
|
this.adapters.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async readloadAdapter<T>(name: string, config: T) {
|
||||||
|
const adapter = this.adapters.get(name);
|
||||||
|
if (adapter) {
|
||||||
|
await adapter.reload(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async readloadSomeAdapters<T>(configMap: Map<string, T>) {
|
||||||
|
await Promise.all(Array.from(configMap.entries()).map(([name, config]) => this.readloadAdapter(name, config)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from './active-http';
|
export * from './active-http';
|
||||||
|
@ -5,19 +5,21 @@ import { NapCatCore } from '@/core';
|
|||||||
import { OB11Response } from '../action/OB11Response';
|
import { OB11Response } from '../action/OB11Response';
|
||||||
import { ActionMap } from '@/onebot/action';
|
import { ActionMap } from '@/onebot/action';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
|
import { HttpServerConfig } from '../config/config';
|
||||||
|
|
||||||
export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
||||||
private app: Express | undefined;
|
private app: Express | undefined;
|
||||||
private server: http.Server | undefined;
|
private server: http.Server | undefined;
|
||||||
private isOpen: boolean = false;
|
isEnable: boolean = false;
|
||||||
|
config: HttpServerConfig;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public name: string,
|
public name: string,
|
||||||
public port: number,
|
config: HttpServerConfig,
|
||||||
public token: string,
|
|
||||||
public core: NapCatCore,
|
public core: NapCatCore,
|
||||||
public actions: ActionMap,
|
public actions: ActionMap,
|
||||||
) {
|
) {
|
||||||
|
this.config = structuredClone(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
onEvent() {
|
onEvent() {
|
||||||
@ -26,13 +28,13 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
|||||||
|
|
||||||
open() {
|
open() {
|
||||||
try {
|
try {
|
||||||
if (this.isOpen) {
|
if (this.isEnable) {
|
||||||
this.core.context.logger.logError('Cannot open a closed HTTP server');
|
this.core.context.logger.logError('Cannot open a closed HTTP server');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.isOpen) {
|
if (!this.isEnable) {
|
||||||
this.initializeServer();
|
this.initializeServer();
|
||||||
this.isOpen = true;
|
this.isEnable = true;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.core.context.logger.logError(`[OneBot] [HTTP Server Adapter] Boot Error: ${e}`);
|
this.core.context.logger.logError(`[OneBot] [HTTP Server Adapter] Boot Error: ${e}`);
|
||||||
@ -41,7 +43,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
this.isOpen = false;
|
this.isEnable = false;
|
||||||
this.server?.close();
|
this.server?.close();
|
||||||
this.app = undefined;
|
this.app = undefined;
|
||||||
}
|
}
|
||||||
@ -64,12 +66,12 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.app.use((req, res, next) => this.authorize(this.token, req, res, next));
|
this.app.use((req, res, next) => this.authorize(this.config.token, req, res, next));
|
||||||
this.app.use(async (req, res, _) => {
|
this.app.use(async (req, res, _) => {
|
||||||
await this.handleRequest(req, res);
|
await this.handleRequest(req, res);
|
||||||
});
|
});
|
||||||
this.server.listen(this.port, () => {
|
this.server.listen(this.config.port, () => {
|
||||||
this.core.context.logger.log(`[OneBot] [HTTP Server Adapter] Start On Port ${this.port}`);
|
this.core.context.logger.log(`[OneBot] [HTTP Server Adapter] Start On Port ${this.config.port}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +88,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async handleRequest(req: Request, res: Response) {
|
private async handleRequest(req: Request, res: Response) {
|
||||||
if (!this.isOpen) {
|
if (!this.isEnable) {
|
||||||
this.core.context.logger.log(`[OneBot] [HTTP Server Adapter] Server is closed`);
|
this.core.context.logger.log(`[OneBot] [HTTP Server Adapter] Server is closed`);
|
||||||
return res.json(OB11Response.error('Server is closed', 200));
|
return res.json(OB11Response.error('Server is closed', 200));
|
||||||
}
|
}
|
||||||
@ -102,7 +104,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
|||||||
const action = this.actions.get(actionName);
|
const action = this.actions.get(actionName);
|
||||||
if (action) {
|
if (action) {
|
||||||
try {
|
try {
|
||||||
const result = await action.handle(payload,this.name);
|
const result = await action.handle(payload, this.name);
|
||||||
return res.json(result);
|
return res.json(result);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return res.json(OB11Response.error(error?.stack?.toString() || error?.message || 'Error Handle', 200));
|
return res.json(OB11Response.error(error?.stack?.toString() || error?.message || 'Error Handle', 200));
|
||||||
@ -111,4 +113,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
|||||||
return res.json(OB11Response.error('不支持的api ' + actionName, 200));
|
return res.json(OB11Response.error('不支持的api ' + actionName, 200));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async reload(config: HttpServerConfig) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,47 +10,44 @@ import { OB11HeartbeatEvent } from '../event/meta/OB11HeartbeatEvent';
|
|||||||
import { IncomingMessage } from 'http';
|
import { IncomingMessage } from 'http';
|
||||||
import { ActionMap } from '@/onebot/action';
|
import { ActionMap } from '@/onebot/action';
|
||||||
import { LifeCycleSubType, OB11LifeCycleEvent } from '../event/meta/OB11LifeCycleEvent';
|
import { LifeCycleSubType, OB11LifeCycleEvent } from '../event/meta/OB11LifeCycleEvent';
|
||||||
|
import { WebsocketServerConfig } from '../config/config';
|
||||||
|
|
||||||
export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||||
wsServer: WebSocketServer;
|
wsServer: WebSocketServer;
|
||||||
wsClients: WebSocket[] = [];
|
wsClients: WebSocket[] = [];
|
||||||
wsClientsMutex = new Mutex();
|
wsClientsMutex = new Mutex();
|
||||||
isOpen: boolean = false;
|
isEnable: boolean = false;
|
||||||
hasBeenClosed: boolean = false;
|
hasBeenClosed: boolean = false;
|
||||||
heartbeatInterval: number = 0;
|
heartbeatInterval: number = 0;
|
||||||
core: NapCatCore;
|
|
||||||
logger: LogWrapper;
|
logger: LogWrapper;
|
||||||
|
config: WebsocketServerConfig;
|
||||||
private heartbeatIntervalId: NodeJS.Timeout | null = null;
|
private heartbeatIntervalId: NodeJS.Timeout | null = null;
|
||||||
wsClientWithEvent: WebSocket[] = [];
|
wsClientWithEvent: WebSocket[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public name: string,
|
public name: string,
|
||||||
ip: string,
|
config: WebsocketServerConfig,
|
||||||
port: number,
|
public core: NapCatCore,
|
||||||
heartbeatInterval: number,
|
|
||||||
token: string,
|
|
||||||
core: NapCatCore,
|
|
||||||
public actions: ActionMap,
|
public actions: ActionMap,
|
||||||
) {
|
) {
|
||||||
this.core = core;
|
this.config = structuredClone(config);
|
||||||
this.logger = core.context.logger;
|
this.logger = core.context.logger;
|
||||||
if (ip === '0.0.0.0') {
|
if (this.config.host === '0.0.0.0') {
|
||||||
//兼容配置同时处理0.0.0.0逻辑
|
//兼容配置同时处理0.0.0.0逻辑
|
||||||
ip = '';
|
this.config.host = '';
|
||||||
}
|
}
|
||||||
this.heartbeatInterval = heartbeatInterval;
|
|
||||||
this.wsServer = new WebSocketServer({
|
this.wsServer = new WebSocketServer({
|
||||||
port: port,
|
port: this.config.port,
|
||||||
host: ip,
|
host: this.config.host,
|
||||||
maxPayload: 1024 * 1024 * 1024,
|
maxPayload: 1024 * 1024 * 1024,
|
||||||
});
|
});
|
||||||
this.wsServer.on('connection', async (wsClient, wsReq) => {
|
this.wsServer.on('connection', async (wsClient, wsReq) => {
|
||||||
if (!this.isOpen) {
|
if (!this.isEnable) {
|
||||||
wsClient.close();
|
wsClient.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//鉴权
|
//鉴权
|
||||||
this.authorize(token, wsClient, wsReq);
|
this.authorize(this.config.token, wsClient, wsReq);
|
||||||
const paramUrl = wsReq.url?.indexOf('?') !== -1 ? wsReq.url?.substring(0, wsReq.url?.indexOf('?')) : wsReq.url;
|
const paramUrl = wsReq.url?.indexOf('?') !== -1 ? wsReq.url?.substring(0, wsReq.url?.indexOf('?')) : wsReq.url;
|
||||||
const isApiConnect = paramUrl === '/api' || paramUrl === '/api/';
|
const isApiConnect = paramUrl === '/api' || paramUrl === '/api/';
|
||||||
if (!isApiConnect) {
|
if (!isApiConnect) {
|
||||||
@ -106,7 +103,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open() {
|
open() {
|
||||||
if (this.isOpen) {
|
if (this.isEnable) {
|
||||||
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Server] Cannot open a opened WebSocket server');
|
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Server] Cannot open a opened WebSocket server');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -117,7 +114,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
const addressInfo = this.wsServer.address();
|
const addressInfo = this.wsServer.address();
|
||||||
this.logger.log('[OneBot] [WebSocket Server] Server Started', typeof (addressInfo) === 'string' ? addressInfo : addressInfo?.address + ':' + addressInfo?.port);
|
this.logger.log('[OneBot] [WebSocket Server] Server Started', typeof (addressInfo) === 'string' ? addressInfo : addressInfo?.address + ':' + addressInfo?.port);
|
||||||
|
|
||||||
this.isOpen = true;
|
this.isEnable = true;
|
||||||
if (this.heartbeatInterval > 0) {
|
if (this.heartbeatInterval > 0) {
|
||||||
this.registerHeartBeat();
|
this.registerHeartBeat();
|
||||||
}
|
}
|
||||||
@ -125,7 +122,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
this.isOpen = false;
|
this.isEnable = false;
|
||||||
this.wsServer.close((err) => {
|
this.wsServer.close((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Server] Error closing server:', err.message);
|
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Server] Error closing server:', err.message);
|
||||||
@ -198,5 +195,8 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
||||||
this.checkStateAndReply<any>({ ...retdata }, wsClient);
|
this.checkStateAndReply<any>({ ...retdata }, wsClient);
|
||||||
}
|
}
|
||||||
|
async reload(config: WebsocketServerConfig) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user