UNPKG

@loopeco/socketio

Version:

A enhanced LoopBack's WebSocket server based on socket.io

85 lines (69 loc) 2.68 kB
import {Context, ControllerClass} from '@loopback/core'; import {HttpServerOptions} from '@loopback/http-server'; import {Socket} from 'socket.io'; import {ExtendedError} from 'socket.io/dist/namespace'; import {getMiddlewareContext, MiddlewareContext} from '@loopback/express'; import {DefaultEventsMap, EventsMap} from 'socket.io/dist/typed-events'; import {Request} from 'express'; import {SocketIoBindings} from './keys'; import {expressInit} from './express'; export type SocketIoOptions = HttpServerOptions; export interface SocketIoSequence { handle(methodName: string, args: unknown[], done: Function): Promise<void>; } export type SocketIoDoneFunction = (response: unknown) => Promise<void>; export type SocketIoInvokeMethod = ( context: Context, controller: ControllerClass, methodName: string, args: unknown[], ) => unknown; export type SocketIoSendMethod = (done: Function, result: unknown) => unknown; export type SocketIoRejectMethod = (done: Function, error: Error) => unknown; export interface SocketIoNextFunction { (err?: ExtendedError): void; } export interface SocketIoConnectionHandler< ListenEvents extends EventsMap = DefaultEventsMap, EmitEvents extends EventsMap = ListenEvents, ServerSideEvents extends EventsMap = DefaultEventsMap, > { (socket: Socket<ListenEvents, EmitEvents, ServerSideEvents>, next: SocketIoNextFunction): void; } export interface SocketIoHandlerContext { socket: Socket; } /** * A per-connection Context to combine an IoC container with handler * context (socket, etc.). */ export class SocketIoConnectionContext extends MiddlewareContext implements SocketIoHandlerContext { /** * Constructor for `SocketContext` * @param socket - SocketIO socket object * @param parent - Parent context * @param name - Name of the middleware context */ constructor(public readonly socket: Socket, parent?: Context, name?: string) { super(...expressInit(socket), parent, name); this.setupBindings(); } protected setupBindings() { this.bind(SocketIoBindings.SOCKET).to(this.socket); } } // eslint-disable-next-line @typescript-eslint/no-explicit-any export function isConnectionContext(ctx: any): ctx is SocketIoConnectionContext { return !!ctx && typeof ctx.bind === 'function' && !!ctx.socket; } export function getConnectionContext<T extends SocketIoConnectionContext = SocketIoConnectionContext>( socket: Socket, ): T | undefined { return getMiddlewareContext<T>(socket.request as Request); } export function getSocket(context: Context) { if (isConnectionContext(context)) { return context.socket; } return context.getSync(SocketIoBindings.SOCKET); }