Ws: Help wanted: Object Oriented Server and Client

Created on 26 Jul 2019  路  8Comments  路  Source: websockets/ws

So, as the title suggests, this is not really a big issue with things not working, but rather a request for help in getting my project to be more Object Oriented since the obvious way of handling the events does not work.
The fact you can attach a function to these events implies one should be able to also attach a class method to it. This is not the case however.

Most occurring errors I've encounter trying to get this to work are: _method is not a function_ and _cannot call x from undefined_

Right now my server class looks terrible with code like:

wss.on('connection', function connection(ws, request) {
// Some stuff my code does when a client connects
    ws.on('message', function (message) {
        // some stuff my code does when a client sends a message to the server
    }

I'd rather have it be that my Server class has code like this:

class Server {
   constructor() {
     //constructor code
   }

   Start() {
      // Start WebSocket Server
   }

   // Event Handlers
   OnConnection(params)

   OnError(params)

   OnHeaders(params)

   OnListening(params)

   OnEvent(params)
}

_(params are the parameters/arguments _ that need to be passed along with the event (eg. ws and request for OnConnection)_

I'd like to have a similar thing going for the Client (both the ws inside of Server as well as the code where a client connects to a server).

I have tried to do things along the lines of

wss.on('connection', this.OnConnection(ws, request));
OnConnection(ws, request) {
// Stuff happens here
}

however, things stop working properly or at all in those sub levels, especially if I attach ws to a different class called ServerClient.

I am unsure how to properly implement your library as wel as keep my methods and functions clean and as close to OOP as possible.
Do I need to extend your code? And if so, how do I make sure my extended class still works (eg the client, I do not want the client to make a connection on creation since I let it access an authentication page first to get a token used in the verifyClient option when creating the WebSocket.Server

Thanks in advance for any advice and/or tips

ps: my current code works just fine, I am just dissatisfied with how the code is set up.

Edit: corrected the markdown
Edit 2: Rewrote my question to avoid misinterpretation

All 8 comments

So, as the title suggests, this is not really an issue with things not working, but rather a request for help in getting my project to be more Object Oriented.

If it's not an issue then

So, as the title suggests, this is not really an issue with things not working, but rather a request for help in getting my project to be more Object Oriented.

If it's not an issue then

It's still somewhat an issue, since you are able to attach a function to the events, one would assume you can use an existing function within your class/scope do handle it for you, which it does on the first level, but as soon as you try to attach the ws (which also has events that can be handled by methods inside your class) to a class called Client and attach it there, the whole thing breaks and it is unable to do anything, it's not recognizing itself, requests come through as undefined, etc...

The only reason I say it's not really an issue is that as long as you don't try and split off the functionality and do everything in nested functions

Start() {
   wss.on('connection', function connection(ws, request) {
      ws.on('message', function (message) {

      });
  });
}

The above works perfectly fine

   Start() {
     wss.on('connection', this.OnConnection);
   }

   OnConnection(ws, request) {
        var client = new Client();
        ws.on('message', client.OnMessage);
        client.ws = ws;
   } 

client.js

class Client {
    constructor() {
        this.ws;
    }

    OnMessage(message) {
        console.log(message);
    }

    Send(message) {
        this.ws.send(message);
    }
}

The above does not work, Client does not work as intended and is unable to recogniwe ws within Send (at least it was for me) and would not be able recognize message in OnMessage either.

In my eyes this is still an issue, just not a code breaking one, it's not a bug as far as I am aware, unless I am doing something completely wrong with my code it seems unlikely to move functionality outside the scope of wherever wss is declared.

If this is a bug since the author intended for this to be possible, I'd love a fix, if it isn't a bug, it's more of a feature request, and if it can't be neither, it's asking how to extend the library within my own project without breaking what's already there. Albeit I may have misphrased my earlier comment... And I get the confusion

As @rgawenda said this issue tracker is only for bugs and feature requests. You are asking for general support, specifically how to wrap ws in your own interface. It can be done easily. Take a look at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions.

As @rgawenda said this issue tracker is only for bugs and feature requests. You are asking for general support, specifically how to wrap ws in your own interface. It can be done easily. Take a look at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions.

My apologies for not knowing this, I am normally a C#.Net dev but due to reasons was forced to start learning and developing in NodeJS... This language just feels so dirty to me, I had no clue something like that was even possible, nor did I find either of those articles when searching for a solution to my issue before making this ticket.

I'd still like to thank you for replying with a solution.

No problem.

Just wanted to let you know it is working like a charm!

16:06:54.600 [WebSocket Server]: WebSocket Server is now running and listening to port 1337
16:06:56.962 [HTTPS Server]: URL Accessed: /auth
16:06:56.985 [WebSocket Server]: Client connected.
16:06:58.540 [WebSocket Server]: Message Received.
16:06:58.649 [Router]: Container received
16:06:58.650 [Queue]: Container Added to Queue (Total: 1)
16:06:58.655 [Router]: Routing Started:
16:06:58.704 [Queue]: Package Resolved (Total Containers Left: 1)
16:07:30.786 [WebSocket Server]: Client [[email protected]] Disconnected with Code: 1006 Connection Terminated Abnormally

@sneels : Can you post your code snippet for reference?

this._https.on('listening', (this.OnListening).bind(this));
by doing something like this you get to use the same object and the function you created for it, instead of the interpreter thinking it's a new object.

Was this page helpful?
0 / 5 - 0 ratings