0

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
Martin Thompson
  • 3,415
  • 10
  • 38
  • 62
  • You can define those methods in the class instead of assigning them in the constructor, by the way. – Ry- Mar 15 '18 at 05:07
  • thanks so much for your time @Ryan , I have edited this as I think it is different to the post you have referenced in a couple of respects ( or I can't figure out how to use it in my scenario ) – Martin Thompson Mar 15 '18 at 17:44
  • @Ryan never mind , I found the solution in your referenced post and put it in the post here. thanks again! – Martin Thompson Mar 15 '18 at 17:57

0 Answers0