【问题标题】:Why Won't the WebSocket.onmessage Event Fire?为什么 WebSocket.onmessage 事件不会触发?
【发布时间】:2010-04-29 08:52:52
【问题描述】:

在玩了几个小时之后,我根本找不到解决方案。我正在为我正在开发的基于画布的在线游戏使用“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 原生 WebSockets。

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

【问题讨论】:

  • 什么是客户端? Chrome 原生 WebSocket 构建? Flash 套接字后备?
  • 我对其进行了编辑并添加了客户端代码。对不起,我真的很累嘿。

标签: javascript canvas node.js websocket multiplayer


【解决方案1】:
var m = '\u0000' + d + '\uffff';
var result = stream.write(m, "utf8");

啊,好像不太对劲。它应该是一个零字节,后跟一个 UTF-8 编码的字符串,然后是一个 0xFF 字节。

\uFFFF 不会以 UTF-8 编码为 0xFF 字节:你得到 0xC3 0xBF。事实上,任何字符都不会在 UTF-8 编码中产生 0xFF:这就是为什么它被选为 WebSocket 中的终止符。

我对 node.js 不熟悉,但我猜你需要这样说:

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

或手动 UTF-8 编码并以二进制形式发送。

握手也是有问题的,但我想这是一个尽可能简单的初稿,目前可能对你有用。您依赖第一个数据包是整个握手标头,仅此而已,然后第二个数据包是有效负载数据。这根本无法保证。您可能希望在缓冲区中收集data,直到看到标头末尾的 0x0D 0x0A 0x0D 0x0A 标记,然后检查标头内容并可能返回 101,然后从该标记之后的数据继续。

【讨论】:

  • 哇哦,这么简单的解决方案!非常感谢!我已经拉了几个小时的头发试图解决这个问题!正如你所说,握手只是一个临时的、尽可能简单的初稿,我以后会做一个更好的。再次感谢一百万!
猜你喜欢
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 2017-12-08
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
  • 2020-02-06
相关资源
最近更新 更多