/************************************************************************ * Copyright (c) 2023 sunking framework * Author : Shao * Mail : yi-shaoye@163.com * Date : 2021-10-28 * Use : ws网络模块 ************************************************************************/ import http, { IncomingMessage } from "http"; import https from "https"; import fs from 'fs'; import { BaseConnector } from '../base/BaseConnector'; import { WebSocket, WebSocketServer } from 'ws'; import myLogger from '@wingyi8/sk-logger'; const logger = myLogger.getLogger('sunking/ws/WsConnector'); import { WsSocket } from './WsSocket'; import { ServerStatus } from "../util/define"; // 计数器 let curId = 1; export class WsConnector extends BaseConnector { /** * server实例 */ private sockio: WebSocketServer = null; /** * 开启服务器 */ public start(): Promise { if (this.sockio) { throw new Error('Server already started'); } this._status = ServerStatus.Opening; return new Promise((resolve, reject) => { if (this.type == 'wss') { let server = https.createServer({ key: fs.readFileSync(this.key), cert: fs.readFileSync(this.cert), }).listen(this.port, () => { this._status = ServerStatus.Opened; resolve(); }); this.sockio = new WebSocketServer({ server, }); } else { this.sockio = new WebSocketServer({ port: this.port }, () => { this._status = ServerStatus.Opened; resolve(); }); } // 订阅服务器消息 this.sockio.on('connection', this.onClientConnect); this.sockio.on('error', e => { logger.error(`[ServerError] ${e.message}`); reject(e); }); this.sockio.on("close", () => { }); // 初始化缓存信息 this.onInitBuffer(); }) } /** * 客户端连接请求 * @param ws * @param httpReq * @returns */ private onClientConnect = (socket: WebSocket, httpReq: IncomingMessage) => { // 停止中 不再接受新的连接 if (this._status !== ServerStatus.Opened) { socket.close(1012); return; } // 客户端数量达到上限 if (this.ClientAry.size >= this.maxConnectionNum) { socket.close(1010, '连接达到上限'); return; } // 初始化客户端状态 let wsSocket = new WsSocket(curId++, this, socket, httpReq, this.debugLog); // 连接成功 wsSocket.on('connection', () => { this.emit('connection', wsSocket); }); // 断开连接 wsSocket.on('disconnect', () => { this.emit('disconnect', wsSocket); this.ClientAry.delete(wsSocket); }); } /** * 停止服务器 */ public stop(): void { // Closed Already if (!this.sockio) { throw new Error('Server has not been started') } if (this._status === ServerStatus.Closed) { throw new Error('Server is closed already'); } logger.info('Server stopped'); this._status = ServerStatus.Closed; this.sockio = undefined; } /** * 显示服务器信息 */ public show() { logger.info(`创建 ${this.type} 服务器 [${this.des}] ${this.type}://${this.host}:${this.port}`); } }