8

Websocket 経由でバイナリ データ、具体的には Websocket 経由で圧縮された文字列を渡そうとしています。私の現在の設定では、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. メッセージはstr、zlib 標準に従ってエンコードされます。反対側のサーバーは、メッセージを受信したことを示しません。クライアントが接続したことを理解し、その後切断したことを理解するだけです。問題がどこにあるか誰か知っていますか?問題がトルネードにあるのか、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. 暗号化されたメッセージを受信するトルネード

正直なところ、最初の選択肢は竜巻よりも可能性が高いと思います。私の意見では、着信メッセージが websocket 標準に従って適切にデコードされていない場合、竜巻が警告を発すると思います。他に提案はありますか?


編集:誰が過ちを犯しているかについてのさらなる開発。独自のサーバーを使用して接続を中継して 4 番目にする代わりに、接続を に中継しました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

これは実際にテストに合格し、データは問題なく受信されました。トルネードがデータを受信するのに何か問題があると思いますか?

4

2 に答える 2

6

ライブラリのソース コードを調べたwebsocketところ、デフォルトでパケットがテキストとしてフォーマットされていることがわかりました。行を変更することにより:

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

パケットは問題なく送信されます。Tornado 偽のバイナリ パケットは、テキストとしてマークされ、バイナリが含まれているため、無視していたと思います。

于 2013-09-22T21:54:23.610 に答える
0

このコミットのおかげでtornado は websocket 圧縮拡張機能をサポートしています。

于 2014-08-27T11:25:30.950 に答える