/*! * TSRPC v3.4.21 * ----------------------------------------- * Copyright (c) King Wang. * MIT License * https://github.com/k8w/tsrpc */ /// /// import { ApiReturn } from 'tsrpc-proto'; import { ApiService } from 'tsrpc-base-client'; import { ApiServiceDef } from 'tsrpc-proto'; import { BaseHttpClient } from 'tsrpc-base-client'; import { BaseHttpClientOptions } from 'tsrpc-base-client'; import { BaseServiceType } from 'tsrpc-proto'; import { BaseWsClient } from 'tsrpc-base-client'; import { BaseWsClientOptions } from 'tsrpc-base-client'; import { Counter } from 'tsrpc-base-client'; import { CustomTypeSchema } from 'tsbuffer-schema'; import { Flow } from 'tsrpc-base-client'; import http from 'http'; import * as http_2 from 'http'; import https from 'https'; import { Logger } from 'tsrpc-proto'; import { LogLevel } from 'tsrpc-proto'; import { MsgService } from 'tsrpc-base-client'; import { ParsedServerInput } from 'tsrpc-base-client'; import { ServiceMap } from 'tsrpc-base-client'; import { ServiceProto } from 'tsrpc-proto'; import { TSBuffer } from 'tsbuffer'; import { TsrpcError } from 'tsrpc-proto'; import { TsrpcErrorData } from 'tsrpc-proto'; import * as WebSocket_2 from 'ws'; /** * A call request by `client.callApi()` * @typeParam Req - Type of request * @typeParam Res - Type of response * @typeParam ServiceType - The same `ServiceType` to server, it is used for code auto hint. */ export declare abstract class ApiCall extends BaseCall { readonly type: "api"; /** * Which `ApiService` the request is calling for */ readonly service: ApiService; /** Only exists in long connection, it is used to associate request and response. * It is created by the client, and the server would return the same value in `ApiReturn`. */ readonly sn?: number; /** * Request data from the client, type of it is checked by the framework already. */ readonly req: Req; constructor(options: ApiCallOptions, logger?: PrefixLogger); protected _return?: ApiReturn; /** * Response Data that sent already. * `undefined` means no return data is sent yet. (Never `call.succ()` and `call.error()`) */ get return(): ApiReturn | undefined; protected _usedTime: number | undefined; /** Time from received req to send return data */ get usedTime(): number | undefined; /** * Send a successful `ApiReturn` with response data * @param res - Response data * @returns Promise resolved means the buffer is sent to kernel */ succ(res: Res): Promise; /** * Send a error `ApiReturn` with a `TsrpcError` * @returns Promise resolved means the buffer is sent to kernel */ error(message: string, info?: Partial): Promise; error(err: TsrpcError): Promise; protected _prepareReturn(ret: ApiReturn): Promise; protected _sendReturn(ret: ApiReturn): ReturnType>; static encodeApiReturn(tsbuffer: TSBuffer, service: ApiService, apiReturn: ApiReturn, type: "text", sn?: number): EncodeApiReturnOutput; static encodeApiReturn(tsbuffer: TSBuffer, service: ApiService, apiReturn: ApiReturn, type: "buffer", sn?: number): EncodeApiReturnOutput; static encodeApiReturn(tsbuffer: TSBuffer, service: ApiService, apiReturn: ApiReturn, type: "json", sn?: number): EncodeApiReturnOutput; static encodeApiReturn(tsbuffer: TSBuffer, service: ApiService, apiReturn: ApiReturn, type: "text" | "buffer" | "json", sn?: number): EncodeApiReturnOutput | EncodeApiReturnOutput | EncodeApiReturnOutput; } export declare class ApiCallHttp extends ApiCall { readonly conn: HttpConnection; constructor(options: ApiCallHttpOptions); protected _sendReturn(ret: ApiReturn): Promise<{ isSucc: true; } | { isSucc: false; errMsg: string; }>; } export declare interface ApiCallHttpOptions extends ApiCallOptions { conn: HttpConnection; } export declare interface ApiCallOptions extends BaseCallOptions { /** Which service the Call is belong to */ service: ApiService; /** Only exists in long connection, it is used to associate request and response. * It is created by the client, and the server would return the same value in `ApiReturn`. */ sn?: number; /** Request Data */ req: Req; } export declare class ApiCallWs extends ApiCall { readonly conn: WsConnection; constructor(options: ApiCallWsOptions); protected _prepareReturn(ret: ApiReturn): Promise; } export declare interface ApiCallWsOptions extends ApiCallOptions { conn: WsConnection; } export declare type ApiHandler = (call: Call) => void | Promise; export declare abstract class BaseCall { readonly conn: BaseConnection; readonly service: ApiService | MsgService; /** Time that server created the call */ readonly startTime: number; readonly logger: PrefixLogger; constructor(options: BaseCallOptions, logger: PrefixLogger); get server(): this["conn"]["server"]; } export declare interface BaseCallOptions { /** Connection */ conn: BaseConnection; /** Which service the call is belong to */ service: ApiService | MsgService; } export declare abstract class BaseConnection { /** It is long connection or short connection */ abstract readonly type: "LONG" | "SHORT"; protected abstract readonly ApiCallClass: { new (options: any): ApiCall; }; protected abstract readonly MsgCallClass: { new (options: any): MsgCall; }; /** Connection unique ID */ readonly id: string; /** Client IP address */ readonly ip: string; readonly server: BaseServer; readonly logger: PrefixLogger; dataType: BaseConnectionOptions["dataType"]; constructor(options: BaseConnectionOptions, logger: PrefixLogger); abstract get status(): ConnectionStatus; /** Close the connection */ abstract close(reason?: string): void; /** Send buffer (with pre-flow and post-flow) */ sendData(data: string | Uint8Array | object, call?: ApiCall): Promise<{ isSucc: true; } | { isSucc: false; errMsg: string; canceledByFlow?: string; }>; protected abstract doSendData(data: string | Uint8Array | object, call?: ApiCall): Promise<{ isSucc: true; } | { isSucc: false; errMsg: string; }>; makeCall(input: ParsedServerInput): ApiCall | MsgCall; /** * Send message to the client, only be available when it is long connection. * @param msgName * @param msg - Message body * @returns Promise resolved when the buffer is sent to kernel, it not represents the server received it. */ sendMsg(msgName: T, msg: ServiceType["msg"][T]): ReturnType; private _msgHandlers?; /** * Add a message handler, * duplicate handlers to the same `msgName` would be ignored. * @param msgName * @param handler */ listenMsg>(msgName: Msg, handler: MsgHandler): MsgHandler; /** * Remove a message handler */ unlistenMsg>(msgName: Msg, handler: Function): void; /** * Remove all handlers from a message */ unlistenMsgAll>(msgName: Msg): void; } export declare interface BaseConnectionOptions { /** Created by server, each Call has a unique id. */ id: string; /** Client IP address */ ip: string; server: BaseServer; dataType: "text" | "buffer" | "json"; } /** * Abstract base class for TSRPC Server. * Implement on a transportation protocol (like HTTP WebSocket) by extend it. * @typeParam ServiceType - `ServiceType` from generated `proto.ts` */ export declare abstract class BaseServer { /** * Start the server * @throws */ abstract start(): Promise; /** * Stop server immediately, not waiting for the requests ending. */ abstract stop(): Promise; protected _status: ServerStatus; get status(): ServerStatus; readonly proto: ServiceProto; readonly options: BaseServerOptions; readonly tsbuffer: TSBuffer; readonly serviceMap: ServiceMap; readonly logger: Logger; protected _connIdCounter: Counter; /** * Flow is a specific concept created by TSRPC family. * All pre-flow can interrupt latter behaviours. * All post-flow can NOT interrupt latter behaviours. */ readonly flows: { /** After the connection is created */ readonly postConnectFlow: Flow>; /** After the connection is disconnected */ readonly postDisconnectFlow: Flow<{ conn: BaseConnection; reason?: string | undefined; }>; /** * Before processing the received data, usually be used to encryption / decryption. * Return `null | undefined` would ignore the buffer. */ readonly preRecvDataFlow: Flow<{ conn: BaseConnection; data: string | Uint8Array | object; /** * @deprecated use `serviceId` instead */ serviceName?: string | undefined; /** * Parsed service id, you can get this by `this.serviceMap.apiName2Service[serviceName].id` */ serviceId?: number | undefined; }>; /** * Before send out data to network, usually be used to encryption / decryption. * Return `null | undefined` would not send the buffer. */ readonly preSendDataFlow: Flow<{ conn: BaseConnection; data: string | Uint8Array | object; call?: ApiCall | undefined; }>; /** * @deprecated Use `preRecvDataFlow` instead. */ readonly preRecvBufferFlow: Flow<{ conn: BaseConnection; buf: Uint8Array; }>; /** * @deprecated Use `preSendDataFlow` instead. */ readonly preSendBufferFlow: Flow<{ conn: BaseConnection; buf: Uint8Array; call?: ApiCall | undefined; }>; /** * Before a API request is send. * Return `null | undefined` would cancel the request. */ readonly preApiCallFlow: Flow>; /** * Before return the `ApiReturn` to the client. * It may be used to change the return value, or return `null | undefined` to abort the request. */ readonly preApiReturnFlow: Flow<{ call: ApiCall; return: ApiReturn; }>; /** * After the `ApiReturn` is send. * return `null | undefined` would NOT interrupt latter behaviours. */ readonly postApiReturnFlow: Flow<{ call: ApiCall; return: ApiReturn; }>; /** * After the api handler is executed. * return `null | undefined` would NOT interrupt latter behaviours. */ readonly postApiCallFlow: Flow>; /** * Before handle a `MsgCall` */ readonly preMsgCallFlow: Flow>; /** * After handlers of a `MsgCall` are executed. * return `null | undefined` would NOT interrupt latter behaviours. */ readonly postMsgCallFlow: Flow>; /** * Before send out a message. * return `null | undefined` would NOT interrupt latter behaviours. */ readonly preSendMsgFlow: Flow<{ conn: BaseConnection; service: MsgService; msg: any; }>; /** * After send out a message. * return `null | undefined` would NOT interrupt latter behaviours. */ readonly postSendMsgFlow: Flow<{ conn: BaseConnection; service: MsgService; msg: any; }>; }; private _apiHandlers; private _msgHandlers; private static _isUncaughtExceptionProcessed; /** * It makes the `uncaughtException` and `unhandledRejection` not lead to the server stopping. * @param logger * @returns */ static processUncaughtException(logger: Logger): void; constructor(proto: ServiceProto, options: BaseServerOptions); protected _setDefaultFlowOnError(): void; protected _pendingApiCallNum: number; /** * Process the buffer, after the `preRecvBufferFlow`. */ _onRecvData(conn: BaseConnection, data: string | Uint8Array | object, serviceId?: number): Promise; protected _handleApiCall(call: ApiCall): Promise; protected _onApiCall(call: ApiCall): Promise; protected _onMsgCall(call: MsgCall): Promise; /** * Associate a `ApiHandler` to a specific `apiName`. * So that when `ApiCall` is receiving, it can be handled correctly. * @param apiName * @param handler */ implementApi>(apiName: Api, handler: ApiHandler): void; /** 用于延迟注册 API */ protected _delayImplementApiPath?: string; /** * Auto call `imeplementApi` by traverse the `apiPath` and find all matched `PtlXXX` and `ApiXXX`. * It is matched by checking whether the relative path and name of an API is consistent to the service name in `serviceProto`. * Notice that the name prefix of protocol is `Ptl`, of API is `Api`. * For example, `protocols/a/b/c/PtlTest` is matched to `api/a/b/c/ApiTest`. * @param apiPath Absolute path or relative path to `process.cwd()`. * @returns */ autoImplementApi(apiPath: string, delay?: boolean): Promise<{ succ: string[]; fail: string[]; }>; getApiHandler(svc: ApiServiceDef, apiPath?: string, logger?: Logger): Promise<{ handler: ApiHandler; errMsg?: undefined; } | { handler?: undefined; errMsg: string; }>; /** * Add a message handler, * duplicate handlers to the same `msgName` would be ignored. * @param msgName * @param handler * @returns */ listenMsg>(msgName: T | RegExp, handler: MsgHandler): MsgHandler; /** * Remove a message handler */ unlistenMsg(msgName: T | RegExp, handler: Function): void; /** * Remove all handlers from a message */ unlistenMsgAll(msgName: T | RegExp): void; /** * Event when the server cannot parse input buffer to api/msg call. * By default, it will return "Input Data Error" . */ onInputDataError(errMsg: string, conn: BaseConnection, data: string | Uint8Array | object): Promise; /** * Event when a uncaught error (except `TsrpcError`) is throwed. * By default, it will return a `TsrpcError` with message "Internal server error". * If `returnInnerError` is `true`, the original error would be returned as `innerErr` property. */ onInternalServerError(err: { message: string; stack?: string; name?: string; }, call: ApiCall): void; protected _gracefulStop?: { rs: () => void; }; /** * Stop the server gracefully. * Wait all API requests finished and then stop the server. * @param maxWaitTime - The max time(ms) to wait before force stop the server. * `undefined` and `0` means unlimited time. */ gracefulStop(maxWaitTime?: number): Promise; /** * Execute API function through the inner connection, which is useful for unit test. * * **NOTICE** * The `req` and return value is native JavaScript object which is not compatible to JSON. (etc. ArrayBuffer, Date, ObjectId) * If you are using pure JSON as transfering, you may need use `callApiByJSON`. * @param apiName * @param req * @param options */ callApi(apiName: T, req: ServiceType["api"][T]["req"]): Promise>; /** * Like `server.callApi`, but both input and output are pure JSON object, * which can be `JSON.stringify()` and `JSON.parse()` directly. * Types that not compatible to JSON, would be encoded and decoded automatically. * @param apiName - The same with `server.callApi`, may be parsed from the URL. * @param jsonReq - Request data in pure JSON * @returns Encoded `ApiReturn` in pure JSON */ /** * Process JSON request by inner proxy, this is useful when you are porting to cloud function services. * Both the input and output is pure JSON, ArrayBuffer/Date/ObjectId are encoded to string automatically. * @param apiName - Parsed from URL * @param req - Pure JSON * @param logger - Custom logger * @returns - Pure JSON */ inputJSON(apiName: string, req: object, logger?: PrefixLogger): Promise>; /** * Process input buffer by inner proxy, this is useful when you are porting to cloud function services. * @param buf Input buffer (may be sent by TSRPC client) * @returns Response buffer */ inputBuffer(buf: Uint8Array): Promise; protected _parseServerInput(tsbuffer: TSBuffer, serviceMap: ServiceMap, data: string | Uint8Array | object, serviceId?: number): { isSucc: true; result: ParsedServerInput; } | { isSucc: false; errMsg: string; }; } export declare interface BaseServerOptions { /** * Whether to enable JSON compatible mode. * When it is true, it can be compatible with typical HTTP JSON request (like RESTful API). * * @remarks * The JSON request methods are: * * 1. Add `Content-type: application/json` to request header. * 2. HTTP request is: `POST /{jsonUrlPath}/{apiName}`. * 3. POST body is JSON string. * 4. The response body is JSON string also. * * NOTICE: Buffer type are not supported due to JSON not support them. * For security and efficient reason, we strongly recommend you use binary encoded transportation. * * @defaultValue `false` */ json: boolean; /** @deprecated Use `json` instead. */ jsonEnabled?: boolean; /** * Whether to strictly distinguish between `null` and `undefined` when encoding, decoding, and type checking. * @defaultValue false */ strictNullChecks: boolean; /** * Timeout for processing an `ApiCall`(ms) * `0` and `undefined` means unlimited time * @defaultValue 30000 */ apiTimeout: number | undefined; /** * Logger for processing log * @defaultValue `new TerminalColorLogger()` (print to console with color) */ logger: Logger; /** * The minimum log level of `logger` * @defaultValue `debug` */ logLevel: LogLevel; /** * Whether to print API request body into log (may increase log size) * @defaultValue `true` */ logReqBody: boolean; /** * Whether to print API response body into log (may increase log size) * @defaultValue `true` */ logResBody: boolean; /** * Whether to print `[SendMsg]` and `[RecvMsg]` log into log * @defaultValue `true` */ logMsg: boolean; /** * If `true`, all sent and received raw buffer would be print into the log. * It may be useful when you do something for buffer encryption/decryption, and want to debug them. */ debugBuf?: boolean; /** * When uncaught error throwed, * whether to return the original error as a property `innerErr`. * (May include some sensitive information, suggests set to `false` in production environment.) * @defaultValue It depends on environment variable `NODE_ENV`. * If `NODE_ENV` equals to `production`, the default value is `false`, otherwise is `true`. */ returnInnerError: boolean; /** * Customize the protocol data type */ customTypes?: { [schemaId: string]: CustomTypeSchema; }; } export declare enum ConnectionStatus { Opened = "OPENED", Closing = "CLOSING", Closed = "CLOSED" } export declare const defaultBaseServerOptions: BaseServerOptions; export declare const defaultHttpServerOptions: HttpServerOptions; export declare type EncodeApiReturnOutput = { isSucc: true; /** Encoded binary buffer */ output: T; errMsg?: undefined; } | { isSucc: false; /** Error message */ errMsg: string; output?: undefined; }; /** * Client for TSRPC HTTP Server. * It uses native http module of NodeJS. * @typeParam ServiceType - `ServiceType` from generated `proto.ts` */ export declare class HttpClient extends BaseHttpClient { readonly options: Readonly; constructor(proto: ServiceProto, options?: Partial); } export declare interface HttpClientOptions extends BaseHttpClientOptions { /** NodeJS HTTP Agent */ agent?: http.Agent | https.Agent; } export declare class HttpConnection extends BaseConnection { readonly type = "SHORT"; protected readonly ApiCallClass: typeof ApiCallHttp; protected readonly MsgCallClass: typeof MsgCallHttp; readonly httpReq: http_2.IncomingMessage & { rawBody?: Buffer; }; readonly httpRes: http_2.ServerResponse; readonly server: HttpServer; /** * Whether the transportation of the connection is JSON encoded instead of binary encoded. */ readonly isJSON: boolean | undefined; /** * In short connection, one connection correspond one call. * It may be `undefined` when the request data is not fully received yet. */ call?: ApiCallHttp | MsgCallHttp; constructor(options: HttpConnectionOptions); get status(): ConnectionStatus; protected doSendData(data: string | Uint8Array, call?: ApiCall): Promise<{ isSucc: true; } | { isSucc: false; errMsg: string; }>; /** * Close the connection, the reason would be attached to response header `X-TSRPC-Close-Reason`. */ close(reason?: string): void; makeCall(input: ParsedServerInput): ApiCallHttp | MsgCallHttp; } export declare interface HttpConnectionOptions extends BaseConnectionOptions { server: HttpServer; httpReq: http_2.IncomingMessage; httpRes: http_2.ServerResponse; } /** * TSRPC Server, based on HTTP connection. * @typeParam ServiceType - `ServiceType` from generated `proto.ts` */ export declare class HttpServer extends BaseServer { readonly options: HttpServerOptions; constructor(proto: ServiceProto, options?: Partial>); /** Native `http.Server` of NodeJS */ httpServer?: http_2.Server | https.Server; /** * {@inheritDoc BaseServer.start} */ start(): Promise; /** * {@inheritDoc BaseServer.stop} */ stop(): Promise; } export declare interface HttpServerOptions extends BaseServerOptions { /** Which port the HTTP server listen to */ port: number; /** * HTTPS options, the server would use https instead of http if this value is defined. * NOTICE: Once you enabled https, you CANNOT visit the server via `http://` anymore. * If you need visit the server via both `http://` and `https://`, you can start 2 HttpServer (one with `https` and another without). * @defaultValue `undefined` */ https?: { /** * @example * fs.readFileSync('xxx-key.pem'); */ key: https.ServerOptions["key"]; /** * @example * fs.readFileSync('xxx-cert.pem'); */ cert: https.ServerOptions["cert"]; }; /** * Passed to the `timeout` property to the native `http.Server` of NodeJS, in milliseconds. * `0` and `undefined` will disable the socket timeout behavior. * NOTICE: this `socketTimeout` be `undefined` only means disabling of the socket timeout, the `apiTimeout` is still working. * `socketTimeout` should always greater than `apiTimeout`. * @defaultValue `undefined` * @see {@link https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_server_timeout} */ socketTimeout?: number; /** * Passed to the `keepAliveTimeout` property to the native `http.Server` of NodeJS, in milliseconds. * It means keep-alive timeout of HTTP socket connection. * @defaultValue 5000 (from NodeJS) * @see {@link https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_server_keepalivetimeout} */ keepAliveTimeout?: number; /** * Response header value of `Access-Control-Allow-Origin`. * If this has any value, it would also set `Access-Control-Allow-Headers` as `*`. * `undefined` means no CORS header. * @defaultValue `*` */ cors?: string; /** * Response header value of `Access-Control-Allow-Origin`. * @defaultValue `3600` */ corsMaxAge?: number; /** * Actual URL path is `${jsonHostPath}/${apiName}`. * For example, if `jsonHostPath` is `'/api'`, then you can send `POST /api/a/b/c/Test` to call API `a/b/c/Test`. * @defaultValue `'/'` */ jsonHostPath: string; } /** * A call request by `client.sendMsg()` * @typeParam Msg - Type of the message * @typeParam ServiceType - The same `ServiceType` to server, it is used for code auto hint. */ export declare abstract class MsgCall extends BaseCall { readonly type: "msg"; readonly service: MsgService; readonly msg: Msg; constructor(options: MsgCallOptions, logger?: PrefixLogger); } export declare class MsgCallHttp extends MsgCall { readonly conn: HttpConnection; constructor(options: MsgCallHttpOptions); } export declare interface MsgCallHttpOptions extends MsgCallOptions { conn: HttpConnection; } export declare interface MsgCallOptions extends BaseCallOptions { service: MsgService; msg: Msg; } export declare class MsgCallWs extends MsgCall { readonly conn: WsConnection; constructor(options: MsgCallWsOptions); } export declare interface MsgCallWsOptions extends MsgCallOptions { conn: WsConnection; } export declare type MsgHandler = (call: Call) => void | Promise; /** * Auto add prefix using existed `Logger` */ export declare class PrefixLogger implements Logger { readonly logger: PrefixLoggerOptions["logger"]; readonly prefixs: PrefixLoggerOptions["prefixs"]; constructor(options: PrefixLoggerOptions); getPrefix(): string[]; log(...args: any[]): void; debug(...args: any[]): void; warn(...args: any[]): void; error(...args: any[]): void; } export declare interface PrefixLoggerOptions { logger: Logger; prefixs: (string | (() => string))[]; } export declare type SendReturnMethod = (ret: ApiReturn) => ReturnType; export declare enum ServerStatus { Opening = "OPENING", Opened = "OPENED", Closing = "CLOSING", Closed = "CLOSED" } /** * Print log to terminal, with color. */ export declare class TerminalColorLogger implements Logger { options: TerminalColorLoggerOptions; private _pid; constructor(options?: Partial); private _time; debug(...args: any[]): void; log(...args: any[]): void; warn(...args: any[]): void; error(...args: any[]): void; } export declare interface TerminalColorLoggerOptions { /** * Process ID prefix * @defaultValue `process.pid` */ pid: string; /** * `undefined` represents not print time * @defaultValue 'yyyy-MM-dd hh:mm:ss' */ timeFormat?: string; } /** Version of TSRPC */ export declare const TSRPC_VERSION = "__TSRPC_VERSION__"; /** * Client for TSRPC WebSocket Server. * @typeParam ServiceType - `ServiceType` from generated `proto.ts` */ export declare class WsClient extends BaseWsClient { readonly options: Readonly; constructor(proto: ServiceProto, options?: Partial); } export declare interface WsClientOptions extends BaseWsClientOptions { } /** * Connected client */ export declare class WsConnection extends BaseConnection { readonly type = "LONG"; protected readonly ApiCallClass: typeof ApiCallWs; protected readonly MsgCallClass: typeof MsgCallWs; readonly ws: WebSocket_2; readonly httpReq: http_2.IncomingMessage; readonly server: WsServer; dataType: "text" | "buffer"; isDataTypeConfirmed?: boolean; constructor(options: WsConnectionOptions); private _lastHeartbeatTime; private _heartbeatInterval?; get status(): ConnectionStatus; protected doSendData(data: string | Uint8Array, call?: ApiCallWs): Promise<{ isSucc: true; } | { isSucc: false; errMsg: string; }>; protected _rsClose?: () => void; /** Close WebSocket connection */ close(reason?: string, code?: number, closeTimeout?: number): Promise; } export declare interface WsConnectionOptions extends BaseConnectionOptions { server: WsServer; ws: WebSocket_2; httpReq: http_2.IncomingMessage; onClose: (conn: WsConnection, code: number, reason: string) => Promise; dataType: "text" | "buffer"; isDataTypeConfirmed?: boolean; } /** * TSRPC Server, based on WebSocket connection. * It can support realtime cases. * @typeParam ServiceType - `ServiceType` from generated `proto.ts` */ export declare class WsServer extends BaseServer { readonly options: WsServerOptions; readonly connections: WsConnection[]; private readonly _id2Conn; constructor(proto: ServiceProto, options?: Partial>); private _wsServer?; private _httpServer?; /** * {@inheritDoc BaseServer.start} */ start(): Promise; /** * {@inheritDoc BaseServer.stop} */ stop(): Promise; private _onClientConnect; private _onClientClose; /** * Send the same message to many connections. * No matter how many target connections are, the message would be only encoded once. * @param msgName * @param msg - Message body * @param connIds - `id` of target connections, `undefined` means broadcast to every connections. * @returns Send result, `isSucc: true` means the message buffer is sent to kernel, not represents the clients received. */ broadcastMsg(msgName: T, msg: ServiceType["msg"][T], conns?: WsConnection[]): Promise<{ isSucc: true; } | { isSucc: false; errMsg: string; }>; } export declare interface WsServerOptions extends BaseServerOptions { /** Which port the WebSocket server is listen to */ port: number; /** Whether to print `[Connected]` and `[Disconnected]` into log */ logConnect: boolean; /** * HTTPS options, the server would use wss instead of http if this value is defined. * NOTICE: Once you enabled wss, you CANNOT visit the server via `ws://` anymore. * If you need visit the server via both `ws://` and `wss://`, you can start 2 HttpServer (one with `wss` and another without). * @defaultValue `undefined` */ wss?: { /** * @example * fs.readFileSync('xxx-key.pem'); */ key: https.ServerOptions["key"]; /** * @example * fs.readFileSync('xxx-cert.pem'); */ cert: https.ServerOptions["cert"]; }; /** * Close a connection if not receive heartbeat after the time (ms). * This value should be greater than `client.heartbeat.interval`, for exmaple 2x of it. * `undefined` or `0` represent disable this feature. * @defaultValue `undefined` */ heartbeatWaitTime?: number; /** * WebSocket server options, transfer to 'ws' package. */ wsOptions?: WebSocket_2.ServerOptions; } export * from "tsrpc-base-client"; export * from "tsrpc-proto"; export { }