gpt4 book ai didi

python - 支持二进制的 Tornado websockets 第 2 部分

转载 作者:太空狗 更新时间:2023-10-29 21:05:49 28 4
gpt4 key购买 nike

我正在尝试通过 websockets 传递二进制数据,更具体地说,是通过 websockets 传递压缩字符串。在我当前的设置中,我使用 tornado 作为带有 websocket 的服务器。客户端传输二进制数据。二进制数据是通过zlib压缩数据形成的。客户端和服务器都非常简单,如下所示。

服务器:

import tornado.websocket
import tornado.httpserver
import tornado.ioloop
import tornado.web

class WebSocketServer(tornado.websocket.WebSocketHandler):
def open(self):
print 'OPEN'

def on_message(self, message):
print 'len = {}'.format(len(message))
print 'GOT MESSAGE: {}'.format(message.decode('zlib'))

def on_close(self):
print 'CLOSE'

app = tornado.web.Application([
(r'/', WebSocketServer)
])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(9500)
tornado.ioloop.IOLoop.instance().start()

客户:

import websocket

host = 'localhost'
port_ws = 9500
ws = websocket.create_connection('ws://{}:{}/'.format(host, port_ws))
message = 'this is my message'.encode('zlib')
print 'Length of message is {}'.format(len(message))
ws.send(message)

客户端没有抛出任何错误,它打印出消息:Length of message is 24。根据 zlib 标准,消息被编码为 str。另一端的服务器没有显示它收到任何消息,它只知道客户端已连接,然后断开连接。有谁知道问题出在哪里?我不确定问题是出在 tornado 还是 websockets 库中。有什么建议吗?


编辑:为了回应下面的评论 (@plg),我修改了上面的脚本以表明:

  1. 非编码消息可以从客户端发送到tornado服务器
  2. Tornado 可以用编码的消息回复

服务器:

import tornado.websocket
import tornado.httpserver
import tornado.ioloop
import tornado.web

class WebSocketServer(tornado.websocket.WebSocketHandler):
def open(self):
print 'OPEN'

def on_message(self, message):
print 'len = {}'.format(len(message))
print 'GOT MESSAGE: {}'.format(message)
self.write_message(message.encode('zlib'))

def on_close(self):
print 'CLOSE'

app = tornado.web.Application([
(r'/', WebSocketServer)
])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(9500)
tornado.ioloop.IOLoop.instance().start()

客户:

import websocket

host = 'localhost'
port_ws = 9500
ws = websocket.create_connection('ws://{}:{}/'.format(host, port_ws))
#message = 'this is my message'.encode('zlib')
message = 'this is my message'
print 'Length of message is {}'.format(len(message))
ws.send(message)
assert ws.recv().decode('zlib') == message

系统运行良好。断言不会引发错误。解码消息与发送消息匹配。所以我想这两者都有问题:

  1. 从客户端发送编码消息
  2. Tornado 接收编码信息

老实说,我确实相信第一种选择比 Tornado 更有可能。在我看来,如果传入消息未按照 websocket 标准正确解码,我相信 Tornado 会提醒我。还有更多建议吗?


编辑:关于谁有错的更多进展。我没有使用我自己的服务器来中继我的连接,而是将连接中继到 ws://echo.websocket.org/。我的测试应用程序如下所示:

import websocket

host = 'localhost'
port_ws = 9500
ws = websocket.create_connection('ws://echo.websocket.org/')
message = 'this is my message'
ws.send(message.encode('zlib'))
got = ws.recv().decode('zlib')
print 'GOT: {}'.format(got)
assert got == message

这个居然通过了测试,数据接收正常。所以我猜是tornado接收数据有问题吧?

最佳答案

在查看了 websocket 库的源代码后,我发现默认情况下它将数据包格式化为文本。通过更改行:

ws.send('message')
# to:
ws.send('message', opcode=websocket.ABNF.OPCODE_BINARY)
# or better yet:
ws.send_binary('message')

数据包会被发送过来就好了。我猜 Tornado 只是忽略了伪造的二进制数据包,因为它们被标记为文本并包含二进制文件。

关于python - 支持二进制的 Tornado websockets 第 2 部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18947091/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com