Example using NestJS with Socket.IO and Redis
File adapters/redis-io.adapter.ts
import { IoAdapter } from '@nestjs/platform-socket.io'; import * as io from 'socket.io' import * as redisIoAdapter from 'socket.io-redis'; import * as redis from 'redis' export class RedisIoAdapter extends IoAdapter { protected ioServer: io.Server constructor(app:any) { super() let httpServer = app.getHttpServer() this.ioServer = io(httpServer) } createIOServer(port: number, options?: io.ServerOptions): any { let server //same port with main application if(port==0 || port == parseInt(process.env.PORT || '4000')) server = this.ioServer //different port with main application else server = super.createIOServer(port, options); const pub = redis.createClient({ host: process.env.REDISHOST||'localhost', port: parseInt(process.env.REDISPORT||"6379") }) const sub = redis.createClient({ host: process.env.REDISHOST||'localhost', port: parseInt(process.env.REDISPORT||"6379") }) const redisAdapter = redisIoAdapter({ pubClient: pub, subClient: sub }); //const redisAdapter = redisIoAdapter({ port: parseInt(process.env.REDISPORT || '6379'), host: process.env.REDISHOST || 'localhost' }); server.adapter(redisAdapter); return server; } }
File main.ts
import { NestFactory } from '@nestjs/core' import { AppModule } from './app.module' import * as dotenv from 'dotenv' import * as helmet from 'helmet' import * as consolidate from 'consolidate' import * as path from 'path' import { NestExpressApplication } from '@nestjs/platform-express' import { RedisIoAdapter } from './adapters/redis-io.adapter' dotenv.config() async function bootstrap() { const app = await NestFactory.create<NestExpressApplication>(AppModule,{ bodyParser:true, }) app.set('trust proxy', 1) app.use(helmet({ contentSecurityPolicy: false, })) app.engine('html', consolidate.mustache) app.set('view engine', 'html') app.set('views', path.join(__dirname,"..", 'views')) app.useWebSocketAdapter(new RedisIoAdapter(app)); await app.listen(process.env.PORT||4000) } bootstrap()
File events/events.gateway.ts
import { MessageBody, SubscribeMessage, WebSocketGateway, WsResponse, ConnectedSocket } from '@nestjs/websockets' import { Socket } from 'socket.io' @WebSocketGateway(parseInt(process.env.WSPORT || '4001'),{ namespace: 'events' }) export class EventsGateway { @SubscribeMessage('events') handleEvent( @MessageBody() data: unknown, @ConnectedSocket() client: Socket ): WsResponse<unknown> { const event = 'events'; return { event, data }; } }
File events/events.module.ts
import { Module } from '@nestjs/common'; import { EventsGateway } from './events.gateway'; @Module({ providers: [EventsGateway] }) export class EventsModule {}
Run test app.
File test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Sockets test</title> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.dev.js"></script> <script> window.s = io('http://localhost:4000/events', { query: { token: '123', }, transports: ['polling'] }); s.emit('events', { event: 'events', data: { test: true } }); s.on('events', (response) => { console.log(response); }); </script> </body> </html>