Matt Knight
Matt Knight

Reputation: 499

Sharing socket.io between modules in typescript

I have read several examples of different ways to share a socket.io connection among modules, but I can't quite seem to put all the pieces together to architect this.

I have a SocketConnection class which I want to share among all of my code.

import * as sio from 'socket.io';

export class SocketConnection {
    private static instance: SocketConnection;
    server: any;

    private constructor(server) {
        this.server = server;
    }
    static getInstance(server) {
        if (!SocketConnection.instance) {
            SocketConnection.instance = new SocketConnection(server);
            const io = sio(server);
            io.on('connection', (socket) => {
                console.log('conncted sockets');
                socket.emit('jobResult', { result: 'emitting startup!' });
            });
        }
        return SocketConnection.instance;
    }
}

Then in my app.ts, I use it like this:

// app.ts
// express app
const server = app.listen(param);
import { SocketConnection } from './integrationJobs/socketConnection';
const io = SocketConnection.getInstance(server);

// Now pass the resulting "io" into the job where I need to use socket.io
import { CourseListJob } from './integrationJobs/courseList';
const courseListJob = new CourseListJob(io);
const job = courseListJob.runJob();

Last bit of code where I call the job needing a socket:

// courseList.ts
export class CourseListJob {
    io: any;

    public constructor(io) {
        this.io = io;
    }

    public async runJob() {

          this.io.emit('progressMessage', 'Hello');
    }
}

Unfortunately, I get this: TypeError: this.io.emit is not a function

What am I doing wrong?

Upvotes: 0

Views: 1121

Answers (1)

Matt Knight
Matt Knight

Reputation: 499

I solved this by modifying my SocketConnection class to this:

import * as sio from 'socket.io';

export class SocketConnection {
    private static instance: SocketConnection;
    server: any;

    private constructor(server) {
        this.server = server;
    }
    public static GetSocket(server) {
        const io = sio(server);
        io.on('connection', (socket) => {
            console.log('conncted SocketConnection sockets');
            socket.emit('jobResult', { result: 'emitting startup!' });
        });
        return io;
    }
}

The in my app.ts, I use it like this:

import { SocketConnection } from './integrationJobs/socketConnection';
const io = SocketConnection.GetSocket(server);


import * as courseList from './integrationJobs/courseList';
courseList.register(io);

import * as courseEnrollment from './integrationJobs/courseEnrollment';
courseEnrollment.register(io);

In any bit of code where I need a socket, I just do this:

import * as sio from 'socket.io';

let io = null;

export function register(foo) {
    io = foo;
}

export class CourseListJob {
    public async runJob() {
    }
}

Upvotes: 1

Related Questions