// utils/socket-io.service.ts
// utils/socket-io.service.ts
import {Server, ServerOptions} from "socket.io";
import {Server as HttpServer} from "http";
export class SocketIOService {
private static _instance: SocketIOService | undefined;
private static server: Server | undefined;
private constructor() {
// Private constructor ensures singleton instance
}
static instance(): SocketIOService {
if (!this._instance) {
return new SocketIOService();
}
return this._instance;
}
initialize(httpServer: HttpServer, opts?: Partial<ServerOptions>) {
SocketIOService.server = new Server(httpServer, opts);
return SocketIOService.server;
}
ready() {
return SocketIOService.server !== null;
}
getServer(): Server {
if (!SocketIOService.server) {
throw new Error('IO server requested before initialization');
}
return SocketIOService.server;
}
sendMessage(roomId: string | string[], key: string, message: string) {
this.getServer().to(roomId).emit(key, message)
}
emitAll(key: string, message: string) {
this.getServer().emit(key, message)
}
getRooms() {
return this.getServer().sockets.adapter.rooms;
}
}
The service must be initialized before use:
// app.ts
import express from "express";
import log from "./logger";
import cors from "cors";
import {createServer} from "http";
import {SocketIOService} from "./utils/socket-io.service";
const app = express();
const httpServer = createServer(app);
SocketIOService.instance().initialize(httpServer, {
cors: {
origin: ['http://localhost:4200']
}
});
const io = SocketIOService.instance().getServer();
io.on('connection', (socket) => {
log.info('a user connected');
socket.on('disconnect', () => {
log.info('user disconnected');
});
socket.on('my message', (msg) => {
console.log('message: ' + msg);
io.emit('my broadcast', `server: ${msg}`);
});
socket.on('room_update', (msg) => {
console.log('message: ' + msg);
})
});
// ...
And then to call the service from another file (e.g. a HTTP Handler)
import {SocketIOService} from "../utils/socket-io.service";
import log from "../logger";
function notifyUpdatedRoom(roomId: string) {
log.info(`Notifying on updated room: ${roomId}`);
if (roomId && SocketIOService.instance().ready()) {
SocketIOService.instance().emitAll('room_update', roomId);
}
}