mattstyles / koa-socket

Sugar for connecting socket.io to a koa instance
242 stars 50 forks source link

Koa ctx argument in event handlers not present #31

Open askdesigners opened 7 years ago

askdesigners commented 7 years ago

@mattstyles pinging you here from that stack overflow question :)

So I'm probably doing something wrong, or not understanding best practices here. :)

I've got an app where I need to create a separate socket io namespace for each "company". The server will be providing service to multiple companies each with their own users, and having things separated this way seems logical.

Since it needs to be dynamic I'm basically reading in all the companies at app-start, and create the namespace for each at this time. This function looks like this.

socket.js

companyService.fetch()
        .then((companies) => {
            console.log(`Creating ${companies.length} company namespaces.`);

            companies.forEach(function(c){
                nameSpaces[c.ClientID] = new IO({
                        namespace: `/${c.ClientID}`
                    });
                nameSpaces[c.ClientID].attach(app);
            });

            app._io.set('transports',['xhr-polling','websockets']);
            app._io.listen(server);

            nameSpaceHandlers(nameSpaces, app._io);

        })

nameSpaceHandlers.js

module.exports = function (namespaces, io) {
    let ns = Object.keys(namespaces);

    ns.forEach(function(companyNamespace) {
        console.log(`Binding handlers and middleware to: ${companyNamespace}`);
        bindMessageHandlers(namespaces[companyNamespace], io);
    }, this);
}

bindMessageHandlers.js


glob.sync('server/resources/**/*.handlers.js').forEach(function (file) {
    let resourceName = file.split('/').slice(-1).pop().split('.')[0];
    socketHandlers[resourceName] = require(path.resolve(file));
    resources.push(resourceName);
});

module.exports = function(ns, io){
    ns.on('connection', function (socket) {
        console.log('<---ooo User connected');

        socket.socket.on('disconnect', function () {
            console.log('xxx---> User disconnected');
        });

        console.log(':: Binding messages ::');

        resources.forEach((r) => {
            Object.keys(socketHandlers[r]).forEach((method) => {
                let eventName = `${r}:${method}`;
                socket.socket.on(eventName, socketHandlers[r][method]);
            });
        });

    });
};

With this setup I'm able to auto-bind all *.handlers.js file in the directory. Makes maintenance really simple. However when I call the events from the client, the handlers are getting triggered so I know it's getting hooked up, but the first argument in the handlers is the data sent by the client, and not the koa ctx object....

I'm also binding middleware in the same way, by globbing *.middleware.js files, and those aren't getting hit at all despite it seeming like they are getting bound at app-start time...

Now I might have gone wrong by passing and operating on the ns object literal I create in the first step. Would that be what causes this?

I've got a goofy koa app setup, with an https wrapper around the normal http server, so I'm not sure if the problem is in the app-->server config, or the app-->sockets setup...

Any ideas? And thanks for offering the help!