1

これを何時間もいじった後、私は単に解決策を見つけることができません。開発中のキャンバスベースのオンラインゲームに「node.js」を使用してWebSocketサーバーで作業しています。私のゲームはサーバーに問題なく接続でき、ハンドシェイクを受け入れ、サーバーにメッセージを送信することもできます。ただし、サーバーがクライアントに応答するとき、クライアントはメッセージを受け取りません。エラーはありません、何もありません、それはただ平和にそこに座っています。私は自分のコードを分解し、これを修正するために考えられるすべてのことを試みましたが、残念ながら何もしませんでした。

これが私のサーバーコードのストリップコピーです。前に述べたように、ハンドシェイクは正常に機能し、サーバーはデータを正常に受信しますが、クライアントにデータを送り返すことはできません。

var sys = require('sys'),
net = require('net');
var server = net.createServer(function (stream) {
    stream.setEncoding('utf8');
    var shaken = 0;
    stream.addListener('connect', function () {
        sys.puts("New connection from: "+stream.remoteAddress);
    });
    stream.addListener('data', function (data) {
        if (!shaken) {
            sys.puts("Handshaking...");
            //Send handshake:
            stream.write(
            "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"+
            "Upgrade: WebSocket\r\n"+
            "Connection: Upgrade\r\n"+
            "WebSocket-Origin: http://192.168.1.113\r\n"+
            "WebSocket-Location: ws://192.168.1.71:7070/\r\n\r\n");
            shaken=1;
            sys.puts("Handshaking complete.");
        }
        else {
            //Message received, respond with 'testMessage'
            var d = "testMessage";
            var m = '\u0000' + d + '\uffff';
            sys.puts("Sending '"+m+"' to client");
            var result = stream.write(m, "utf8");
   /*
            Result is equal to true, meaning that it pushed the data out.
            Why isn't the client seeing it?!?
            */
        }
    });
    stream.addListener('end', function () {
        sys.puts("Connection closed!");
  stream.end();
    });
});
server.listen(7070);
sys.puts("Server Started!");

これが私のクライアント側のコードです。ChromeネイティブのWebSocketを使用します。

socket = new WebSocket("ws://192.168.1.71:7070");
socket.onopen = function(evt) {
    socket.send("blah");
    alert("Connected!");
};
socket.onmessage = function(evt) {
    alert(evt.data);
};
4

1 に答える 1

4
var m = '\u0000' + d + '\uffff';
var result = stream.write(m, "utf8");

ああ、それは完全に正しくないようです。ゼロバイト、UTF-8エンコード文字列、0xFFバイトの順である必要があります。

\uFFFFUTF-8で0xFFバイトにエンコードしません:0xC30xBFを取得します。実際、UTF-8エンコーディングで0xFFを生成する文字はありません。そのため、WebSocketでターミネータとして選択されました。

私はnode.jsに精通していませんが、次のように言う必要があると思います。

stream.write('\u0000'+d, 'utf-8');
stream.write('\xFF', 'binary');

または、手動でUTF-8エンコードしてバイナリとして送信します。

ハンドシェークも疑わしいですが、それはおそらく現時点であなたのために働いている、可能な限り単純な最初のドラフトだと思います。最初のパケットがハンドシェイクヘッダー全体であり、他には何も依存しておらず、2番目のパケットがペイロードデータであることに依存しています。これはまったく保証されていません。dataヘッダーの終わりに0x0D0x0A0x0D 0x0Aマーカーが表示されるまでバッファーに収集し、ヘッダーの内容を確認して101を返し、そのマーカーの後のデータから続行することをお勧めします。

于 2010-04-29T13:41:25.610 に答える