支持二进制第2部分的龙卷风腹板

时间:2013-09-22 18:05:24

标签: python websocket tornado

我试图通过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。另一端的服务器没有显示它收到任何消息,它只是知道客户端已连接,然后断开连接。有谁知道问题在哪里?我不确定问题是否存在于龙卷风或websockets库中。有什么建议吗?


编辑:在回复下面的评论(@plg)时,我修改了上面的脚本以显示:

  1. 非编码消息可以从客户端发送到龙卷风服务器
  2. 龙卷风可以回复编码信息
  3. 服务器:

    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接收编码信息
    3. 说实话,我确实认为第一种选择比龙卷风更可能。在我看来,我相信龙卷风会提醒我,如果传入的消息没有按照websocket标准正确解码。还有其他建议吗?


      编辑:关于谁有过错的更多发展。我没有使用自己的服务器来中继我的连接,而是将连接转发到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
      

      这实际上通过了测试,收到的数据很好。所以我猜龙卷风接收数据有问题吗?

2 个答案:

答案 0 :(得分:5)

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

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

数据包将被发送得很好。龙卷风我想只是忽略了伪二进制数据包,因为它们被标记为文本并包含二进制文件。

答案 1 :(得分:0)

感谢这个commit龙卷风支持websocket压缩扩展。