Próbuję przekazać dane binarne przez websockets, a konkretnie skompresowane łańcuchy na stronach internetowych. W mojej obecnej konfiguracji używam tornada jako serwera z klientem websocket przesyłającym dane binarne. Dane binarne są tworzone przez kompresję danych za pomocą zlib
. Zarówno klient, jak i serwer są tak proste, jak to tylko możliwe, i pokazano je poniżej.Sieci webowe podpórki Tornado obsługujące część binarną 2
Serwer:
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()
Klient:
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)
Klient nie rzucać żadnych błędów, to wypisuje, że wiadomości: Length of message is 24
. Wiadomość jest zakodowana jako str
zgodnie ze standardem Zlib. Serwer na drugim końcu nie pokazuje, że otrzymał jakiekolwiek wiadomości, rozumie jedynie, że klient podłączył się, a następnie rozłączył. Czy ktoś wie, gdzie jest problem? Nie jestem pewien, czy problem leży w bibliotece tornada czy w sieci. Jakieś sugestie?
EDIT: W odpowiedzi na komentarz poniżej (@plg), I zmodyfikowane skrypty powyżej, aby pokazać, że:
- Non-zakodowane wiadomości można wysyłać od klienta do serwera tornado
- Tornado może odpowiadać z zakodowanej wiadomości
Serwer:
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()
Klient:
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
System działa dobrze. Aserser nie rzuca błędu. Zdekodowany komunikat odpowiada wiadomości wysłanej. Więc myślę, że jest problem z albo:
- Wysyłanie zakodowaną wiadomość od klienta
- Tornado odbieranie zakodowane wiadomości
Aby być całkiem szczery, wierzę, że pierwsza opcja jest bardziej prawdopodobne niż tornado. Moim zdaniem, wierzę, że tornado powiadomi mnie, jeśli wiadomość przychodząca nie zostanie poprawnie zdekodowana zgodnie ze standardem websocket. Jakieś dodatkowe sugestie?
EDYCJA: Więcej informacji na temat tego, kto ponosi winę. Zamiast używać mojego własnego serwera do przekazywania z powrotem i czwartego połączenia, przekazałem połączenie do ws://echo.websocket.org/
. Moja aplikacja do testowania jest taka jak:
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
To faktycznie zdało test, dane zostały odebrane dobrze. Sądzę więc, że coś jest nie tak z tornadem odbierającym dane?
Czy próbowałeś zrobić to na odwrót, aby sprawdzić, czy działa lub zgłasza wyjątek? Używanie ws.recv() w kliencie iw open(): self.write_message ("to jest mój message'.encode (" zlib ")). Próbowałeś także bez kompresji zlib, znowu na wypadek, gdyby czegoś nam brakowało. – ThinkChaos
@plg Działa na odwrót. Wysłałem standardową wiadomość ascii do tornada, a tornado odpowiedziało z zakodowaną wiadomością. Ten kierunek działa. – jakebird451