Reputation: 48769
I'm running a WebSocket server with ws
, and am trying to split incoming messages based on whether they are JSON or not.
function determineJSON(m) {
try { return ['json', JSON.parse(m)] }
catch (err) { return ['not-json', m] }
}
wss.on('connection', ws => {
ws.on('message', m => {
// Emit to 'json' and 'not-json' as appropriate
if (ws.listenerCount('json') + ws.listenerCount('not-json') > 0) {
ws.emit(...determineJSON(m))
}
})
.on('json', j => { ... })
.on('not-json', m => { ... })
})
The code works great, but I was wondering how I could add the .on('message', ...)
listener to the WS
class, so that all new WS
objects would have it. I tried WS.prototype.on('message', ...)
, but that didn't seem to do anything.
Upvotes: 0
Views: 111
Reputation: 493
So actually you want creating instances of WS with predefined state?
For that purpose I would suggest you just to create a factory which would handle it for you.
WsFactory.create = function () {
var ws = new WS(); //or whatever you use for creating
ws.on(...);
return ws;
}
You would avoid mutating prototypes, and would get what you want to have.
Upvotes: 1
Reputation: 19581
Well I'm not a big fan of modifying the prototype, so you can do something like :
function determineJSON(m) {
try { return ['json', JSON.parse(m)] }
catch (err) { return ['not-json', m] }
}
function decorateWS(ws) {
return ws.on('message', m => {
// Emit to 'json' and 'not-json' as appropriate
if (ws.listenerCount('json') + ws.listenerCount('not-json') > 0) {
ws.emit(...determineJSON(m))
}
})
}
wss.on('connection', ws => {
decorateWS(ws).on('json', j => { ... })
.on('not-json', m => { ... })
})
Anyway if you want to modify the class itself you will probably need to do something like :
let origConstructor = ws.prototype.constructor;
WS.prototype.constructor = () => {
origConstructor.apply( this, arguments );
const ws = this;
this.on('message', m => {
// Emit to 'json' and 'not-json' as appropriate
if (ws.listenerCount('json') + ws.listenerCount('not-json') > 0) {
ws.emit(...determineJSON(m))
}
})
}
In any case I think this might have side effects. So the decorate approach looks far better and maintainable.
Upvotes: 0