2016-03-19 238 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