16

同じポートでtcphttp、およびwebsocket.io通信を有効にしようとしています。私はtcpサーバー(////行の上の部分)から始めましたが、うまくいきました。次に、websocket.io (//// 行の下の部分) にあるエコー サーバーの例を実行しましたが、これも機能しました。しかし、それらをマージしようとすると、tcp が機能しなくなります。

SO、tcp、http、および websockets をすべて同じポートを使用して有効にすることは可能ですか? それとも、tcp 接続のために別のポートでリッスンする必要がありますか?

var net = require('net');
var http = require('http');
var wsio = require('websocket.io');

var conn = [];

var server = net.createServer(function(client) {//'connection' listener
    var info = {
        remote : client.remoteAddress + ':' + client.remotePort
    };
    var i = conn.push(info) - 1;
    console.log('[conn] ' + conn[i].remote);

    client.on('end', function() {
        console.log('[disc] ' + conn[i].remote);
    });

    client.on('data', function(msg) {
        console.log('[data] ' + conn[i].remote + ' ' + msg.toString());
    });

    client.write('hello\r\n');
});

server.listen(8080);

///////////////////////////////////////////////////////////

var hs = http.createServer(function(req, res) {
    res.writeHead(200, {
        'Content-Type' : 'text/html'
    });
    res.end(['<script>', "var ws = new WebSocket('ws://127.0.0.1:8080');", 'ws.onmessage = function (data) { ws.send(data); };', '</script>'].join(''));
});

hs.listen(server);

var ws = wsio.attach(hs);
var i = 0, last;

ws.on('connection', function(client) {

    var id = ++i, last

    console.log('Client %d connected', id);

    function ping() {
        client.send('ping!');
        if (last)
            console.log('Latency for client %d: %d ', id, Date.now() - last);
        last = Date.now();
    };

    ping();
    client.on('message', ping);

});
4

2 に答える 2

31

同じポートで複数の異なるプロトコルを処理できますが、いくつかの注意事項があります。

  • クライアントが話したいプロトコルをサーバーが検出 (またはネゴシエート) する何らかの方法が必要です。個別のポートは、クライアントが話したいプロトコルを検出する通常の方法と考えることができます。

  • 実際にポートをリッスンできるサーバー プロセスは 1 つだけです。このサーバーは、プロトコルのタイプを検出してから他の複数のサーバーに転送するという目的のみを果たしますが、各ポートは単一のサーバープロセスによって所有されます。

  • サーバーが最初に話す複数のプロトコルをサポートすることはできません (クライアントのプロトコルを検出する方法がないため)。複数のクライアント ファースト プロトコルを使用して単一のサーバー ファースト プロトコルをサポートすることはできますが (クライアントがデータを送信するかどうかを確認するために、受け入れ後に短い遅延を追加することによって)、それは少し不安定です。

WebSocket プロトコルの明確な設計目標は、WebSocket と HTTP プロトコルが同じサーバー ポートを共有できるようにすることでした。最初の WebSocket ハンドシェイクは、HTTP 互換のアップグレード リクエストです。

websockifyサーバー/ブリッジは、同じポートで 5 つの異なるプロトコルを使用できるサーバーの例です: HTTP、HTTPS (暗号化された HTTP)、WS (WebSockets)、WSS (暗号化された WebSocket)、および Flash ポリシー応答。サーバーは、着信要求の最初の文字を調べて、TLS 暗号化されているか (HTTPS または WSS)、または「<」で始まっているか (Flash ポリシー要求) を判断します。Flash ポリシー要求の場合は、要求を読み取り、応答して接続を閉じます。それ以外の場合は、HTTP ハンドシェイク (暗号化されているかどうかに関係なく) を読み取り、Connection ヘッダーと Upgrade ヘッダーによって、それが WebSocket 要求かプレーン HTTP 要求かが判断されます。

免責事項: websockify を作成しました

于 2012-12-10T16:54:26.907 に答える
0

簡単な答え-いいえ、同じポートで異なるTCP / HTTP/Websocketサーバーを実行することはできません。

長い答え-WebSocketとHTTPの両方がTCP上で機能します。したがって、httpサーバーまたはWebSocketサーバーをカスタムTCPサーバーと考えることができます(いくつかの状態管理とプロトコル固有のエンコード/デコードを使用)。マシン上の同じポート/プロトコルペアに複数のソケットをバインドすることはできないため、最初のソケットが優先され、次のソケットはソケットバインドの例外を取得します。

于 2012-12-10T08:08:09.173 に答える