mattafix19
mattafix19

Reputation: 55

Socket.io server to server (sending message to specific server)

I have a specific situation. I have client (browser) which connects to server A. Server A is connected to server B and C. When client sends message to server A, I need to send message to specific server which means to one of the servers B or C, not both of them. Generally I need separated communication between servers but I have only broadcasted communication. Message from server A to another server can't be seen on all connected servers.

How can I send messages directly to one of the servers ? Here is my code snippet for servers. I just change ports for each server and connect them.

// Load requirements
var PORT = process.env.PORT || 8080;//just change port for other servers
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 });//connection to server B
var socket2 = client.connect('http://localhost:8082', { reconnect: true });//connection to server C

// Add a connect listener
io.on('connection', function (socket) {
    console.log('Client connected.');
//when server receive 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.');
    });
});

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

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

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

Upvotes: 2

Views: 3988

Answers (2)

jfriend00
jfriend00

Reputation: 707328

You have a naming conflict with the variable name socket. It is defined as both your connection to server B and as an argument in your .on('connection', function(socket) {...}) callback.

To fix that, change this:

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

To this:

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

And, then refer to the server B connection as socket1, not socket.

The variable named socket is already defined as an argument in this so you cannot reach the outer socket variable when it has a conflicting name:

// Add a connect listener
io.on('connection', function (socket) {
    // socket variable name   ^^^^^^
    console.log('Client connected.');
//when server receive 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.');
    });
});

And there were no listeners for incoming server messages so you need to add listeners for 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);
    });
});

Upvotes: 2

Alberto Souza
Alberto Souza

Reputation: 681

Use one variable and configs to track others hosts, try:

Updated to fix some bugs:

// Load requirements
var PORT = process.env.PORT || 8081;//just change port for other servers
var express = require("express");
var app = express();
var http = require("http").Server(app);
var io = require("socket.io")(http);
var async = require('async'); // async is optional for this example ...
var client = require('socket.io-client');

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

// save hosts here ...
var otherServers = {
  server1: {
    url: 'http://localhost:8082'
  },
  server2: {
    url: 'http://localhost:8083'
  },
};

// Add a connect listener
io.on('connection', function (socket) {
  console.log('Client connected.');
  //when server receive 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
      };

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

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

async.each(otherServers, function forEachOtherServer(otherServer, next) {
  //connect to another server
  otherServer.client = client.connect(otherServer.url, { reconnect: true });
  // to something more if need in 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;
  // to something after connect in all servers ...
});

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

Upvotes: 0

Related Questions