I'm fairly new to Nodejs & trying to get my head around ES6 Classes & keeping things encapsulated , but also being able to reference functions in the class.
I'm writing a wrapper around one of the websockets classes and trying to map a function defined inside the websocket connection function to a function defined in the class. ( see the init function where I explain ) . I do understand why it fails , but I don't know how to make it reference the function in the class.
So question is: how do I reference or "inject" a function defined in a class to an embedded function ( which has a different context ) , and is there a best practice for this. Note: This is different to How to access the correct this
inside a callback?
in the following regards ( or I need help understanding the application ) :
1) It is using a class , so we can't currently declare a variable unless we set it using "this.variable = somevalue" ( which defeats the whole purpose of referencing "this" ).
2) If I use arrow functions , like this:
this.socketServer.on('connection', (ws) => {
ws.on('message', () => this.receiveMessage)
ws.send('socket open')
});
* Solved *
const boundReceiveMessage = this.receiveMessage.bind(this)
this.socketServer.on('connection', (ws) => {
ws.on('message', boundReceiveMessage)
ws.send('socket open')
});
when I am referencing ws.on('message'.. , the scope of this is not the class - it is the actual webscocket itself - which makes sense - but I can't figure out how to reference the class defined function there.
My gut feeling is that I am doing something fundamentally wrong in my structure - and that possibly the event emitters might be incorrectly instantiated.
I appreciate you helping my solve this , and if you can point me to a better way of doing all this it would be appreciated as well.
'use strict'
const WebSocket = require('ws')
const EventEmitter = require('events')
const eventEmitter = new EventEmitter()
class WebsocketServer{
constructor(){
this.openSocket = openSocket
this.socketServer = {}
this.broadcastMessage = broadcastMessage
this.receiveMessage = receiveMessage
this.init = init
}
}
async function init(){
await this.openSocket()
await this.socketServer.on('connection', function connection(ws) {
//the following line fails because "this" is not the context of the class
ws.on('message', this.receiveMessage)
ws.send('socket open')
})
}
function openSocket(portNumber){
this.socketServer = new WebSocket.Server({ port: portNumber==undefined ? 8080 : portNumber })
}
function broadcastMessage(message){
this.socketServer.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(message)
}
})
}
function receiveMessage(data){
console.log(`Received socket Message: ${data}`)
eventEmitter.emit('dataReceived',data)
}
module.exports = WebsocketServer