Sending messages from one Socket.io server to another specific server

I am facing a unique scenario where a client (browser) connects to server A, which in turn is connected to server B and C. When the client sends a message to server A, I need to route that message to a specific server, either B or C, but not both. Essentially, I require isolated communication between servers rather than broadcasting the message to all connected servers.

How can I directly send messages to a single server? Below is my code snippet for setting up connections with the servers by adjusting the port numbers accordingly:

// Loading required modules
var PORT = process.env.PORT || 8080; // Change port based on server
var express = require("express");
var app = express();
var http = require("http").Server(app);
var io = require("socket.io")(http);

app.use(express.static(__dirname + '/public'));

var client = require('socket.io-client');

var socket1 = client.connect('http://localhost:8081', { reconnect: true }); // Connect to server B
var socket2 = client.connect('http://localhost:8082', { reconnect: true }); // Connect to server C

// Establishing connection listener
io.on('connection', function (socket) {
    console.log('Client connected.');
    
    // Listening for message from client
    socket.on('message_from_browser', function (message) {
        console.log("Browser message broadcasted: " + message.text);
        var updated_message = {
           text: message.text,
           port: PORT  
        };

        // Send message to server B
        socket1.emit('server_message', updated_message); 
    });

    // Disconnection listener
    socket.on('disconnect', function () {
        console.log('Client disconnected.');
    });
});

socket1.on('connect', function () {
    socket1.on('server_message', function (message) {
        console.log('RECEIVED MESSAGE FROM SERVER ON PORT '+ message.port + ": " + message.text);
    });
    console.log('Connected to server B!');
});

socket2.on('connect', function () {
    socket2.on('server_message', function (message) {
        console.log('RECEIVED MESSAGE FROM SERVER ON PORT '+ message.port + ": " + message.text);
    });
    console.log('Connected to server C!');
});

http.listen(PORT, function (req, res) {
    console.log("Server Started on port: " + PORT);
});

Answer №1

A conflict arises with the variable name socket. It is used to define both the connection to server B and as an argument in your

.on('connection', function(socket) {...})
callback.

To resolve this, make the following changes:

var socket1 = client.connect('http://localhost:8081', { reconnect: true });//connection to server B
var socket2 = client.connect('http://localhost:8082', { reconnect: true });//connection to server C

Now, refer to the connection to server B as socket1, instead of socket.

The variable named socket is already being used as an argument here, causing a conflict:

// Add a connect listener
io.on('connection', function (socket) {
    console.log('Client connected.');

    //when server receives message from client
    socket.on('message_from_browser', function (message) {
        console.log("Message from browser broadcasted: " + message.text);
        
        var updated_message = {
           text: message.text,
           port: PORT  
        };

        // send message to server B
        socket1.emit('server_message', updated_message);//send message to server B
    });

    // Disconnect listener
    socket.on('disconnect', function () {
        console.log('Client disconnected.');
    });
});

You also need to add listeners for incoming server messages for both socket1 and socket2.

io.on('connect', function(socket1){
    socket1.on('server_message', function (message) {
        console.log('RECEIVED MESSAGE FROM ANOTHER SERVER ON PORT '+ message.port + ": " + message.text);
    });
});

io.on('connect', function(socket2){
    socket2.on('server_message', function (message) {
        console.log('RECEIVED MESSAGE FROM ANOTHER SERVER ON PORT '+ message.port + ": " + message.text);
    });
});

Answer №2

Utilize a single variable and configurations to monitor multiple hosts, give this approach a try:

Revised version addressing various issues:

// Load prerequisites
var PORT = process.env.PORT || 8081; // modify port for alternative servers
var express = require("express");
var app = express();
var http = require("http").Server(app);
var io = require("socket.io")(http);
var async = require('async'); // optional dependency for this scenario ...
var client = require('socket.io-client');

app.use(express.static(__dirname + '/public'));

// store host details here ...
var otherServers = {
  server1: {
    url: 'http://localhost:8082'
  },
  server2: {
    url: 'http://localhost:8083'
  },
};

// Implement a connection listener
io.on('connection', function (socket) {
  console.log('Client connected.');
  
  // when the server receives a message from the client
  socket.on('message_from_browser', function (message) {
      console.log("Message broadcasted from browser: " + message.text);
      var updated_message = {
         text: message.text,
         port: PORT
      };

      // determine how the server will handle this message...
      // then send it
      otherServers.server1.client.broadcast.emit('server_message', updated_message);
  });

  // Disconnection listener
  socket.on('disconnect', function () {
      console.log('Client disconnected.');
  });
});

async.each(otherServers, function forEachOtherServer(otherServer, next) {
  // establish connection with another server
  otherServer.client = client.connect(otherServer.url, { reconnect: true });
  // perform additional operations if required for every client connection ...

  otherServer.client.on('connect', function (x) {

    otherServer.client.on('server_message', function (message) {
        console.log('RECEIVED MESSAGE FROM ANOTHER SERVER ON PORT '+ message.port + ": " + message.text);
        //socket.broadcast.emit('message_from_server', message_server);
    });
    console.log('Connected!');
  });

  next();
}, function afterConnectInAllServers(err) {
  if (err) throw err;
  // execute post-connection tasks on all servers ...
});

http.listen(PORT, function (req, res) {
  console.log("Server Started on port: " + PORT);
});

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

Guide on including a sum (integer) property in the JSON output of my API

Currently, I am working on an API using Express.js. In one of my functions named getAll, my goal is to not only return an array of records but also include the total number of records in the response. The code snippet below showcases how I have been handli ...

Missing data: Node JS fails to recognize req.body

I've looked through various posts and I'm feeling quite lost with this issue. When I run console.log(req), the output is as follows: ServerResponse { ... req: IncomingMessage { ... url: '/my-endpoint', method: &a ...

Creating animated reactions in discord.js is a goal of mine, however, I am encountering an issue that needs to

Last year, I asked this question and received helpful answers. However, there is still a problem that I couldn't figure out. Since I am unable to comment on the previous answers, I have decided to add a new question client.on('message', mess ...

Invoke the express function on the client using the callable method

When I'm listening on a local port with my browser, the following method will return Hello world. //Node app.get('/', (req,res)=>{ res.send('Hello world') }); I've successfully exported the app as a ca ...

Tips for maintaining a user's session post-login with Passport and Express JS

I recently set up a node backend using express and integrated Passport for authentication purposes. My application has a route called /login for logging in and another route called /me to retrieve information about the currently logged in user. Below is t ...

Is it possible to execute JavaScript code (using Node.js) through AppleScript on MAC OS?

After downloading Node.js for MAC OS from this link: http://nodejs.org/download/ (http://nodejs.org/dist/v0.10.29/node-v0.10.29.pkg), I needed to execute a JavaScript on Google Chrome. To do this, I utilized the following AppleScript code: do shell script ...

"Mastering the art of traversing through request.body and making necessary updates on an object

As I was reviewing a MERN tutorial, specifically focusing on the "update" route, I came across some interesting code snippets. todoRoutes.route('/update/:id').post(function(req, res) { Todo.findById(req.params.id, function(err, todo) { ...

Integrate your React Native application with a Node.js backend on your local machine

My attempt to establish a connection between my react native app and my node.js app on a Windows system has hit a roadblock. While I am able to receive responses from the node API using Postman, the response from the react native app is coming back as unde ...

Modify information on the user interface without the need to refresh the page

Is there a way to update data on the UI without having to refresh the screen in a web application built with Node.js? I'm looking to make only specific changes on the screen. Additionally, how can I ensure that the data displayed on the screen is upda ...

The node experiences a crash when the redis-server goes offline

Struggling with a persistent issue here. Despite reading numerous documents and posts from others on the same topic, I can't seem to find a solution to prevent this problem. I am intentionally shutting down the redis server to avoid potential disaster ...

Building a simple messaging platform with the power of Socket.io and Node.js

After following the guide at http://socket.io/get-started/chat/, I attempted to create a basic chat application. However, upon running npm install --save socket.io I encountered the error message below. How can I resolve this issue? npm WARN package.jso ...

Issue when attempting to update user profile picture using Mongoose schema and Cloudinary

updateProfile: async function(req, res) { try { const update = req.body; const id = req.params.id; if (!req.files || Object.keys(req.files).length === 0) { return res.status(400).send('No files were uploaded.&a ...

Create a search feature based on names utilizing Node Express in conjunction with SQL database

After deciding to create an API with a search feature using SQL queries in node express, this is how I structured my code: app.get('/search/:query', (req, res) => { pool.getConnection((err, connection) => { if(err) throw err ...

Currently using Mongoose and Luxon to showcase the event date, however, I am encountering an issue where the displayed date is one day earlier than expected

Currently, I am working with Mongoose and Luxon to present a date chosen by the user from a form. However, there seems to be an issue where the date is being console logged as one day, but appearing on the page as the previous day. Below is my model setup ...

Unexpected token error occurs when making cross-domain AJAX requests to the server and receiving a JSON object

I have set up an express server to handle get requests to specific url endpoints. When responding to these requests, I am sending back data in JSON format to enable making Ajax calls and retrieving data from the page. To allow for cross-domain requests, I ...

I would prefer not to add another database table just to differentiate between team members and friends. Can you provide assistance with this?

Instead of creating another table named friends in Strapi and linking it to Visual Studio Code, I have opted to use a Characters table for both team members and friends. This way, I can input new data only at Characters and filter it to differentiate betwe ...

Capturing an error within an asynchronous callback function

I am utilizing a callback function to asynchronously set some IPs in a Redis database. My goal is to catch any errors that occur and pass them to my error handling middleware in Express. To purposely create an error, I have generated one within the selec ...

Retrieving information from a virtual document in a 'pre' save hook using Mongoose

Seeking help with utilizing data from a recently created document to update a value using a 'pre' hook. An example of the model being used: ... title: { type: String, required: true }, company: { type: mongoose.Schema.ObjectId, ref: &ap ...

Extracting Unprocessed Data with Node.js Express

I am currently working with an Express server that handles a login form page: const app = express(); // part A app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.urlencoded()); app.get('/login', ...

How can Vue define the relationship on the client-side when submitting a post belonging to the current user?

Currently, I am developing an application using Node.js, specifically Express server-side and Vue client-side, with SQLite + Sequelize for managing the database. One of the features of this app is that a user can create a post. While this functionality ex ...