Inverisfy express util is not connecting to web socket socket.io server

import 'module-alias/register';
import 'reflect-metadata';
import sourceMapSupport from 'source-map-support';
import { LIB_ENV_CONFIG, logger } from '@sn/shared';
import { AppServer, IExpressMiddleware, InversifyFactory } from '@sn/server';
import { AsyncContainerModule } from 'inversify';
import { customMiddleware } from './shared/middleware/AppMiddleware';
import swaggerMiddleware from './shared/middleware/Swagger';
import { AppModule } from '@ioc/IocConfig';
import { Server, Socket } from 'socket.io';
import * as http from 'http';

sourceMapSupport.install();

const expressApp = (async (): Promise<void> => {
  try {
    logger.pushContext(LIB_ENV_CONFIG.LIB_SERVICE_NAME);
    const serviceGlobalCustomMiddlewares: IExpressMiddleware[] = [
      customMiddleware,
      swaggerMiddleware
    ];
    const containers: AsyncContainerModule[] = await InversifyFactory.create(AppModule);
    const app = new AppServer(containers, serviceGlobalCustomMiddlewares);
    await app.startServer();

    const expressServerInstance = app.getServer();
    const httpServer = http.createServer(expressServerInstance);
    const io: Server = new Server(httpServer);

    io.on('connection', (socket: Socket) => {
      console.log('a user connected');

      socket.on('disconnect', () => {
        console.log('user disconnected');
      });

      socket.on('chat message', (msg: string) => {
        io.emit('chat message', msg);
      });
    });
    io.on('listening', () => {
      console.log('WebSocket server is listening for connections');
    });
  } catch (err) {
    logger.error(`Server setup error in apps/${LIB_ENV_CONFIG.LIB_SERVICE_NAME}`, err);
  }
})();

expressApp;

This is how I am setting up the inversify express server

import 'reflect-metadata';
/* eslint-disable  @typescript-eslint/no-explicit-any */
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('source-map-support').install();
import * as dotenv from 'dotenv';
import { InversifyExpressServer } from 'inversify-express-utils';
import { ExpressMiddleware, errorMiddleware } from './../middleware';
import { LIB_ENV_CONFIG, logger } from '@sn/shared';
import { AsyncContainerModule, Container } from 'inversify';
import { IExpressMiddleware } from './../interface/IMiddleware';
import { HealthCheckRouter } from './HealthCheckRouter';

dotenv.config();

export class AppServer {
  private readonly servicePort = LIB_ENV_CONFIG.LIB_PORT;
  private readonly serviceName = LIB_ENV_CONFIG.LIB_SERVICE_NAME;
  private readonly serviceUrl = LIB_ENV_CONFIG.LIB_SERVICE_URL;
  private readonly serviceApiVersionUri = LIB_ENV_CONFIG.LIB_CLIENT_API_VERSION;
  private readonly serviceBaseUrl = LIB_ENV_CONFIG.LIB_SERVICE_BASE_URL;
  private readonly serviceEnv = LIB_ENV_CONFIG.LIB_NODE_ENV || 'development';
  private rootPath = this.serviceBaseUrl + this.serviceApiVersionUri;

  private server: InversifyExpressServer;
  private serverInstance;
  constructor(
    serviceInversifyContainers: AsyncContainerModule[],
    serviceGlobalCustomMiddlewares: IExpressMiddleware[]
  ) {
    this.loadInversifyServer(serviceInversifyContainers);
    this.loadLibMiddlewares(serviceGlobalCustomMiddlewares);
    this.loadErrorMiddleware();
  }

  private loadInversifyServer = (serviceInversifyContainers: AsyncContainerModule[]) => {
    const container = new Container();

    HealthCheckRouter;
    serviceInversifyContainers.forEach((moduleConfigContainer: any) => {
      container.loadAsync(moduleConfigContainer);
    });

    this.server = new InversifyExpressServer(container, null, {
      rootPath: this.rootPath
    });
  };

  private loadLibMiddlewares = (serviceGlobalCustomMiddlewares: IExpressMiddleware[]) => {
    this.server.setConfig((app) => {
      logger.info(`LOADING LIBRARY LEVEL MIDDLEWARES ...........`);
      new ExpressMiddleware(app);
      serviceGlobalCustomMiddlewares.forEach((serviceMiddleware) => {
        serviceMiddleware(app);
      });
    });
  };

  private loadErrorMiddleware = () => {
    this.server.setErrorConfig(errorMiddleware);
  };

  startServer = async () => {
    const serverInstance = this.server.build();
    this.serverInstance = serverInstance;
    serverInstance.listen(this.servicePort, () => {
      logger.info(
        `FOR SERVICE: [ ${this.serviceName} ] -> Server running at ${this.serviceUrl}:${this.servicePort}${this.rootPath} -> on ${this.serviceEnv} environment`
      );
    });
  };

  getServer = () => {
    return this.serverInstance;
  };
}


The express server is working fine but not able to setup socket.io connection

There is no error in server build but connection is not working

ws://127.0.0.1:3008/web-socket-service/api/v1/socket.io?EIO=3&transport=websocket

this is disconnection error

It worked, Need to add few changes

The app server is using the base path and that base path has to be added to the socket.io namespace

Also instead of passing the express request handler function to server instance
this.serverInstance = serverInstance;

we need to pass the server

startServer = async () => {
    const serverInstance = this.server.build();
    this.serverInstance = serverInstance.listen(this.servicePort, () => {
      logger.info(
        `FOR SERVICE: [ ${this.serviceName} ] -> Server running at ${this.serviceUrl}:${this.servicePort}${this.rootPath} -> on ${this.serviceEnv} environment`
      );
    });
  };

Leave a Comment