0

スケーラブルな Web ソケット サーバーが必要なため、node-http-proxy の評価を開始しました。

リポジトリで提供されている「simple-balancer-with-websockets」の例をテストしましたが、複数のアドレスへのプロキシとして機能する場合は機能しません。1 つのアドレスのプロキシとしてのみ機能します。

複数のアドレスにプロキシすると、次のような WebSocket ハングアップ エラーが発生します。

Error: socket hang up
    at createHangUpError (http.js:1472:15)
    at Socket.socketOnEnd [as onend] (http.js:1568:23)
    at Socket.g (events.js:180:16)
    at Socket.EventEmitter.emit (events.js:117:20)
    at _stream_readable.js:920:16
    at process._tickCallback (node.js:415:13)

私は使っている:

ノード 0.10.26 ソケット io 1.0.6 ノード HTTP プロキシ 1.1.5 プラットフォーム OSX

以下はロードバランサです。提供されたサンプルとの唯一の違いは、使用されるアドレスとリッスン ポートです。

var http = require('http'),
    httpProxy = require('http-proxy');

//
// A simple round-robin load balancing strategy.
// 
// First, list the servers you want to use in your rotation.
//
var addresses = [
    {
        host: 'localhost',
        port: 8000
    },
    {
        host: 'localhost',
        port: 8001
    },
    {
        host: 'localhost',
        port: 8002
    }
];

//
// Create a HttpProxy object for each target
//

var proxies = addresses.map(function (target) {

  return new httpProxy.createProxyServer({
    target: target
  });
});

//
// Get the proxy at the front of the array, put it at the end and return it
// If you want a fancier balancer, put your code here
//

function nextProxy() {
  var proxy = proxies.shift();
  proxies.push(proxy);
  return proxy;
}

// 
// Get the 'next' proxy and send the http request 
//

var server = http.createServer(function (req, res) {    
  nextProxy().web(req, res);
});

// 
// Get the 'next' proxy and send the upgrade request 
//

server.on('upgrade', function (req, socket, head) {
  nextProxy().ws(req, socket, head);
});

server.listen(9000);

上記のロードバランサーのターゲットとして機能する基本的な http サーバーは次のとおりです。

var http = require('http'),
    fs = require('fs'),
    io = require('socket.io');

var args = process.argv.splice(2);

var port = args[0] || 8000;

server = http.createServer(function(req, res) {

    var filePath = (__dirname + '/public/connect.html');

    fs.readFile(filePath,function (err, data){
        res.writeHead(200, {'Content-Type': 'text/html','Content-Length':data.length});
        res.write(data);
        res.end();
    });
});

server.listen(port, function() {

    console.log('ws listening on: ' + port);

});

io = io(server);

io.on('connect', function(socket){

   console.log('socket connected');

    socket.emit('message', 'ws message from ' + port);
});

クライアントのhtmlは次のとおりです。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>

    <script src="/socket.io/socket.io.js"></script>
    <script>
        var socket = io();

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

                console.log(data);
            });

    </script>

</head>
<body>
node-http-proxy basic load balance test with websockets
</body>
</html>

これは基本的なテストだと思いますが、うまくいきません! 誰かが私が間違っていることを説明し、解決策を提案してもらえますか?

ご意見ありがとうございます。

4

1 に答える 1

2

Socket.io 1.0 にはスティッキー セッションが必要です。socket.io/docs/using-multiple-nodes を参照してください

最初に engine.io が xhr リクエストを作成し、次に websocket リクエストを作成します。両方のリクエストが同じ socket.io サーバーに到達する必要があります。engine.io が長いポーリングなどにフォールバックする必要がある場合はなおさらです。. .

これを修正するには、プロキシ サーバー セッションを認識させる必要があります。新しい接続をラウンドロビンすることはできますが、socket.io リクエストを処理するとすぐに、そのセッションからの後続のリクエストを同じバックエンドにルーティングする必要があります。

于 2014-07-22T21:50:02.963 に答える