Websocket 连接因错误“收到意外的延续帧”而关闭。

Posted

技术标签:

【中文标题】Websocket 连接因错误“收到意外的延续帧”而关闭。【英文标题】:Websocket connection closed with an error "Received unexpected continuation frame." 【发布时间】:2015-03-11 07:01:08 【问题描述】:

我只是想使用 WebSockets。我用python编写了服务器代码。服务器运行正常,但是当尝试使用浏览器连接到套接字时,我收到了错误

“到 'ws://localhost:9876/' 的 WebSocket 连接失败:已接收 意外的延续框架”

当在互联网上提及时,我理解它与从服务器发送的数据的框架有关。我在发送数据时尝试遵循these (rfc6455) 标准,即使我无法实现 websocket 连接。几乎类似的问题被问到here,但这是一个旧帖子,解决方案也不清楚。

这是我非常简单的服务器代码..

import socket

def handle(s):
    print repr(s.recv(4096))
    
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
s.bind(('',9876))
s.listen(2)

handshakes='\
HTTP/1.1 101 Web Socket Protocol Handshake\r\n\
Upgrade: WebSocket\r\n\
Connection: Upgrade\r\n\
Sec-WebSocket-Origin: null\r\n\
Sec-WebSocket-Location: ws://localhost:9876/\r\n\
'
def handshake(hs):
    hslist = hs.split('\r\n')
    body = hs.split('\r\n\r\n')[1]
    key = ''
    cc = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'

    for h in hslist:
        if h.startswith('Sec-WebSocket-Key:'):
            key = h[19:]
        else:
            continue

    import hashlib
    import base64
    s = hashlib.sha1()
    s.update(key+cc)()
    h = s.digest()
    return base64.b64encode(h)

def sender(data, conn):
    first_byte = chr(0x00)
    payload = data.encode('utf-8')
    pl = first_byte + payload + chr(0xFF)
    conn.send(pl)

while True:
    c,a = s.accept()
    msg = c.recv(4096)
    if(msg):

        print msg
        print 'sending handshake ...'
        handshakes += 'Sec-WebSocket-Accept: '+str(handshake(msg))+'\r\n\r\n'
        print handshakes
        c.send(handshakes)
        sender("Hello", c)
        break;

还有html,index.html

 <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Web Socket Example</title>
    <meta charset="UTF-8">
    <script>
      window.onload = function() 
        var s = new WebSocket("ws://localhost:9876/");
        s.onopen = function(e)  alert("opened"); 
        s.onclose = function(e)  alert("closed"); 
        s.onmessage = function(e)  alert("got: " + e.data); 
      ;
    </script>
  </head>
    <body>
      <div id="holder" style="width:600px; height:300px"></div>
    </body>
</html>

我正在像这样运行这段代码..

./server.py & python -m SimpleHTTPServer 8888

运行服务器后,当我使用浏览器点击 localhost:8888 时,它会提示“已打开”(表示握手已完成),同时提示“已关闭”(连接已关闭)并在控制台上显示上述错误。

不太清楚如何调试这个问题。

我正在使用浏览器 Chrome(版本:41)、Python 2.7、Websocket 13。

【问题讨论】:

听起来您可能遇到了 webSocket 框架错误。我建议您查看网络嗅探器并比较浏览器如何与您的 webSocket 服务器交互,以及同一浏览器如何与测试和已知良好的 webSocket 服务器交互,例如websocket.org/echo.html。两者之间的框架差异可能会很明显。 如果你很好奇,这里有一张很好的图表,说明 webSocket 框架在 http 握手完成后应该是什么样子:developer.mozilla.org/en-US/docs/WebSockets/… 感谢 jfriend00 的链接.. 它真的帮助我前进 【参考方案1】:

当我像这样更改发件人功能时它可以工作..

...

def sender(data, conn):
    length = len(data)

    if length <= 125:
        ret = bytearray([129, length])

        for byte in text.encode("utf-8"):
            ret.append(byte)

        conn.send(ret)

...

【讨论】:

这适用于较小的字符串。如果我们必须发送更大的字符串怎么办?

以上是关于Websocket 连接因错误“收到意外的延续帧”而关闭。的主要内容,如果未能解决你的问题,请参考以下文章

WebSocket 客户端的状态不会因网络丢失而改变

无法启动连接:错误:WebSocket 连接失败

nodejs websocket检测断开连接的套接字

为 Kaleido 使用 Websocket 连接时出现“连接未在 send() 上打开”错误

Unity+Firebase-Database [错误] WebSocket:ws_0 - 无法连接

错误:在建立连接之前关闭了 WebSocket