diff --git a/packages/napcat-onebot/network/http-server.ts b/packages/napcat-onebot/network/http-server.ts index a2b19260..e1b4c9ea 100644 --- a/packages/napcat-onebot/network/http-server.ts +++ b/packages/napcat-onebot/network/http-server.ts @@ -13,14 +13,12 @@ import { URL } from 'url'; import { ActionName } from '@/napcat-onebot/action/router'; import { OB11HeartbeatEvent } from '@/napcat-onebot/event/meta/OB11HeartbeatEvent'; import { OB11LifeCycleEvent, LifeCycleSubType } from '@/napcat-onebot/event/meta/OB11LifeCycleEvent'; -import { Mutex } from 'async-mutex'; export class OB11HttpServerAdapter extends IOB11NetworkAdapter { private app: Express | undefined; private server: http.Server | undefined; private wsServer?: WebSocketServer; private wsClients: WebSocket[] = []; - private wsClientsMutex = new Mutex(); private heartbeatIntervalId: NodeJS.Timeout | null = null; private wsClientWithEvent: WebSocket[] = []; @@ -30,19 +28,17 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter override async onEvent (event: T) { // http server is passive, no need to emit event - this.wsClientsMutex.runExclusive(async () => { - const promises = this.wsClientWithEvent.map((wsClient) => { - return new Promise((resolve, reject) => { - if (wsClient.readyState === WebSocket.OPEN) { - wsClient.send(JSON.stringify(event)); - resolve(); - } else { - reject(new Error('WebSocket is not open')); - } - }); + const promises = this.wsClientWithEvent.map((wsClient) => { + return new Promise((resolve, reject) => { + if (wsClient.readyState === WebSocket.OPEN) { + wsClient.send(JSON.stringify(event)); + resolve(); + } else { + reject(new Error('WebSocket is not open')); + } }); - await Promise.allSettled(promises); }); + await Promise.allSettled(promises); } open () { @@ -65,13 +61,9 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter this.server?.close(); this.app = undefined; this.stopHeartbeat(); - await this.wsClientsMutex.runExclusive(async () => { - this.wsClients.forEach((wsClient) => { - wsClient.close(); - }); - this.wsClients = []; - this.wsClientWithEvent = []; - }); + this.wsClients.forEach((wsClient) => wsClient.close()); + this.wsClients = []; + this.wsClientWithEvent = []; this.wsServer?.close(); } @@ -153,36 +145,29 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter wsClient.on('message', (message) => { this.handleWSMessage(wsClient, message).then().catch(e => this.logger.logError(e)); }); - wsClient.on('ping', () => { - wsClient.pong(); - }); wsClient.on('pong', () => { // this.logger.logDebug('[OneBot] [HTTP WebSocket] Pong received'); }); wsClient.once('close', () => { - this.wsClientsMutex.runExclusive(async () => { - const NormolIndex = this.wsClients.indexOf(wsClient); - if (NormolIndex !== -1) { - this.wsClients.splice(NormolIndex, 1); - } - const EventIndex = this.wsClientWithEvent.indexOf(wsClient); - if (EventIndex !== -1) { - this.wsClientWithEvent.splice(EventIndex, 1); - } - if (this.wsClientWithEvent.length === 0) { - this.stopHeartbeat(); - } - }); - }); - await this.wsClientsMutex.runExclusive(async () => { - if (!isApiConnect) { - this.wsClientWithEvent.push(wsClient); + const NormolIndex = this.wsClients.indexOf(wsClient); + if (NormolIndex !== -1) { + this.wsClients.splice(NormolIndex, 1); } - this.wsClients.push(wsClient); - if (this.wsClientWithEvent.length > 0) { - this.startHeartbeat(); + const EventIndex = this.wsClientWithEvent.indexOf(wsClient); + if (EventIndex !== -1) { + this.wsClientWithEvent.splice(EventIndex, 1); + } + if (this.wsClientWithEvent.length === 0) { + this.stopHeartbeat(); } }); + if (!isApiConnect) { + this.wsClientWithEvent.push(wsClient); + } + this.wsClients.push(wsClient); + if (this.wsClientWithEvent.length > 0) { + this.startHeartbeat(); + } }).on('error', (err) => this.logger.log('[OneBot] [HTTP WebSocket] Server Error:', err.message)); } @@ -197,12 +182,10 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter private startHeartbeat () { if (this.heartbeatIntervalId) return; this.heartbeatIntervalId = setInterval(() => { - this.wsClientsMutex.runExclusive(async () => { - this.wsClientWithEvent.forEach((wsClient) => { - if (wsClient.readyState === WebSocket.OPEN) { - wsClient.send(JSON.stringify(new OB11HeartbeatEvent(this.core, 30000, this.core.selfInfo.online ?? true, true))); - } - }); + this.wsClientWithEvent.forEach((wsClient) => { + if (wsClient.readyState === WebSocket.OPEN) { + wsClient.send(JSON.stringify(new OB11HeartbeatEvent(this.core, 30000, this.core.selfInfo.online ?? true, true))); + } }); }, 30000); } diff --git a/packages/napcat-onebot/network/websocket-client.ts b/packages/napcat-onebot/network/websocket-client.ts index 320e7f70..b19c477c 100644 --- a/packages/napcat-onebot/network/websocket-client.ts +++ b/packages/napcat-onebot/network/websocket-client.ts @@ -85,9 +85,6 @@ export class OB11WebSocketClientAdapter extends IOB11NetworkAdapter { - this.connection?.pong(); - }); this.connection.on('pong', () => { // this.logger.logDebug('[OneBot] [WebSocket Client] 收到pong'); }); diff --git a/packages/napcat-onebot/network/websocket-server.ts b/packages/napcat-onebot/network/websocket-server.ts index 4fdfad57..ca953b2f 100644 --- a/packages/napcat-onebot/network/websocket-server.ts +++ b/packages/napcat-onebot/network/websocket-server.ts @@ -1,7 +1,6 @@ import { OB11EmitEventContent, OB11NetworkReloadType } from './index'; import { URL } from 'url'; import { RawData, WebSocket, WebSocketServer } from 'ws'; -import { Mutex } from 'async-mutex'; import { OB11Response } from '@/napcat-onebot/action/OneBotAction'; import { ActionName } from '@/napcat-onebot/action/router'; import { NapCatCore } from 'napcat-core'; @@ -17,7 +16,6 @@ import json5 from 'json5'; export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter { wsServer?: WebSocketServer; wsClients: WebSocket[] = []; - wsClientsMutex = new Mutex(); private heartbeatIntervalId: NodeJS.Timeout | null = null; wsClientWithEvent: WebSocket[] = []; @@ -58,36 +56,29 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter { this.handleMessage(wsClient, message).then().catch(e => this.logger.logError(e)); }); - wsClient.on('ping', () => { - wsClient.pong(); - }); wsClient.on('pong', () => { // this.logger.logDebug('[OneBot] [WebSocket Server] Pong received'); }); wsClient.once('close', () => { - this.wsClientsMutex.runExclusive(async () => { - const NormolIndex = this.wsClients.indexOf(wsClient); - if (NormolIndex !== -1) { - this.wsClients.splice(NormolIndex, 1); - } - const EventIndex = this.wsClientWithEvent.indexOf(wsClient); - if (EventIndex !== -1) { - this.wsClientWithEvent.splice(EventIndex, 1); - } - if (this.wsClientWithEvent.length === 0) { - this.stopHeartbeat(); - } - }); - }); - await this.wsClientsMutex.runExclusive(async () => { - if (!isApiConnect) { - this.wsClientWithEvent.push(wsClient); + const NormolIndex = this.wsClients.indexOf(wsClient); + if (NormolIndex !== -1) { + this.wsClients.splice(NormolIndex, 1); } - this.wsClients.push(wsClient); - if (this.wsClientWithEvent.length > 0) { - this.startHeartbeat(); + const EventIndex = this.wsClientWithEvent.indexOf(wsClient); + if (EventIndex !== -1) { + this.wsClientWithEvent.splice(EventIndex, 1); + } + if (this.wsClientWithEvent.length === 0) { + this.stopHeartbeat(); } }); + if (!isApiConnect) { + this.wsClientWithEvent.push(wsClient); + } + this.wsClients.push(wsClient); + if (this.wsClientWithEvent.length > 0) { + this.startHeartbeat(); + } }).on('error', (err) => this.logger.log('[OneBot] [WebSocket Server] Server Error:', err.message)); } @@ -100,19 +91,17 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter (event: T) { - this.wsClientsMutex.runExclusive(async () => { - const promises = this.wsClientWithEvent.map((wsClient) => { - return new Promise((resolve, reject) => { - if (wsClient.readyState === WebSocket.OPEN) { - wsClient.send(JSON.stringify(event)); - resolve(); - } else { - reject(new Error('WebSocket is not open')); - } - }); + const promises = this.wsClientWithEvent.map((wsClient) => { + return new Promise((resolve, reject) => { + if (wsClient.readyState === WebSocket.OPEN) { + wsClient.send(JSON.stringify(event)); + resolve(); + } else { + reject(new Error('WebSocket is not open')); + } }); - await Promise.allSettled(promises); }); + await Promise.allSettled(promises); } open () { @@ -136,24 +125,18 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter { - this.wsClients.forEach((wsClient) => { - wsClient.close(); - }); - this.wsClients = []; - this.wsClientWithEvent = []; - }); + this.wsClients.forEach((wsClient) => wsClient.close()); + this.wsClients = []; + this.wsClientWithEvent = []; } private startHeartbeat () { if (this.heartbeatIntervalId || this.config.heartInterval <= 0) return; this.heartbeatIntervalId = setInterval(() => { - this.wsClientsMutex.runExclusive(async () => { - this.wsClientWithEvent.forEach((wsClient) => { - if (wsClient.readyState === WebSocket.OPEN) { - wsClient.send(JSON.stringify(new OB11HeartbeatEvent(this.core, this.config.heartInterval, this.core.selfInfo.online ?? true, true))); - } - }); + this.wsClientWithEvent.forEach((wsClient) => { + if (wsClient.readyState === WebSocket.OPEN) { + wsClient.send(JSON.stringify(new OB11HeartbeatEvent(this.core, this.config.heartInterval, this.core.selfInfo.online ?? true, true))); + } }); }, this.config.heartInterval); } diff --git a/packages/napcat-onebot/package.json b/packages/napcat-onebot/package.json index a3417a0b..4546bfb3 100644 --- a/packages/napcat-onebot/package.json +++ b/packages/napcat-onebot/package.json @@ -26,7 +26,6 @@ "express": "^5.0.0", "ws": "^8.18.3", "file-type": "^21.0.0", - "async-mutex": "^0.5.0", "napcat-protobuf": "workspace:*", "json5": "^2.2.3", "napcat-core": "workspace:*", diff --git a/packages/napcat-types/external-shims.d.ts b/packages/napcat-types/external-shims.d.ts index abb75cc8..c4774548 100644 --- a/packages/napcat-types/external-shims.d.ts +++ b/packages/napcat-types/external-shims.d.ts @@ -61,20 +61,6 @@ declare module 'yaml' { export const stringify: (...args: any[]) => any; } -declare module 'async-mutex' { - export class Mutex { - acquire (): Promise<() => void>; - runExclusive (callback: () => T | Promise): Promise; - } - export class Semaphore { - acquire (): Promise<[() => void, number]>; - runExclusive (callback: () => T | Promise): Promise; - release (): void; - } - const _async_mutex_default: { Mutex: typeof Mutex; Semaphore: typeof Semaphore; }; - export default _async_mutex_default; -} - declare module 'napcat-protobuf' { export class NapProtoMsg { constructor (schema: any); diff --git a/packages/napcat-types/scripts/post-build.mjs b/packages/napcat-types/scripts/post-build.mjs index 6bc789c5..47ce34d4 100644 --- a/packages/napcat-types/scripts/post-build.mjs +++ b/packages/napcat-types/scripts/post-build.mjs @@ -35,9 +35,6 @@ const EXTERNAL_TYPE_REPLACEMENTS = { 'ValidateFunction': 'any', // inversify 'Container': 'any', - // async-mutex - 'Mutex': 'any', - 'Semaphore': 'any', // napcat-protobuf 'NapProtoDecodeStructType': 'any', 'NapProtoEncodeStructType': 'any', @@ -90,15 +87,15 @@ function replaceExternalTypes (content) { // 使用类型上下文的模式匹配 const typeContextPatterns = [ // : Type - /:\s*(WebSocket|WebSocketServer|RawData|Ajv|AnySchema|ValidateFunction|Container|Mutex|Semaphore|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)(?=\s*[;,)\]\}|&]|$)/g, + /:\s*(WebSocket|WebSocketServer|RawData|Ajv|AnySchema|ValidateFunction|Container|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)(?=\s*[;,)\]\}|&]|$)/g, // - /<(WebSocket|WebSocketServer|RawData|Ajv|AnySchema|ValidateFunction|Container|Mutex|Semaphore|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)>/g, + /<(WebSocket|WebSocketServer|RawData|Ajv|AnySchema|ValidateFunction|Container|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)>/g, // Type[] - /(WebSocket|WebSocketServer|RawData|Ajv|AnySchema|ValidateFunction|Container|Mutex|Semaphore|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)\[\]/g, + /(WebSocket|WebSocketServer|RawData|Ajv|AnySchema|ValidateFunction|Container|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)\[\]/g, // extends Type - /extends\s+(WebSocket|WebSocketServer|RawData|Ajv|AnySchema|ValidateFunction|Container|Mutex|Semaphore|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)(?=\s*[{,])/g, + /extends\s+(WebSocket|WebSocketServer|RawData|Ajv|AnySchema|ValidateFunction|Container|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)(?=\s*[{,])/g, // implements Type - /implements\s+(WebSocket|WebSocketServer|RawData|Ajv|AnySchema|ValidateFunction|Container|Mutex|Semaphore|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)(?=\s*[{,])/g, + /implements\s+(WebSocket|WebSocketServer|RawData|Ajv|AnySchema|ValidateFunction|Container|NapProtoDecodeStructType|NapProtoEncodeStructType|Express|Request|Response|NextFunction)(?=\s*[{,])/g, ]; for (const pattern of typeContextPatterns) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 885a3776..886d9dad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -176,9 +176,6 @@ importers: ajv: specifier: ^8.13.0 version: 8.17.1 - async-mutex: - specifier: ^0.5.0 - version: 0.5.0 cors: specifier: ^2.8.5 version: 2.8.5 @@ -3563,9 +3560,6 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} - async-mutex@0.5.0: - resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} - async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} @@ -10443,10 +10437,6 @@ snapshots: async-function@1.0.0: {} - async-mutex@0.5.0: - dependencies: - tslib: 2.8.1 - async@3.2.6: {} asynckit@0.4.0: {}