【问题标题】:Python Web Socket closes immediately after openingPython Web Socket 打开后立即关闭
【发布时间】:2017-01-25 19:55:35
【问题描述】:

所以我对 Python 中的 websocket 有疑问。我正在尝试与使用 websockets 进行某些内容通信的网站进行交互。这是他们网站上的 javascript 代码:

 var $j = jQuery.noConflict(); // Use $j to reference JQuery selectors instead of $
 function sockify() {
    var ws = new WebSocket("ws://website:1234");
    ws.onmessage = function (evt) {
        console.log(evt.data)
       $j('#output').html(evt.data);
    }
    ws.onopen = function () {
        ws.send(JSON.stringify($j('#srctext').val()));
    }
    ws.onerror = function () {
        alert("socket down");
    }
 }

所以该站点运行良好,并且没有问题,但是当我尝试使用此 python 代码时,我收到一条错误消息,指出套接字在打开后立即关闭:

ws = create_connection("ws://website:1234/")
print "Sending 'Hello, World'..."
ws.send("Hello, World")
print "Sent"
print "Receiving..."
result = ws.recv()
print "Received '%s'" % result
ws.close()

这是从websocket man page on python.org 提取的示例代码,如果我不将主机更改为我要从中提取的网站,而是将示例的主机保留在示例中,它确实有效。

这是我收到的错误:

Traceback (most recent call last):
  File "irc.py", line 462, in <module>
    tmpmsg = getSocket()
  File "irc.py", line 64, in getTrump
    result = ws.recv()
  File "/Library/Python/2.7/site-packages/websocket/_core.py", line 293, in recv
    opcode, data = self.recv_data()
  File "/Library/Python/2.7/site-packages/websocket/_core.py", line 310, in recv_data
    opcode, frame = self.recv_data_frame(control_frame)
  File "/Library/Python/2.7/site-packages/websocket/_core.py", line 323, in recv_data_frame
    frame = self.recv_frame()
  File "/Library/Python/2.7/site-packages/websocket/_core.py", line 357, in recv_frame
    return self.frame_buffer.recv_frame()
  File "/Library/Python/2.7/site-packages/websocket/_abnf.py", line 336, in recv_frame
    self.recv_header()
  File "/Library/Python/2.7/site-packages/websocket/_abnf.py", line 286, in recv_header
    header = self.recv_strict(2)
  File "/Library/Python/2.7/site-packages/websocket/_abnf.py", line 371, in recv_strict
    bytes_ = self.recv(min(16384, shortage))
  File "/Library/Python/2.7/site-packages/websocket/_core.py", line 427, in _recv
    return recv(self.sock, bufsize)
  File "/Library/Python/2.7/site-packages/websocket/_socket.py", line 93, in recv
    "Connection is already closed.")
websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed.

知道为什么它会立即关闭吗?

编辑:

在 enableTrace 为 true 的情况下运行。

这是我得到的错误:

--- request header ---
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: website
Origin: website
Sec-WebSocket-Key: 6jsV5DEWXPGTTTLKSEwz6g==
Sec-WebSocket-Version: 13


-----------------------
--- response header ---
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: CX4DYsItQC6utXvt8JH641455mM=
-----------------------
send: '\x81\x8b\x98\x8d\x81\xce\xd0\xe8\xed\xa2\xf7\xad\xd6\xa1\xea\xe1\xe5'

请注意,我实际上无法控制 websocket,因此任何修复都需要我自己完成。我在 Python 2.7.10

我还注意到,如果我在使用网站时在 Burp 中拦截 websocket 请求,websocket 初始连接请求是不同的。这是从网站上捕获的:

GET / HTTP/1.1
Host: website
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: website
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: uyG2WBK51ZtPhy9RXLNTmg==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

【问题讨论】:

  • 对于遇到此问题的任何人,我都没有很好的解决方案。我只是使用 selenium 和 phantomjs 加载站点,输入字段,单击按钮,然后从那里读取响应。这么多开销,但它适用于我的小宠物项目。
  • 看起来websocket不喜欢接收Hello, World

标签: python websocket


【解决方案1】:

你肯定有一个错误(很可能你的套接字正在无声地爆炸......)

改为在配置中为套接字中的错误设置一个回调并打印你得到的消息..

示例:(取自here

 websocket.enableTrace(True)
 ws = websocket.WebSocketApp("ws://echo.websocket.org/",
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close)

并定义方法

def on_error(ws, error):
    print(error)

【讨论】:

  • 这样做并将结果放在我原来的帖子底部。
【解决方案2】:

对于遇到相同问题的任何人,我通过调整 websocket 模块并在获取请求中设置自定义标头尝试强制它使用此标头来修复它

GET / HTTP/1.1 Host: website User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:50.0) Gecko/20100101 Firefox/50.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Sec-WebSocket-Version: 13 Origin: website Sec-WebSocket-Extensions: permessage-deflate Sec-WebSocket-Key: uyG2WBK51ZtPhy9RXLNTmg== Connection: keep-alive, Upgrade Pragma: no-cache Cache-Control: no-cache Upgrade: websocket

而不是这个

GET / HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: website Origin: website Sec-WebSocket-Key: 6jsV5DEWXPGTTTLKSEwz6g== Sec-WebSocket-Version: 13

【讨论】:

  • @dan 自从我发布此内容以来已经很长时间了,但我记得对标题进行硬编码,所以每次我不记得抱歉的地方时都会发布它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-20
  • 2017-11-21
  • 2014-11-23
  • 2018-05-02
  • 2016-03-19
  • 1970-01-01
  • 2014-06-14
相关资源
最近更新 更多