socketcluster
socketcluster copied to clipboard
How to organize large numbers of event handlers
When you start handling many different types of events, the code in worker.js can get a little unwieldy:
scServer.on('connection', socket => {
socket.on('foo1', (data, res) => { ... });
socket.on('foo2', (data, res) => { ... });
socket.on('foo3', (data, res) => { ... });
socket.on('bar1', (data, res) => { ... });
socket.on('bar2', (data, res) => { ... });
...
});
Is there a recommended/built-in way to split these handlers into their own modules?
If not, it would be nice to add a module that does something like express.Router does for Express routes. For example:
// foo-handlers.js
const eventManager = require('socketcluster/event-manager');
eventManager.on('foo1', (data, res) => { ... });
eventManager.on('foo2', (data, res) => { ... });
eventManager.on('foo3', (data, res) => { ... });
module.exports = eventManager;
// bar-handlers.js
const eventManager = require('socketcluster/event-manager');
eventManager.on('bar1', (data, res) => { ... });
eventManager.on('bar2', (data, res) => { ... });
module.exports = eventManager;
// worker.js
const foo = require('./foo-handlers'),
bar = require('./bar-handlers');
scServer.on('connection', socket => {
socket.register(foo);
socket.register(bar);
});
I hacked together a rough attempt at this:
class SCEventManager {
constructor() {
this.handlers = {};
}
on(eventName, callback) {
this.handlers[eventName] = callback;
}
register(socket) {
Object.keys(this.handlers).forEach(eventName => {
socket.on(eventName, this.handlers[eventName]);
});
}
}
module.exports = () => new SCEventManager();
But you have to call foo.register(socket)
instead of socket.register(foo)
:
// foo-handlers.js
const eventManager = require('sc-event-manager')();
eventManager.on('foo1', (data, res) => { ... });
eventManager.on('foo2', (data, res) => { ... });
eventManager.on('foo3', (data, res) => { ... });
module.exports = eventManager;
// worker.js
const foo = require('./foo-handlers');
scServer.on('connection', socket => {
foo.register(socket);
});
There are probably other issues with this design; it would be nice if there were something integrated with Socketcluster that did this. Also, express.Router provides other neat features like per-module routing prefixes and middleware that might be useful in such a feature.
@maxwellhaydn that sound like a good solution to help organize handlers but I think it's better as a separate module because SC shouldn't be too opinionated about code organization (any more than it already is). If you've published such a module to npm, feel free to share it with the community here.