第一条消息总是出错

Posted

技术标签:

【中文标题】第一条消息总是出错【英文标题】:Always an Error on the First Message 【发布时间】:2011-03-26 05:41:50 【问题描述】:

目前我正在设置一个基本的 WebSockets 脚本。我可以让客户端连接到服务器,但是每当服务器向客户端发送第一条消息时,客户端就会注册并出错,据我所知,readyState 是打开的,并且应该允许消息通过。该消息具有正确的 /x00 和 /xff 开头。我不知道出了什么问题。

编辑:以下是似乎导致错误的代码。 data.js 只是保存了 Python 服务器用来设置服务器的内容,所以当我测试它并且端口还没有超时时,我只需要更改一个文件。

客户端:

<html>
<head>
<script type="text/javascript" src="data.js">
</script>
<script type="text/javascript">
var ws, error
init = function() 
  ws = new WebSocket("ws://127.0.0.1:"+port+"/websockets/main.py")
  ws.onopen = function() 
    console.log("Connected")
    log("Connected")
  
  ws.onmessage = function(e) 
    console.log("Received data")
    log(e.data)
  
  ws.onerror = function(e) 
    console.log(e)
    ws.send("Error occurred. Resend")
  

log = function(msg) 
  document.getElementById("log").appendChild(document.createElement("br"))
  document.getElementById("log").innerHTML = document.getElementById("log").innerHTML+msg

</script>
</head>
<body onload="init()">
<div id="log">
</div>
</body>
</html>

服务器端:

import threading, hashlib, socket, time, re, struct

class WebSocketThread(threading.Thread):
  def __init__(self, channel, details, websocket):
    self.channel = channel
    self.details = details
    self.websocket = websocket
    threading.Thread.__init__(self)

  def run(self):
    print("> Received connection ", self.details[0])
    self.handshake(self.channel)
    while True:
        self.interact(self.channel)

  def finduser(self, client):
    for user in self.websocket.users:
      if user.socket == client:
        return user
        return 0

  def send_data(self, user, data):
    user.socket.send(self.wrap(data))
    print ("> Sent data", data, "to", user)

  def recv_data(self, client, count):
    data = client.recv(count)
    return data

  def handshake(self, client):
    shake = self.recv_data(client, 256)
    our_handshake = self.create_response(shake)
    client.send(our_handshake)
    print ("> Accepted client ", self.finduser(client))
    self.send_data(self.finduser(client), "Test")

  def interact(self, client):
    users = self.websocket.users
    this_user = self.finduser(client)
    data = self.unwrap(self.recv_data(client, 256))
    print ("> Received data ", data, "from", this_user)

  def create_response(self, data):
    key3 = ""
    lines = data.splitlines()
    resource = re.compile("GET (.*) HTTP").findall(data)
    resource = resource[0]
    for line in lines:
      parts = line.partition(": ")
      if parts[0] == "Host":
        host = parts[2]
      elif parts[0] == "Origin":
        origin = parts[2]
      elif parts[0] == "Sec-WebSocket-Key1":
        key1 = parts[2]
      elif parts[0] == "Sec-WebSocket-Key2":
        key2 = parts[2]
      key3 = line
    spaces1 = key1.count(" ")
    spaces2 = key2.count(" ")
    num1 = int("".join([c for c in key1 if c.isdigit()]))/spaces1
    num2 = int("".join([c for c in key2 if c.isdigit()]))/spaces2
    token = hashlib.md5(struct.pack(">II8s", num1, num2, key3)).digest()
    return "HTTP/1.1 101 WebSocket Protocol Handshake\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\nSec-WebSocket-Origin: %s\r\nSec-WebSocket-Location: ws://%s%s\r\nSec-WebSocket-Protocol: sample\r\n\r\n%s\r\n"% (origin, host, resource, token)

  def unwrap(self, data):
    return data[1:-1]

  def wrap(self, data):
    return ("\x00"+data+"\xff")

【问题讨论】:

错误是什么?你能把代码贴出来吗 我无法读取错误。它只是一个错误对象,没有消息或任何东西。你想要代码的哪一部分?客户端还是服务器端? 两者都可能是必要的。 您使用的是哪个客户端/浏览器版本?哪个 WebSockets 服务器?您是否正在修改服务器(这就是您知道消息正确开始和结束的原因)? 我使用的是最新版本的 Google-Chrome。我正在使用一个在发送之前添加每条消息的开头和结尾的函数,因此我知道它已正确发送。我将使用代码编辑原始消息。 【参考方案1】:

尝试删除令牌后的最后一个 \r\n:

return "HTTP/1.1 101 WebSocket Protocol Handshake\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\nSec-WebSocket-Origin: %s\r\nSec-WebSocket-Location: ws://%s%s\r\nSec-WebSocket-Protocol: sample\r\n\r\n%s"% (origin, host, resource, token)

我相信它会解决你的问题:)

【讨论】:

非常感谢。 ^^ 我发誓我见过的所有例子都有它。我正要放弃想办法。我想这是小事。 也遇到了这个问题,搜索了将近一周:D

以上是关于第一条消息总是出错的主要内容,如果未能解决你的问题,请参考以下文章

为啥 kafka 生产者在第一条消息上很慢?

UCWA:发送多条消息时出错

EventSource 在第一条消息后断开连接

Websocket4Net 只接收第一条消息的回复

到特定远程 IP 的第一条 UDP 消息丢失

收到一条错误消息,提示“从“字符串”转换为不相关的类型 NSDictionary 总是失败”。我得到一个线程 1:EXC_BAD_INSTRUCTION