mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
refactor: reloadNetwork
This commit is contained in:
parent
02c4a468cb
commit
e7d138448a
@ -122,6 +122,7 @@ export const mergeNetworkDefaultConfig = {
|
||||
websocketClients: websocketClientDefaultConfigs,
|
||||
} as const;
|
||||
|
||||
export type NetworkConfigAdapter = HttpServerConfig | HttpClientConfig | WebsocketServerConfig | WebsocketClientConfig;
|
||||
type NetworkConfigKeys = keyof typeof mergeNetworkDefaultConfig;
|
||||
|
||||
export function mergeOneBotConfigs(
|
||||
|
@ -16,9 +16,11 @@ import {
|
||||
} from '@/core';
|
||||
import { OB11ConfigLoader } from '@/onebot/config';
|
||||
import {
|
||||
IOB11NetworkAdapter,
|
||||
OB11ActiveHttpAdapter,
|
||||
OB11ActiveWebSocketAdapter,
|
||||
OB11NetworkManager,
|
||||
OB11NetworkReloadType,
|
||||
OB11PassiveHttpAdapter,
|
||||
OB11PassiveWebSocketAdapter,
|
||||
} from '@/onebot/network';
|
||||
@ -45,7 +47,7 @@ import { OB11GroupRecallNoticeEvent } from '@/onebot/event/notice/OB11GroupRecal
|
||||
import { LRUCache } from '@/common/lru-cache';
|
||||
import { NodeIKernelRecentContactListener } from '@/core/listeners/NodeIKernelRecentContactListener';
|
||||
import { BotOfflineEvent } from './event/notice/BotOfflineEvent';
|
||||
import { mergeOneBotConfigs, migrateOneBotConfigsV1, OneBotConfig } from './config/config';
|
||||
import { mergeOneBotConfigs, migrateOneBotConfigsV1, NetworkConfigAdapter, OneBotConfig } from './config/config';
|
||||
import { OB11Message } from './types';
|
||||
|
||||
//OneBot实现类
|
||||
@ -179,152 +181,56 @@ export class NapCatOneBot11Adapter {
|
||||
const newLog = await this.creatOneBotLog(now);
|
||||
this.context.logger.log(`[Notice] [OneBot11] 配置变更前:\n${prevLog}`);
|
||||
this.context.logger.log(`[Notice] [OneBot11] 配置变更后:\n${newLog}`);
|
||||
|
||||
const { added: addedHttpServers, removed: removedHttpServers } = this.findDifference(prev.network.httpServers, now.network.httpServers);
|
||||
const { added: addedHttpClients, removed: removedHttpClients } = this.findDifference(prev.network.httpClients, now.network.httpClients);
|
||||
const { added: addedWebSocketServers, removed: removedWebSocketServers } = this.findDifference(prev.network.websocketServers, now.network.websocketServers);
|
||||
const { added: addedWebSocketClients, removed: removedWebSocketClients } = this.findDifference(prev.network.websocketClients, now.network.websocketClients);
|
||||
|
||||
// 移除旧的 HTTP 服务器
|
||||
for (const server of removedHttpServers) {
|
||||
await this.networkManager.closeAdapterByPredicate((adapter) => adapter.name === server.name);
|
||||
await this.handleRemovedAdapters(removedHttpServers);
|
||||
await this.handleRemovedAdapters(removedHttpClients);
|
||||
await this.handleRemovedAdapters(removedWebSocketServers);
|
||||
await this.handleRemovedAdapters(removedWebSocketClients);
|
||||
|
||||
await this.handlerConfigChange(now.network.httpServers);
|
||||
await this.handlerConfigChange(now.network.httpClients);
|
||||
await this.handlerConfigChange(now.network.websocketServers);
|
||||
await this.handlerConfigChange(now.network.websocketClients);
|
||||
|
||||
await this.handleAddedAdapters(addedHttpServers, OB11PassiveHttpAdapter);
|
||||
await this.handleAddedAdapters(addedHttpClients, OB11ActiveHttpAdapter);
|
||||
await this.handleAddedAdapters(addedWebSocketServers, OB11PassiveWebSocketAdapter);
|
||||
await this.handleAddedAdapters(addedWebSocketClients, OB11ActiveWebSocketAdapter);
|
||||
}
|
||||
|
||||
// 移除旧的 HTTP 客户端
|
||||
for (const client of removedHttpClients) {
|
||||
await this.networkManager.closeAdapterByPredicate((adapter) => adapter.name === client.name);
|
||||
}
|
||||
private async handlerConfigChange(adapters: Array<NetworkConfigAdapter>) {
|
||||
for (const adapterConfig of adapters) {
|
||||
const existingAdapter = this.networkManager.findSomeAdapter(adapterConfig.name);
|
||||
if (existingAdapter) {
|
||||
let networkChange = await existingAdapter.reload(adapterConfig);
|
||||
if (networkChange === OB11NetworkReloadType.NetWorkClose) {
|
||||
this.networkManager.closeSomeAdapters([existingAdapter]);
|
||||
|
||||
// 移除旧的 WebSocket 服务器
|
||||
for (const server of removedWebSocketServers) {
|
||||
await this.networkManager.closeAdapterByPredicate((adapter) => adapter.name === server.name);
|
||||
}
|
||||
|
||||
// 移除旧的 WebSocket 客户端
|
||||
for (const client of removedWebSocketClients) {
|
||||
await this.networkManager.closeAdapterByPredicate((adapter) => adapter.name === client.name);
|
||||
}
|
||||
|
||||
// 处理 enable 状态变化的 HTTP 服务器
|
||||
for (const server of now.network.httpServers) {
|
||||
const prevServer = prev.network.httpServers.find(s => s.name === server.name);
|
||||
if (prevServer && prevServer.enable !== server.enable) {
|
||||
if (server.enable) {
|
||||
let adapter = new OB11PassiveHttpAdapter(server.name, server, this.core, this.actions);
|
||||
adapter.open();
|
||||
this.networkManager.registerAdapter(
|
||||
adapter
|
||||
);
|
||||
} else {
|
||||
await this.networkManager.closeAdapterByPredicate((adapter) => adapter.name === server.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理 enable 状态变化的 HTTP 客户端
|
||||
for (const client of now.network.httpClients) {
|
||||
const prevClient = prev.network.httpClients.find(c => c.name === client.name);
|
||||
if (prevClient && prevClient.enable !== client.enable) {
|
||||
if (client.enable) {
|
||||
let adapter = new OB11ActiveHttpAdapter(client.name, client, this.core, this, this.actions);
|
||||
adapter.open();
|
||||
this.networkManager.registerAdapter(
|
||||
adapter
|
||||
);
|
||||
} else {
|
||||
await this.networkManager.closeAdapterByPredicate((adapter) => adapter.name === client.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理 enable 状态变化的 WebSocket 服务器
|
||||
for (const server of now.network.websocketServers) {
|
||||
const prevServer = prev.network.websocketServers.find(s => s.name === server.name);
|
||||
if (prevServer && prevServer.enable !== server.enable) {
|
||||
if (server.enable) {
|
||||
let adapter = new OB11PassiveWebSocketAdapter(
|
||||
server.name,
|
||||
server,
|
||||
this.core,
|
||||
this.actions
|
||||
);
|
||||
adapter.open();
|
||||
this.networkManager.registerAdapter(
|
||||
adapter
|
||||
);
|
||||
} else {
|
||||
await this.networkManager.closeAdapterByPredicate((adapter) => adapter.name === server.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理 enable 状态变化的 WebSocket 客户端
|
||||
for (const client of now.network.websocketClients) {
|
||||
const prevClient = prev.network.websocketClients.find(c => c.name === client.name);
|
||||
if (prevClient && prevClient.enable !== client.enable) {
|
||||
if (client.enable) {
|
||||
let adapter = new OB11ActiveWebSocketAdapter(
|
||||
client.name,
|
||||
client,
|
||||
this.core,
|
||||
this.actions
|
||||
)
|
||||
this.networkManager.registerAdapter(
|
||||
adapter
|
||||
);
|
||||
} else {
|
||||
await this.networkManager.closeAdapterByPredicate((adapter) => adapter.name === client.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 注册新的 HTTP 服务器
|
||||
for (const server of addedHttpServers) {
|
||||
if (server.enable) {
|
||||
let adapter = new OB11PassiveHttpAdapter(server.name, server, this.core, this.actions);
|
||||
adapter.open();
|
||||
this.networkManager.registerAdapter(adapter);
|
||||
private async handleRemovedAdapters(adapters: Array<{ name: string }>): Promise<void> {
|
||||
for (const adapter of adapters) {
|
||||
await this.networkManager.closeAdapterByPredicate((existingAdapter) => existingAdapter.name === adapter.name);
|
||||
}
|
||||
}
|
||||
|
||||
// 注册新的 HTTP 客户端
|
||||
for (const client of addedHttpClients) {
|
||||
|
||||
if (client.enable) {
|
||||
let adapter = new OB11ActiveHttpAdapter(client.name, client, this.core, this, this.actions);
|
||||
adapter.open();
|
||||
this.networkManager.registerAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
// 注册新的 WebSocket 服务器
|
||||
for (const server of addedWebSocketServers) {
|
||||
if (server.enable) {
|
||||
let adapter = new OB11PassiveWebSocketAdapter(
|
||||
server.name,
|
||||
server,
|
||||
this.core,
|
||||
this.actions
|
||||
);
|
||||
adapter.open();
|
||||
this.networkManager.registerAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
// 注册新的 WebSocket 客户端
|
||||
for (const client of addedWebSocketClients) {
|
||||
if (client.enable) {
|
||||
let adapter = new OB11ActiveWebSocketAdapter(
|
||||
client.name,
|
||||
client,
|
||||
this.core,
|
||||
this.actions
|
||||
)
|
||||
adapter.open();
|
||||
this.networkManager.registerAdapter(adapter);
|
||||
private async handleAddedAdapters<T extends new (...args: any[]) => IOB11NetworkAdapter>(addedAdapters: Array<NetworkConfigAdapter>, AdapterClass: T) {
|
||||
for (const adapter of addedAdapters) {
|
||||
if (adapter.enable) {
|
||||
const newAdapter = new AdapterClass(adapter.name, adapter, this.core, this.actions);
|
||||
await newAdapter.open();
|
||||
this.networkManager.registerAdapter(newAdapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private findDifference<T>(prev: T[], now: T[]): { added: T[]; removed: T[] } {
|
||||
const added = now.filter((item) => !prev.includes(item));
|
||||
const removed = prev.filter((item) => !now.includes(item));
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IOB11NetworkAdapter, OB11EmitEventContent } from '@/onebot/network/index';
|
||||
import { IOB11NetworkAdapter, OB11EmitEventContent, OB11NetworkReloadType } from '@/onebot/network/index';
|
||||
import { createHmac } from 'crypto';
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { QuickAction, QuickActionEvent } from '../types';
|
||||
@ -11,7 +11,7 @@ import { ActionMap } from '../action';
|
||||
export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter {
|
||||
logger: LogWrapper;
|
||||
isEnable: boolean = false;
|
||||
config: HttpClientConfig;
|
||||
public config: HttpClientConfig;
|
||||
constructor(
|
||||
public name: string,
|
||||
config: HttpClientConfig,
|
||||
@ -67,7 +67,20 @@ export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter {
|
||||
close() {
|
||||
this.isEnable = false;
|
||||
}
|
||||
async reload(config: HttpClientConfig){
|
||||
this.config = structuredClone(config);
|
||||
async reload(newconfig: HttpClientConfig) {
|
||||
const wasEnabled = this.isEnable;
|
||||
const oldUrl = this.config.url;
|
||||
this.config = newconfig;
|
||||
if (newconfig.enable && !wasEnabled) {
|
||||
this.open();
|
||||
return OB11NetworkReloadType.NetWorkOpen;
|
||||
} else if (!newconfig.enable && wasEnabled) {
|
||||
this.close();
|
||||
return OB11NetworkReloadType.NetWorkClose;
|
||||
}
|
||||
if (oldUrl !== newconfig.url) {
|
||||
return OB11NetworkReloadType.NetWorkReload;
|
||||
}
|
||||
return OB11NetworkReloadType.Normal;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IOB11NetworkAdapter, OB11EmitEventContent } from '@/onebot/network/index';
|
||||
import { IOB11NetworkAdapter, OB11EmitEventContent, OB11NetworkReloadType } from '@/onebot/network/index';
|
||||
import { WebSocket } from 'ws';
|
||||
import { OB11HeartbeatEvent } from '../event/meta/OB11HeartbeatEvent';
|
||||
import { NapCatCore } from '@/core';
|
||||
@ -14,7 +14,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||
logger: LogWrapper;
|
||||
private connection: WebSocket | null = null;
|
||||
private heartbeatRef: NodeJS.Timeout | null = null;
|
||||
config: WebsocketClientConfig;
|
||||
public config: WebsocketClientConfig;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@ -154,7 +154,43 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
||||
this.checkStateAndReply<any>({ ...retdata });
|
||||
}
|
||||
async reload(config: WebsocketClientConfig) {
|
||||
async reload(newConfig: WebsocketClientConfig) {
|
||||
const wasEnabled = this.isEnable;
|
||||
const oldUrl = this.config.url;
|
||||
const oldHeartInterval = this.config.heartInterval;
|
||||
this.config = newConfig;
|
||||
|
||||
if (newConfig.enable && !wasEnabled) {
|
||||
this.open();
|
||||
return OB11NetworkReloadType.NetWorkOpen;
|
||||
} else if (!newConfig.enable && wasEnabled) {
|
||||
this.close();
|
||||
return OB11NetworkReloadType.NetWorkClose;
|
||||
}
|
||||
|
||||
if (oldUrl !== newConfig.url) {
|
||||
this.close();
|
||||
if (newConfig.enable) {
|
||||
this.open();
|
||||
}
|
||||
return OB11NetworkReloadType.NetWorkReload;
|
||||
}
|
||||
|
||||
if (oldHeartInterval !== newConfig.heartInterval) {
|
||||
if (this.heartbeatRef) {
|
||||
clearInterval(this.heartbeatRef);
|
||||
this.heartbeatRef = null;
|
||||
}
|
||||
if (newConfig.heartInterval > 0 && this.isEnable) {
|
||||
this.heartbeatRef = setInterval(() => {
|
||||
if (this.connection && this.connection.readyState === WebSocket.OPEN) {
|
||||
this.connection.send(JSON.stringify(new OB11HeartbeatEvent(this.core, newConfig.heartInterval, this.core.selfInfo.online ?? true, true)));
|
||||
}
|
||||
}, newConfig.heartInterval);
|
||||
}
|
||||
return OB11NetworkReloadType.NetWorkReload;
|
||||
}
|
||||
|
||||
return OB11NetworkReloadType.Normal;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,21 @@
|
||||
import { OB11BaseEvent } from '@/onebot/event/OB11BaseEvent';
|
||||
import { OB11Message } from '@/onebot';
|
||||
import { ActionMap } from '@/onebot/action';
|
||||
import { NetworkConfigAdapter } from '../config/config';
|
||||
|
||||
export type OB11EmitEventContent = OB11BaseEvent | OB11Message;
|
||||
|
||||
export enum OB11NetworkReloadType {
|
||||
Normal = 0,
|
||||
ConfigChange = 1,
|
||||
NetWorkReload = 2,
|
||||
NetWorkClose = 3,
|
||||
NetWorkOpen = 4
|
||||
}
|
||||
export interface IOB11NetworkAdapter {
|
||||
actions: ActionMap;
|
||||
name: string;
|
||||
isEnable: boolean;
|
||||
config: NetworkConfigAdapter;
|
||||
|
||||
onEvent<T extends OB11EmitEventContent>(event: T): void;
|
||||
|
||||
@ -15,7 +23,7 @@ export interface IOB11NetworkAdapter {
|
||||
|
||||
close(): void | Promise<void>;
|
||||
|
||||
reload(config: any): void | Promise<void>;
|
||||
reload(config: any): OB11NetworkReloadType | Promise<OB11NetworkReloadType>;
|
||||
}
|
||||
|
||||
export class OB11NetworkManager {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IOB11NetworkAdapter } from './index';
|
||||
import { IOB11NetworkAdapter, OB11NetworkReloadType } from './index';
|
||||
import express, { Express, Request, Response } from 'express';
|
||||
import http from 'http';
|
||||
import { NapCatCore } from '@/core';
|
||||
@ -11,7 +11,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
||||
private app: Express | undefined;
|
||||
private server: http.Server | undefined;
|
||||
isEnable: boolean = false;
|
||||
config: HttpServerConfig;
|
||||
public config: HttpServerConfig;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@ -113,7 +113,28 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
||||
return res.json(OB11Response.error('不支持的api ' + actionName, 200));
|
||||
}
|
||||
}
|
||||
async reload(config: HttpServerConfig) {
|
||||
|
||||
async reload(newConfig: HttpServerConfig) {
|
||||
const wasEnabled = this.isEnable;
|
||||
const oldPort = this.config.port;
|
||||
this.config = newConfig;
|
||||
|
||||
if (newConfig.enable && !wasEnabled) {
|
||||
this.open();
|
||||
return OB11NetworkReloadType.NetWorkOpen;
|
||||
} else if (!newConfig.enable && wasEnabled) {
|
||||
this.close();
|
||||
return OB11NetworkReloadType.NetWorkClose;
|
||||
}
|
||||
|
||||
if (oldPort !== newConfig.port) {
|
||||
this.close();
|
||||
if (newConfig.enable) {
|
||||
this.open();
|
||||
}
|
||||
return OB11NetworkReloadType.NetWorkReload;
|
||||
}
|
||||
|
||||
return OB11NetworkReloadType.Normal;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IOB11NetworkAdapter, OB11EmitEventContent } from './index';
|
||||
import { IOB11NetworkAdapter, OB11EmitEventContent, OB11NetworkReloadType } from './index';
|
||||
import urlParse from 'url';
|
||||
import { WebSocket, WebSocketServer } from 'ws';
|
||||
import { Mutex } from 'async-mutex';
|
||||
@ -20,7 +20,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||
hasBeenClosed: boolean = false;
|
||||
heartbeatInterval: number = 0;
|
||||
logger: LogWrapper;
|
||||
config: WebsocketServerConfig;
|
||||
public config: WebsocketServerConfig;
|
||||
private heartbeatIntervalId: NodeJS.Timeout | null = null;
|
||||
wsClientWithEvent: WebSocket[] = [];
|
||||
|
||||
@ -195,8 +195,48 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
||||
this.checkStateAndReply<any>({ ...retdata }, wsClient);
|
||||
}
|
||||
async reload(config: WebsocketServerConfig) {
|
||||
|
||||
async reload(newConfig: WebsocketServerConfig) {
|
||||
const wasEnabled = this.isEnable;
|
||||
const oldPort = this.config.port;
|
||||
const oldHost = this.config.host;
|
||||
const oldHeartbeatInterval = this.heartbeatInterval;
|
||||
this.config = newConfig;
|
||||
|
||||
if (newConfig.enable && !wasEnabled) {
|
||||
this.open();
|
||||
return OB11NetworkReloadType.NetWorkOpen;
|
||||
} else if (!newConfig.enable && wasEnabled) {
|
||||
this.close();
|
||||
return OB11NetworkReloadType.NetWorkClose;
|
||||
}
|
||||
|
||||
if (oldPort !== newConfig.port || oldHost !== newConfig.host) {
|
||||
this.close();
|
||||
this.wsServer = new WebSocketServer({
|
||||
port: newConfig.port,
|
||||
host: newConfig.host === '0.0.0.0' ? '' : newConfig.host,
|
||||
maxPayload: 1024 * 1024 * 1024,
|
||||
});
|
||||
if (newConfig.enable) {
|
||||
this.open();
|
||||
}
|
||||
return OB11NetworkReloadType.NetWorkReload;
|
||||
}
|
||||
|
||||
if (oldHeartbeatInterval !== newConfig.heartInterval) {
|
||||
if (this.heartbeatIntervalId) {
|
||||
clearInterval(this.heartbeatIntervalId);
|
||||
this.heartbeatIntervalId = null;
|
||||
}
|
||||
this.heartbeatInterval = newConfig.heartInterval;
|
||||
if (newConfig.heartInterval > 0 && this.isEnable) {
|
||||
this.registerHeartBeat();
|
||||
}
|
||||
return OB11NetworkReloadType.NetWorkReload;
|
||||
}
|
||||
|
||||
return OB11NetworkReloadType.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user