Using NodeJS to manage multiple paths for WebSocket connections

Greetings, I am currently working on creating a WebSocket server class with multiple paths. I have encountered an issue where the connection Event is successfully emitted when calling the websocket server with a valid path, but the message Event does not seem to be triggered at all. Interestingly, when using the provided code example everything works smoothly; however, with my custom class, only the connection event gets fired. I'm at a loss as to why this discrepancy exists...

Any assistance would be greatly appreciated.

The WebSocket server class

const http = require('http');
const WebSocket = require('ws');
const url = require('url');

class WSServer {
    #server;
    #wsServer = {};
    #ip;
    #port;
  #origin;
  #routes = {};

    constructor(ip, port, origin = null, routes = ['/']) {
        this.#ip = ip;
        this.#port = port;
        this.#origin = origin;
    this.#routes = routes;

        this.#server = http.createServer((request, response) => {
            console.log((new Date()) + ' Received request for ' + request.url);
            response.writeHead(404);
            response.end();
    });
    
    this.#routes.forEach(route => {
      this.#wsServer[route] = new WebSocket.Server({ noServer: true });
    })

        this.#server.listen(this.#port, this.#ip, () => {
            console.log((new Date()) + ' Server is listening on port ' + this.#port);
    });
    
    this.#server.on('upgrade', (request, socket, head) => {
      const pathname = url.parse(request.url).pathname;
      console.log(pathname);
      this.#routes.forEach(route => {
        if (pathname === route) {
          this.#wsServer[route].handleUpgrade(request, socket, head, (ws) => {
            this.#wsServer[route].emit('connection', ws, request);
          });
        } else {
          socket.destroy();
        }
      });
    });
  }

  clients(route = '/') {
        return this.#wsServer[route].connections;
    }

    on(route = '/', event, func) {
        this.#wsServer[route].on(event, func);
    }
}

module.exports = WSServer;

Code example


const WSServer = require('./WSServer');

const wsServer = new WSServer('localhost', '7070', null, ['/db', '/']);

wsServer.on('/', 'connection', function test(conn, req) {
    conn.on('message', msg => {
        console.log(msg);
    })
});

wsServer.on('/db', 'connection', function test(conn, req) {
    conn.on('message', msg => {
        console.log(msg);
    })
});

Answer №1

Issue resolved!

The problem was identified in the route loop of the onupgrade http server event...

Here is the fixed code:

if (this.#wsServer[pathname] !== undefined) {
    this.#wsServer[pathname].handleUpgrade(request, socket, head, (ws) => {
        this.#wsServer[pathname].emit('connection', ws, request);
    });
} else {
    socket.destroy();
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Steps to create a private route in Express:

In my current project, I am utilizing a nodejs/express application as the backend solution. This application incorporates passport-jwt to secure specific routes using JWT as the header Authorization. One of these secured routes, known as secure-route, need ...

The node/express server is throwing an error due to an undefined parameter

What seems to be the issue with my string parameter? var express = require('express'); var app = module.exports = express(); var mongoose = require('mongoose'); var bodyParser = require('body-parser'); var braintree = require ...

Streamlining the Compilation of Dependencies for Electron Application Distribution

I am currently exploring the best method to package and distribute various dependencies (such as node modules and client-side scripts/frameworks like Angular) with my Electron App. While the standard approach of npm install module-name --save is effective ...

What are the steps to activate the hot-swapping feature for HTML and JavaScript files in IntelliJ's Community edition?

Just starting out with IntelliJ to work on an AngularJS project with spring-boot as the backend server. Every time I make changes to my HTML or JavaScript code, I find myself needing to restart the app server. Is there a configuration setting or plugin ava ...

Facing difficulties in initiating Selenium with PhantomJS/GhostDriver as child processes

I am currently working on a Node script that involves using the child_process module in order to run a Selenium server with PhantomJS's GhostDriver. I have imported the module: Child = require "child_process" This is how I am attempting to start the ...

The NPM Install command is failing to download the required dependencies

My current challenge involves the installation of the Ushahidi V3 Client. I have diligently followed the provided installation guide up to the point where I am required to build the project from the source repository using npm and gulp. These tools are com ...

Is it feasible to utilize Google Calendar API for JavaScript through npm install? Alternatively, can the Google Calendar API be utilized for Node.js in the browser within Next.js?

Looking to integrate the Google Calendar API as a library in your Next.js project without using _document.tsx? I have explored two potential approaches for achieving this: Utilize the google calendar api for JavaScript by installing it via npm Use the goo ...

communicating an item between app.js and routes in node.js

Here is the content of my app.js: var express = require('express'); ... var model = require('./models/my_model'); var routes = require('./routes/index'); var app = express(); app.use('/', routes); var middlewar ...

Is it possible to manually download or use an alternative method to install `tmi.js` because the `npm i tmi.js` command is not

Attempting to install tmi.js using the command npm i tmi.js or npm i tmi.js --save is generating warnings and errors. Even after clearing all caches and attempting the download on another computer, I am still facing the same issues. Here is a screenshot o ...

Apologies, but there seems to be an issue with decrypting the digital envelope

I have encountered an issue with decrypting encrypted data stored in a database. The encryption process is working correctly, but when attempting to decrypt the data in order to display it on the front-end, I receive the following error: error:06065064:dig ...

Obtain details regarding a worker's collision

This code snippet is being used to manage cluster crashes within a node application cluster.on('exit', function (worker, code, signal) { console.log("error in cluster",worker); console.log("cluster code",code); console.l ...

Reading cached JSON value in a Node.js application

Recently, I embarked on creating a node.js application and reached a stage where I needed to retrieve a value from an updated JSON file. However, my attempts using the 'sleep' module to introduce a small delay were unsuccessful. I'm relativ ...

Utilizing cheerio to set outerHTML in HTML

Could someone kindly assist me with setting the outerHTML of an element using cheerio? I seem to be encountering some issues with this process. For example, let's consider the following HTML structure: <div class="page-info"> <s ...

Currently, I am working with Angular 11 and encountered some errors while trying to embark on a new project

Command: ng serve Error: Cannot find module '@angular-devkit/build-angular/package.json' View details in "/tmp/ng-lQbnUK/angular-errors.log". These errors occurred when I tried to create the project: Installing packages (npm)... npm WARN depreca ...

Utilize NodeJS to dynamically alter the text outputted on an HTML page

For educational purposes, I am designing a website where users can sign in by entering their name on the login page. After signing in, they will be redirected to the home page which displays a personalized welcome message using their name. I have included ...

How can I incorporate 'virtual' properties into a mongoose schema?

In my document schema, I currently have fields for name, description, and URL: var pageSchema = new Schema({ name: String , desc: String , url: String }) However, I also need to include the HTML source of the page in my application without ...

NodeJS file execution through a stored procedure

Everything I've come across regarding the topic revolves around using a NodeJS program to call a stored procedure. Inquiring: Is it feasible to reverse this process? Can a stored procedure be designed to call/execute a NodeJS file/program instead? I& ...

Can Express handle more than one GET query in a single route?

Currently, I am faced with a small issue that I'm unsure if it's even solvable. I am in the process of developing a website where users can store their contacts. I would like to be able to retrieve a contact by its ID using the URL format /conta ...

When using async functions in iterative processes

In my current setup, I am utilizing a for-each loop to handle a list and specifically require element n to be processed only after element n-1 has completed: let elements = ["item1", "item2", "item3"]; elements.forEach(function(element){ someAsyncFun ...

Creating a new session in Node.js for every request

Our team is currently developing a nodejs application that requires the maintenance of sessions. We have implemented express to handle node variables, but we are facing an issue where a new session is created every time we hit a new service. The structure ...