/// /// /// /// /// /// import { EventEmitter } from "events"; import { IncomingMessage, Server as HTTPServer } from "http"; import { RequestOptions, Server as HTTPSServer, ServerOptions } from "https"; import { AddressInfo, Socket } from "net"; import { UrlObject } from "url"; /** 表示一个 WebSocket 连接 */ export declare class WebSocket extends EventEmitter { /** 获取关联的 TCP/IP 协议套接字 */ socket: Socket; /** 获取当前使用的子协议 */ protocol?: string; /** 获取当前使用的 WebSocket 扩展 */ readonly extension?: WebSocketExtension; /** 获取当前 WebSocket 的状态 */ readyState: WebSocketState; /** * 初始化新的 WebSocket 客户端 * @param url 要连接的服务端地址 * @param protocols 所有可用的子协议 * @param options 附加选项 */ constructor(url: string | UrlObject | URL, protocols?: string | readonly string[], options?: WebSocketOptions); /** * 初始化新的 WebSocket 服务端 * @param socket 已连接的 TCP/IP 协议套接字 * @param protocol 当前使用的子协议 * @param options 附加选项 */ constructor(socket: Socket, protocol?: string, options?: Pick); /** * 初始化指定的 TCP/IP 协议套接字 * @param socket 要关联的 TCP/IP 协议套接字 * @param protocol 子协议 */ private init; /** 正在挂起的请求对象 */ private _request?; /** * 连接到指定的 WebSocket 服务器 * @param url 要连接的服务端地址 * @param protocols 所有可用的子协议 * @param options 附加选项 */ private open; /** * 当连接错误后执行 * @param error 处理打开错误 */ protected onConnectError(error: Error): void; /** 使当前进程等待当前连接停止后退出 */ ref(): this; /** 允许当前进程不等待当前连接停止直接退出 */ unref(): this; /** 判断发送数据前是否添加掩码以避免缓存服务器攻击 */ readonly mask: boolean; /** * 向远程发送一段数据 * @param data 要发送的数据 * @param callback 发送成功后的回调函数 */ send(data: string | Buffer | ArrayBuffer | SharedArrayBuffer | Uint8Array, callback?: (error?: Error) => void): void; /** * 向远程发送一个“乒”消息 * @param callback 发送成功后的回调函数 */ ping(callback?: (error?: Error) => void): void; /** * 底层发送一个 WebSocket 帧 * @param data 要发送的数据 * @param opcode 操作码 * @param final 当前帧是否是最后一帧 * @param rsv 扩展码 * @param mask 是否添加掩码以避免缓存服务器攻击 * @param dataImmutable 是否禁止函数修改 *data* * @param callback 发送完成后的回调函数 */ sendPayload(data: string | Buffer | ArrayBuffer | SharedArrayBuffer | Uint8Array, opcode: WebSocketOpcode, final?: boolean, rsv?: WebSocketExtensionRSV, mask?: boolean, dataImmutable?: boolean, callback?: (error?: Error) => void): void; /** 获取已缓存但未发送的字节数 */ get bufferedAmount(): number; /** 所有已接收但未解析的二进制数据 */ private readonly _receivedBuffers; /** 已接收但未解析的字节长度 */ private _receivedLength; /** 已接收的第一个二进制数据中已解析的字节数 */ private _receivedOffset; /** 已接收的单个数据包的解析状态 */ private _receivedPayloadParseState; /** 已接收的单个数据包是否已结束 */ private _receivedPayloadFinal; /** 已接收的单个数据包是否已添加掩码 */ private _receivedPayloadMask?; /** 已接收的单个数据包的长度 */ private _receivedPayloadLength; /** 已接收的单个数据包的掩码 */ private _receivedPayloadMaskKey?; /** 已接收的数据块的扩展码 */ private _receivedPayloadRSV?; /** 已接收的数据块的操作码 */ private _receivedPayloadOpcode?; /** 已接收的数据块的所有二进制数据 */ private readonly _receivedChunks; /** 已接收的数据块的总字节长度 */ private _receivedChunkLength; /** 获取允许的每个数据块的最大字节长度 */ maxBufferSize: number; /** * 处理 TCP/IP 套接字接收数据事件 * @param data 接收的数据 */ protected handleSocketData: (data: Buffer) => void; /** 从已接收的缓存中读取一个字节 */ private _readReceivedByte; /** * 从缓存中读取指定数目的字节 * @param count 要读取的字节数 * @param outputBuffers 接收已读取的所有二进制数据的数组 */ private _readReceivedBytes; /** * 当数据解析错误后执行 * @param code 错误的状态码 * @param message 错误的信息 */ protected onParseError(code: number, message: string): void; /** * 当数据解析完成后执行 * @param buffers 接收到的所有数据 * @param length 接收到的所有数据字节长度 * @param opcode 操作码 * @param rsv 扩展码 */ protected onReceive(buffers: Buffer[], length: number, opcode: WebSocketOpcode, rsv: WebSocketExtensionRSV): void; /** * 当接收到数据后执行 * @param data 接收的数据 */ protected onMessage(data: string | Buffer): void; /** * 当接收到“乒”请求后执行 * @param data 请求的附加数据 */ protected onPing(data: Buffer): void; /** * 当接收到“乓”响应后执行 * @param data 请求的附加数据 */ protected onPong(data: Buffer): void; /** * 当接收到关闭请求后执行 * @param data 请求的附加数据 * @param code 远程发送的状态码 * @param reason 远程关闭的原因 */ protected onClose(data: Buffer, code?: number, reason?: string): void; /** 退出的状态码 */ private _closeCode?; /** 退出的原因 */ private _closeReason?; /** 等待强制关闭的计时器 */ private _destroyTimer?; /** * 发送一个关闭连接帧并关闭连接 * @param code 关闭的状态码 * @param reason 关闭的原因 * @param timeout 等待服务器响应的超时毫秒数,如果为 0 则不设置超时 */ close(code?: number, reason?: string, timeout?: number): void; /** * 强制关闭连接 * @param error 关联的错误对象 */ destroy(error?: Error): void; /** 释放所有资源 */ private uninit; /** 处理连接关闭事件 */ protected handleSocketClose: () => void; /** 处理连接错误事件 */ protected handleSocketError: (error: Error) => void; } /** 表示一个 WebSocket 连接的附加选项 */ export interface WebSocketOptions extends Omit { /** WebSocket 扩展 */ extension?: WebSocketExtension; /** * 允许远程发送的每个数据块的最大字节数 * @default 100 * 1024 * 1024 */ maxBufferSize?: number; /** * 响应服务端的 3XX 重定向的最大次数,如果为 0 则不重定向 * @default 10 */ maxRedirects?: number; } /** 表示一个 WebSocket 扩展 */ export interface WebSocketExtension { /** * 处理客户端提交的扩展头并返回支持的扩展头,如果都不支持则返回 `null` * @param header 客户端请求的扩展头 * @returns 返回传递给客户端的扩展头 */ accept(header: string): string | null; /** * 应用到 WebSocket 对象以实现扩展功能 * @param webSocket 要修改的 WebSocket 对象 */ apply(webSocket: WebSocket): void; } /** 表示 WebSocket 的扩展标记位 */ export declare const enum WebSocketExtensionRSV { /** 扩展字段 1 */ rsv1 = 64, /** 扩展字段 2 */ rsv2 = 32, /** 扩展字段 3 */ rsv3 = 16 } /** 表示 WebSocket 的连接状态 */ export declare const enum WebSocketState { /** 正在连接 */ connecting = 0, /** 已连接 */ open = 1, /** 正在关闭 */ closing = 2, /** 已关闭 */ closed = 3 } /** 表示 WebSocket 的操作码 */ export declare const enum WebSocketOpcode { /** 继续发送帧 */ continueFrame = 0, /** 文本(UTF-8 编码)帧 */ textFrame = 1, /** 二进制数据帧 */ binaryFrame = 2, /** 关闭连接 */ connectionCloseFrame = 8, /** “乒”帧 */ pingFrame = 9, /** “乓”帧 */ pongFrame = 10 } /** 表示一个 WebSocket 服务器 */ export declare class WebSocketServer extends EventEmitter { /** 获取关联的 HTTP 服务器 */ readonly server: HTTPServer | HTTPSServer; /** 判断当前服务器对象是否关联了已在外部创建的服务器对象 */ readonly existingServer: boolean; /** * 初始化新的 WebSocket 服务器 * @param server 关联的 HTTP 服务器或服务器地址(如 `ws://0.0.0.0/chat`) * @param options 附加选项 */ constructor(server: HTTPServer | HTTPSServer | string | UrlObject | URL, options?: WebSocketServerOptions); /** 获取当前服务器正在监听的地址,如果服务未启动则返回 `null` */ address(): AddressInfo; /** 判断当前服务器是否使用了加密传输协议(HTTPS) */ get isSecure(): boolean; /** 获取当前服务器的根地址,如果服务器未在监听则返回 `undefined` */ get url(): string; /** 获取配置的服务器主机地址 */ readonly hostname?: string; /** 获取配置的服务器端口 */ readonly port?: number; /** 获取允许的最大连接数 */ readonly backlog?: number; /** * 启动服务器 * @returns 如果服务器已成功启动,返回 `true`,如果当前实例关联了外部服务器,返回 `false` */ start(): Promise; /** * 处理服务器开始监听事件 */ protected handleListening: () => void; /** * 处理服务器错误事件 * @param error 发生的错误对象 */ protected handleError: (error: Error) => void; /** 获取所有已打开的连接 */ readonly connections: Set; /** 获取允许客户端发送的每个数据块的最大字节数 */ readonly maxBufferSize: number; /** 获取监听的服务器路径 */ readonly path?: string; /** 获取所有扩展协议 */ readonly extension?: WebSocketExtension; /** * 当被子类重写后负责验证是否允许指定的客户端连接 * @param request 当前的请求对象 * @param socket 当前的 TCP/IP 套接字对象 * @param server 当前的 WebSocket 服务器 */ protected verify?: (request: IncomingMessage, socket: Socket, server: WebSocketServer) => boolean | Promise; /** * 处理 HTTP 协议升级事件 * @param request 当前的请求对象 * @param socket 当前的 TCP/IP 套接字对象 * @param head 请求头的原始流 */ handleUpgrade: (request: IncomingMessage, socket: Socket, head: Buffer) => Promise; /** * 当有新的客户端连接时执行 * @param ws 用于和客户端通信的 WebSocket 对象 */ protected onConnection(ws: WebSocket): void; /** * 当被子类重写后负责停止升级操作 * @param socket 当前的 TCP/IP 套接字对象 * @param code 响应的 HTTP 错误码 */ protected abortUpgrade(socket: Socket, code: number): void; /** * 当被子类重写后负责选择合适的子协议 * @param protocols 所有可用的子协议 */ protected selectProtocol(protocols: string[]): string; /** * 向所有客户端发送数据 * @param data 要发送的数据 */ send(data: string | Buffer): void; /** * 关闭当前服务器 * @returns 如果服务器已成功关闭,返回 `true`,如果当前实例关联了外部服务器,返回 `false` */ close(): Promise; /** * 使当前进程等待当前服务器停止后退出 */ ref(): this; /** * 允许当前进程不等待当前服务器停止直接退出 */ unref(): this; } /** 表示 WebSocket 服务器的附加选项 */ export interface WebSocketServerOptions extends Pick, ServerOptions { /** * 服务器的路径 * @default "" */ path?: string; /** 允许的最大连接数 */ backlog?: number; /** * 验证是否允许指定的客户端连接 * @param request 当前的请求对象 * @param socket 当前的 TCP/IP 套接字对象 * @param server 当前的 WebSocket 服务器 */ verify?: (request: IncomingMessage, socket: Socket, server: WebSocketServer) => boolean | Promise; /** * 选择合适的子协议 * @param protocols 所有可用的子协议 */ selectProtocol?: (protocols: string[]) => string; }