UNPKG

@freemework/hosting

Version:

Hosting library of the Freemework Project.

187 lines (186 loc) 9.55 kB
import { FDisposable, FExecutionContext, type FChannelPublisher, type FChannelSubscriber, FCancellationToken, FInitableBase, FLogger } from "@freemework/common"; import express from 'express'; import http from "http"; import https from "https"; import WebSocket from "ws"; import { FHostingSettings } from "./f_hosting_settings.js"; export { FHostingSettings, FHostingConfiguration } from "./f_hosting_settings.js"; export { FHttpRequestCancellationToken } from "./FHttpRequestCancellationToken.js"; export * from "./configuration/index.js"; export * from "./launcher/index.js"; export type FWebServerRequestHandler = http.RequestListener; export interface FWebServer extends FInitableBase { readonly name: string; readonly underlyingServer: http.Server | https.Server; rootExpressApplication: express.Application; bindRequestHandler(bindPath: string, handler: FWebServerRequestHandler): void; createWebSocketServer(bindPath: string): WebSocket.Server; destroyWebSocketServer(bindPath: string): Promise<void>; } export declare abstract class FAbstractWebServer<TOpts extends FHostingSettings.WebServerBase | FHostingSettings.WebServer> extends FInitableBase implements FWebServer { abstract readonly underlyingServer: http.Server | https.Server; protected readonly _trustProxy: boolean | "loopback" | "linklocal" | "uniquelocal"; protected readonly _name: string; protected readonly _listenHost: string; protected readonly _listenPort: number; protected readonly _webSockets: { [bindPath: string]: WebSocket.Server; }; protected readonly _log: FLogger; protected readonly _handleUpgrade: boolean; private readonly _onUpgrade; private readonly _onRequestImpl; private readonly _handlers; private _rootExpressApplication; static createFCancellationToken(request: http.IncomingMessage): FCancellationToken; constructor(opts: TOpts); /** * Lazy create for Express Application */ get rootExpressApplication(): express.Application; set rootExpressApplication(value: express.Application); get name(): string; bindRequestHandler(bindPath: string, value: FWebServerRequestHandler): void; createWebSocketServer(bindPath: string): WebSocket.Server; destroyWebSocketServer(bindPath: string): Promise<void>; protected onInit(): Promise<void>; protected abstract onListen(): Promise<void>; protected onRequest(req: http.IncomingMessage, res: http.ServerResponse): void; private onRequestCommon; private onRequestXFCC; private onUpgradeCommon; private onUpgradeXFCC; private validateXFCC; } export declare class UnsecuredWebServer extends FAbstractWebServer<FHostingSettings.UnsecuredWebServer> { private readonly _httpServer; constructor(opts: FHostingSettings.UnsecuredWebServer); get underlyingServer(): http.Server; protected onListen(): Promise<void>; protected onDispose(): Promise<void>; } export declare class SecuredWebServer extends FAbstractWebServer<FHostingSettings.SecuredWebServer> { private readonly _httpsServer; constructor(opts: FHostingSettings.SecuredWebServer); get underlyingServer(): https.Server; protected onListen(): Promise<void>; protected onDispose(): Promise<void>; } export declare abstract class FBindEndpoint extends FInitableBase { protected readonly _bindPath: string; constructor(opts: FHostingSettings.BindEndpoint); protected onInit(): void | Promise<void>; protected onDispose(): void | Promise<void>; } export declare abstract class FServersBindEndpoint extends FBindEndpoint { protected readonly _servers: ReadonlyArray<FWebServer>; constructor(servers: ReadonlyArray<FWebServer>, opts: FHostingSettings.BindEndpoint); } /** * This endpoint supplies communication channels for each client connection. * * WebSocket Client is hosting the channel: * - Client's messages delivered via SubscriberChannel * - To deliver message to client use PublisherChannel * * If you need opposite behavior take a look for `WebSocketChannelFactoryEndpoint` * * You need to override onOpenBinaryChannel and/or onOpenTextChannel to obtain necessary channel */ export declare class FWebSocketChannelSupplyEndpoint extends FServersBindEndpoint { private readonly _webSocketServers; private readonly _connections; private readonly _log; private _defaultProtocol; private _allowedProtocols; private _connectionCounter; constructor(servers: ReadonlyArray<FWebServer>, opts: FHostingSettings.WebSocketEndpoint); protected onInit(): void; protected onDispose(): Promise<void>; protected onConnection(webSocket: WebSocket, request: http.IncomingMessage): void; /** * The method should be overridden. The method called by the endpoint, * when WSClient sent first binary message for specified sub-protocol. * @param webSocket WebSocket instance * @param subProtocol These strings are used to indicate sub-protocols, * so that a single server can implement multiple WebSocket sub-protocols (for example, * you might want one server to be able to handle different types of interactions * depending on the specified protocol). * @param channel Binary channel instance to be user in inherited class */ protected onOpenBinaryChannel(_webSocket: WebSocket, subProtocol: string, _channel: FWebSocketChannelSupplyEndpoint.BinaryChannel): void; /** * The method should be overridden. The method called by the endpoint, * when WSClient sent first text message for specified sub-protocol. * @param webSocket WebSocket instance * @param subProtocol These strings are used to indicate sub-protocols, * so that a single server can implement multiple WebSocket sub-protocols (for example, * you might want one server to be able to handle different types of interactions * depending on the specified protocol). * @param channel Text channel instance to be user in inherited class */ protected onOpenTextChannel(_webSocket: WebSocket, subProtocol: string, _channel: FWebSocketChannelSupplyEndpoint.TextChannel): void; } export declare namespace FWebSocketChannelSupplyEndpoint { interface BinaryChannel extends FChannelPublisher<Uint8Array>, FChannelSubscriber<Uint8Array> { } interface TextChannel extends FChannelPublisher<string>, FChannelSubscriber<string> { } } /** * This endpoint requests you for communication channels for each client connection. * * WebSocket Client is used the channel: * - Client's messages delivered via PublisherChannel * - To deliver message to client use SubscriberChannel * * If you need opposite behavior take a look for `WebSocketChannelSupplyEndpoint` * * You need to override createBinaryChannel and/or createTextChannel to provide necessary channel */ export declare class FWebSocketChannelFactoryEndpoint extends FServersBindEndpoint { private readonly _webSocketServers; private readonly _connections; private readonly _autoCreateChannelBinary; private readonly _autoCreateChannelText; private readonly _log; private _defaultProtocol; private _allowedProtocols; private _connectionCounter; constructor(servers: ReadonlyArray<FWebServer>, opts: FHostingSettings.WebSocketEndpoint, autoCreateChannels?: { binary?: boolean; text?: boolean; }); protected onInit(): void; protected onDispose(): Promise<void>; protected onConnection(webSocket: WebSocket, request: http.IncomingMessage): Promise<void>; /** * The method should be overridden. The method called by the endpoint, * when WSClient sent first binary message for specified sub-protocol. * @param webSocket WebSocket instance * @param subProtocol These strings are used to indicate sub-protocols, * so that a single server can implement multiple WebSocket sub-protocols (for example, * you might want one server to be able to handle different types of interactions * depending on the specified protocol). */ protected createBinaryChannel(_executionContext: FExecutionContext, _webSocket: WebSocket, subProtocol: string): Promise<FWebSocketChannelFactoryEndpoint.BinaryChannel>; /** * The method should be overridden. The method called by the endpoint, * when WSClient sent first text message for specified sub-protocol. * @param webSocket WebSocket instance * @param subProtocol These strings are used to indicate sub-protocols, * so that a single server can implement multiple WebSocket sub-protocols (for example, * you might want one server to be able to handle different types of interactions * depending on the specified protocol). */ protected createTextChannel(_executionContext: FExecutionContext, _webSocket: WebSocket, subProtocol: string): Promise<FWebSocketChannelFactoryEndpoint.TextChannel>; } export declare namespace FWebSocketChannelFactoryEndpoint { interface BinaryChannel extends FDisposable, FChannelPublisher<Uint8Array>, FChannelSubscriber<Uint8Array> { } interface TextChannel extends FDisposable, FChannelPublisher<string>, FChannelSubscriber<string> { } } export declare function instanceofWebServer(server: any): server is FWebServer; export declare function createWebServer(serverOpts: FHostingSettings.WebServer): FWebServer; export declare function createWebServers(serversOpts: ReadonlyArray<FHostingSettings.WebServer>): ReadonlyArray<FWebServer>;