Skip to content
Nguyễn Minh Tâm edited this page Jul 28, 2024 · 6 revisions

Socket IO Server

Configure Redis
import { RedisHelper } from '@tanphat199/lb-infra';

class RedisComponent extends BaseComponent {
  private ioRedis: RedisHelper;

  constructor(
    @inject(CoreBindings.APPLICATION_INSTANCE) private application: BaseApplication,
  ) {
    super({ scope: RedisComponent.name });

    // --------------------------------------------------------------------------------
    this.logger.info('START | Initialize IO REDIS');
    const ioRedisOptions = {
      name: 'MT_IO_REDIS',
      host: applicationEnvironment.get<string>(
        EnvironmentKeys.APP_ENV_REDIS_HOST,
      ),
      port: applicationEnvironment.get<number>(
        EnvironmentKeys.APP_ENV_REDIS_PORT,
      ),
      password: applicationEnvironment.get<string>(
        EnvironmentKeys.APP_ENV_REDIS_PASSWORD,
      ),
    };
    this.ioRedis = new RedisHelper(ioRedisOptions);
    this.application.bind(<YOUR_BINDING_REDIS_KEY>).to(this.ioRedis);
    this.logger.info('DONE | Initialize IO REDIS');
  }
}
class MyApplication extends DefaultRestApplication {
  ...
  postConfigure(): void {
    ...
    this.component(RedisComponent);
    ...
  }
  ...
}
Configure Socket IO

Configure options

import { RedisHelper } from '@tanphat199/lb-infra';

class ApplicationIOServerComponent
  extends BaseComponent
  implements LifeCycleObserver
{
  constructor(
    @inject(CoreBindings.APPLICATION_INSTANCE)
    private application: BaseApplication,
    @inject(<YOUR_BINDING_REDIS_KEY>) private ioRedisClient: RedisHelper,
  ) {
    super({ scope: ApplicationIOServerComponent.name });
  }

  start() {
    this.logger.info('START | Initialize Application Socket IO Server');

    const jwtTokenService = this.application.getSync<JWTTokenService>(
      'services.JWTTokenService',
    );
    this.application
      .bind(SocketIOKeys.IDENTIFIER)
      .to('APPLICATION_SOCKET_IO_SERVER');
    this.application.bind(SocketIOKeys.SERVER_OPTIONS).to({
      path: RestPaths.STREAM,
      cors: {
        origin: '*',
        methods: ['GET', 'POST'],
        preflightContinue: false,
        optionsSuccessStatus: 204,
        credentials: true,
      },
    });
    this.application
      .bind(SocketIOKeys.REDIS_CONNECTION)
      .to(this.ioRedisClient.client);
    this.application
      .bind(SocketIOKeys.AUTHENTICATE_HANDLER)
      .to(async (handshake: { headers: any }) => {
        if (handshake.headers.authorization) {
          const token = jwtTokenService.extractCredentials(handshake);
          const rs = jwtTokenService.verify(token);
          return rs?.userId !== undefined && (rs.userId as number) > 0;
        }
        return true;
      });

    this.application
      .bind(SocketIOKeys.CLIENT_CONNECTED_HANDLER)
      .to((...rest: any[]) => {});
    this.application.component(SocketIOComponent);

    this.logger.info('DONE | Initialize Application Socket IO Server');
  }
}
class MyApplication extends DefaultRestApplication {
  ...
  postConfigure(): void {
    ...
    this.component(ApplicationSocketIOServerComponent);
    ...
  }
  ...
}
How to use
const socketIOInstance = application.getSync<SocketIOServerHelper>(
  SocketIOKeys.SOCKET_IO_INSTANCE
);

socketIOInstance.send({
  destination: "<YOUR_DESTINATION>",
  payload: {
    topic: "<YOUR_TOPIC>",
    data: {},
  },
});

Socket TCP Client

Configure options

interface IArticleTcpHandlerOptions {
  identifier: string;
  host: string;
  port: number;
}

class NetworkTcpHandler {
  private readonly RECONNECT = true;
  private readonly MAX_RETRY = 1000;

  private client: NetworkTcpClient;
  private identifier: string;
  private host: string;
  private port: number;

  constructor(opts: IArticleTcpHandlerOptions) {
    this.identifier = opts.identifier;
    this.host = opts.host;
    this.port = opts.port;
  }

  static newInstance(opts: IArticleTcpHandlerOptions) {
    return new ArticleTcpHandler(opts);
  }

  getClient() {
    return this.client;
  }

  configure() {
    this.client = new NetworkTcpClient({
      identifier: this.identifier,
      options: {
        host: this.host,
        port: this.port,
        localAddress: "",
      },
      reconnect: this.RECONNECT,
      maxRetry: this.MAX_RETRY,
      onData: this.onData,
      onConnected: this.onConnect,
    });

    this.client.connect({ resetReconnectCounter: true });
  }

  onData = async (opts: { identifier: string; message: any }) => {
    const rawMessage = opts.message;
    <LOGIC_HANDLE_DATA>
    ...
  }

  onConnect() {
    ...
  }
}
How to use
this.networkTcpHandler = NetworkTcpHandler.newInstance({
  identifier: <YOUR_IDENTIFIER>,
  host: <YOUR_HOST>,
  port: <YOUR_PORT>,
});

this.networkTcpHandler.configure();

Minimal Technology Vietnam

Clone this wiki locally