使用 Python 使用 JSON 与网络套接字通信

Using Python to communicate with web socket using JSON

为了更好地理解如何在基本的 hello-world 之外使用 websockets,我给自己设定了使用 websockets 从页面获取一些数据的任务和 JSON(因为 gitxiv 的源代码很容易可用,我选择查看http://gitxiv.com/day/2015/12/31)。

通过 Python 连接到这个 websocket 似乎很简单

from websocket import create_connection
import websocket
import pprint

websocket.enableTrace(True)
ws=create_connection("ws://gitxiv.com/sockjs/212/2aczpiim/websocket")
result = ws.recv()
print "Received '%s'" % result
result = ws.recv()
print "Received '%s'" % result

我不是很清楚 ws:// url 中的变量,比如 '212'。 运行这段代码似乎可以可靠地连接(尽管总是有可能没有正确的变量导致服务器稍后拒绝合作?)

现在,如果我观察 Firefox 和 gitxiv 页面之间的通信,我会看到在连接 websocket 之后服务器发送

o
a["{\"server_id\":\"0\"}"]

上面的脚本得到相同的响应,因此似乎连接成功。

然而,这是我绊倒的地方。通信的下一步是我的浏览器向 Web 服务发送相当多的信息,例如行:

"["{\"msg\":\"connect\",\"version\":\"1\",\"support\":[\"1\",\"pre2\",\"pre1\"]}"]"

直接使用 ws.send() 发送这些行会导致 'broken framing'。仅发送:

controlstr='{"msg":"connect","version":"1","support":["1","pre2","pre1"]}';
ws.send(controlstr)

导致发送的内容如下所示:

send: '\x81\xbd\xef\x17F8\x945+K\x885|\x1a\x8cx(V\x8at2\x1a\xc350]\x9dd/W\x815|\x1a\xde5j\x1a\x9cb6H\x80e2\x1a\xd5Ld\t\xcd;dH\x9drt\x1a\xc356J\x8a&de\x92'

我得到一个不同的错误:

'a["{\"msg\":\"error\",\"reason\":\"Bad request\"}"]'

因此,我向 websocket 发送此 JSON 消息的方式似乎有问题。有人知道它期望什么格式,以及如何使用 websocket/websocket-client 实现它吗?任何 clarification/suggestions 都将受到欢迎。

我要发送的 JSON 消息是 Firefox 的 Websocket 开发人员工具报告的消息:这里是屏幕截图:

如果您仔细查看通过浏览器发送的内容,请注意它是:

["{\"msg\":\"connect\"}"]

这看起来非常像一个 JSON 字符串数组。事实上,如果您尝试复制它:

ws.send(json.dumps([json.dumps({'msg': 'connect', 'version': '1', 'support': ['1', 'pre2', 'pre1']})]))

您会看到已连接。这是我的全部代码:

import json
import pprint
import websocket
from websocket import create_connection

websocket.enableTrace(True)
ws = create_connection('ws://gitxiv.com/sockjs/212/2aczpiim/websocket')

result = ws.recv()
print('Result: {}'.format(result))

result = ws.recv()
print('Result: {}'.format(result))

ws.send(json.dumps([json.dumps({'msg': 'connect', 'version': '1', 'support': ['1', 'pre2', 'pre1']})]))
result = ws.recv()
print('Result: {}'.format(result))