2016-03-19 188 views
1

我有一个特定的情况。我有连接到服务器A的客户端(浏览器)。服务器A连接到服务器B和C.当客户端向服务器A发送消息时,我需要将消息发送到特定服务器,这意味着服务器B或C之一,而不是两个都。一般来说,我需要在服务器之间进行分离通信,但我只能广播通信。从服务器A到另一台服务器的消息不能在所有连接的服务器上看到。Socket.io服务器到服务器(发送消息到特定服务器)

如何将消息直接发送到其中一台服务器?这是我的服务器代码片段。我只是更改每个服务器的端口并连接它们。

// 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); 
}); 
+0

我也许不明白这个问题,因为答案看起来很简单,因为您只将消息发送到所需的服务器。如果你有socket.io连接到服务器B和服务器C,并且一个传入消息应该只发送给服务器B,那么你得到了连接到服务器B的套接字,并且你执行'socket.emit()'只有那个插座。这将只将消息发送到该连接。如果服务器A启动了到服务器B和服务器C的连接,那么您已经知道哪个连接是哪个连接。 – jfriend00

+0

如果服务器B和服务器C连接到您,那么您需要他们确定他们连接时哪一个,以便您可以跟踪哪个是哪个。 – jfriend00

+0

非常感谢您的建议。我已经尝试过你的解决方案,但是当我创建2个套接字,然后,当我发送消息,如socket.emit('server_message',updated_message);或者socket2.emit('server_message',updated_message);这不起作用,当我试图发送像socket.emit('server_message',updated_message)这样的消息时,这个消息也发送到socket2。当你在第二条评论中输入时,我也尝试过使用套接字标识跟踪服务器,但它也不起作用。 – mattafix19

回答

1

您有变量名socket命名冲突。它被定义为您与服务器B的连接并作为您的.on('connection', function(socket) {...})回调中的参数。

为了解决这个问题,改变这种:

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 

要这样:

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 

而且,当时指的是服务器B连接,socket1,不socket

命名socket变量已经被定义为这样的一个说法,所以你无法到达外socket变量时,它有一个名称冲突:

// 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.'); 
    }); 
}); 

并有传入服务器的消息,所以你不需要听众为socket1socket2添加侦听器。

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); 
    }); 
}); 
+0

我试过你的修复,但似乎第二台服务器没有正确接收消息。我已经调试过它,并且消息似乎正确发送,但另一台服务器不显示任何消息。 – mattafix19

+0

@ mattafix19 - 除非您向我们展示当前的发送和接收消息代码,否则我们无法帮助您解决此问题。使用正确时,Socket.io工作得很好。 – jfriend00

+0

对不起。我完全理解,但我的代码是相同的,但唯一不同的是你建议的修复。此代码提供用于发送和接收。再次非常感谢你的时间。 – mattafix19

-1

使用一个变量和CONFIGS跟踪别人的主机,尝试:

更新修复了一些bug:

// 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); 
}); 
+0

谢谢你的帮助。其实我无法让你的代码工作。我无法建立服务器之间的连接。当我尝试从浏览器转发消息时,我在'otherServers.server1.client.broadcast.emit('server_message',updated_message);'line,'socket'上缺少错误处理程序时出错。 TypeError:无法读取未定义的属性'broadcast' – mattafix19

+0

使用console.log('otherServers');查看所有连接的服务器。 我更新了这个示例代码来修复一些错误 –

+0

非常感谢您的快速解答。我在你的代码中看到你已经创建了'async.each(otherServers,forEachOtherServer(otherServer,next)的函数{'。这意味着你为对象'otherServers'中的每个服务器建立连接,不是吗? ...做一些事情其实我仍然有错误,因为在上次评论中,似乎我没有在服务器之间创建连接,所以我需要的是我正在使用CDN网络适配器,并且需要创建通信但是消息必须直接发送到选定的服务器 – mattafix19