49

Is it possible for a server to connect to another using Socket.IO and be treated like a client?

And have it join rooms, recieve io.sockets.in('lobby').emit(). And more?

The first server is also listening for connections/messages as well.

Hey Brad, here's my full .js app below for reference:

var io = require("socket.io").listen(8099);
io.set('log level', 1);

io.sockets.on("connection", function (socket) {

    console.log('A Client has Connected to this Server');

    //Let Everyone Know I just Joined   
    socket.broadcast.to('lobby').emit("message",'UC,' + socket.id); // Send to everyone in Room but NOT me  


socket.on("message", function (data) {

//Missing code
socket2.send('message,' + data); //Forward Message to Second Server

});

socket.on("disconnect", function (data) {
    //Send Notification to Second Server
    //Need to figure out later

    //Send Notification to Everyone
    socket.broadcast.emit("message",'UD,' + socket.id ); //Send to Everyone but NOT me

    //Remove user from Session ID
    arSessionIDs.removeByValue(socket.id);      

    //Send Notification to Console
    console.log("disconnecting " + arRoster[socket.id][1]);
});

});

var io_client = require( 'socket.io-client' );
var socket2 = io_client.connect('http://192.168.0.104:8090');
socket2.on('connect', function () {
socket2.emit('C3434M,Test');
});
Taurian
  • 1,660
  • 7
  • 20
  • 28
  • Possible duplicate of [Node.js client for a socket.io server](https://stackoverflow.com/questions/10703513/node-js-client-for-a-socket-io-server) – StefansArya Jul 02 '17 at 13:08

3 Answers3

57

Yes, absolutely. Just use the Socket.IO client in your server application directly.

https://github.com/LearnBoost/socket.io-client

You can install it with npm install socket.io-client. Then to use:

var socket = io.connect('http://example.com');
socket.on('connect', function () {
  // socket connected
  socket.emit('server custom event', { my: 'data' });
});
Ates Goral
  • 137,716
  • 26
  • 137
  • 190
Brad
  • 159,648
  • 54
  • 349
  • 530
  • Hey Brad, would it be possible to receive a message socket.on('message'), and then forward that message to the second server using Socket IO? Thanks, -T – Taurian Jan 02 '13 at 07:23
  • Yes, you can use the Socket.IO client server-side the same way you use it client-side. You can do whatever you want with the messages. – Brad Jan 02 '13 at 07:25
  • Ok great, I put up my app, easy to copy/paste and run. Can you help me fill in the blanks? How does connecting to the second server come into play? Thanks, -T – Taurian Jan 02 '13 at 07:51
  • I don't really know what you are asking, or what blanks there are to fill in. When you get a message event raised on your client object, emit the message and data on your server object. Also, there is no reason to send ACK ("message received") emits back. That happens automatically in the background. If you need to perform an action for an ACK, use a callback function. – Brad Jan 02 '13 at 07:59
  • Using the code in the first post. How exactly do you emit the message to the second server. – Taurian Jan 02 '13 at 08:07
  • Nowhere in your code have you connected to that second server yet, so you can't emit a message. You need to connect to that server first with `io.connect()`, and then just do a `.emit()` like you would with any other Socket.IO client. – Brad Jan 02 '13 at 08:12
  • Ok, so what am I missing? Running the code in your example causes an error: TypeError: Object # has no method 'connect' – Taurian Jan 02 '13 at 08:23
  • It's just the example code... since you have your Socket.IO server currently assigned to `io`, you need to do something like `ioClient = require('socket.io-client')`. Then use `var secondServerClient = ioClient.connect()`. Why they picked the same name for both client and server examples, I don't know. – Brad Jan 02 '13 at 08:36
  • Ok that should do it. Thanks. – Taurian Jan 02 '13 at 08:43
18

I realize this is an old post, but I was working on something similar and decided to come back and contribute something as it got me thinking.

Here's a basic Client -> Server 1 -> Server 2 setup

Server #1

// Server 1
var io = require("socket.io").listen(8099); // This is the Server for SERVER 1
var other_server = require("socket.io-client")('http://example.com:8100'); // This is a client connecting to the SERVER 2

other_server.on("connect",function(){
    other_server.on('message',function(data){
        // We received a message from Server 2
        // We are going to forward/broadcast that message to the "Lobby" room
        io.to('lobby').emit('message',data);
    });
});

io.sockets.on("connection",function(socket){
    // Display a connected message
    console.log("User-Client Connected!");

    // Lets force this connection into the lobby room.
    socket.join('lobby');

    // Some roster/user management logic to track them
    // This would be upto you to add :)
    
    // When we receive a message...
    socket.on("message",function(data){
        // We need to just forward this message to our other guy
        // We are literally just forwarding the whole data packet
        other_server.emit("message",data);
    });
    
    socket.on("disconnect",function(data){
        // We need to notify Server 2 that the client has disconnected
        other_server.emit("message","UD,"+socket.id);
        
        // Other logic you may or may not want
        // Your other disconnect code here
    });
});

And here's Server #2

// Server 2
var io = require("socket.io").listen(8100);
io.sockets.on("connection",function(socket){
    // Display a connected message
    console.log("Server-Client Connected!");
    
    // When we receive a message...
    socket.on("message",function(data){
        // We got a message. I don't know, what we should do with this
    });
});

This is our Client, who sends the original message.

// Client
var socket = io('http://localhost');
socket.on('connect', function(){
    socket.emit("message","This is my message");
    
    socket.on('message',function(data){
        console.log("We got a message: ",data);
    });
});

I am making this post a Community Wiki so that someone can improve this if they feel like it.

The code has not been tested, use at your own risk.

peterh
  • 11,875
  • 18
  • 85
  • 108
Destreyf
  • 441
  • 5
  • 7
  • Beautiful man! This got me a rocketship to a socket.io cluster setup. Thank you very much. – Nick Steele Jun 15 '16 at 18:54
  • Let's take it a step further - server(s) implement mDNS to discover who else is on the network. All http/s servers running on some predetermined port broadcast their http/s service to the network. When mDNS detects a new client it automatically attempts to subscribe to it's websocket server as a client. Ideally all servers would see each other and subscribe to each others websockets. If a client emits a websocket, it should work it's way through to all servers and rebroadcast to all clients on those servers. From there you could shape all kinds of interesting services :) – John Oct 02 '20 at 17:21
2

I had the same problem, but instead to use socket.io-client I decided to use a more simple approach (at least for me) using redis pub/sub, the result is pretty simple.

You can take a look at my solution here: https://github.com/alissonperez/scalable-socket-io-server

With this solution you can have how much process/servers you want (using auto-scaling solution), you just use redis as a way to forward your messages between your servers.

  • for me, this is the correct answer. I realize that the question specifically asks for socket.io, but using redis pub-sub is a better way to solve this problem of communicating between 2 distinct processes/servers. +1 – user566245 Feb 29 '20 at 01:11