Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tornado websockets supporting binary

Tags:

python

tornado

I am using tornado as a server. I would like it to receive binary data. The server side is as simple as simple gets:

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 'GOT MESSAGE: {}'.format(message)

    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()

This server is just used to visualize incoming data, not too special. The server works just find with standard ascii, but it explodes when it gets any unicode (my test for fake binary data). I used the site http://www.websocket.org/echo.html and redirected the sending to go to ws://172.0.0.1:9500/ which is where I set up the server. The server then prompted me with the very nasty error:

ERROR:tornado.application:Uncaught exception in /
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site packages/tornado/websocket.py", line 303, in wrapper
    return callback(*args, **kwargs)
  File "test.py", line 11, in on_message
    print 'GOT MESSAGE: {}'.format(message)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa1' in position 0: ordinal not in range(128)

The character was ¡, an upside down !. Now I know that tornado can send binary, but apparently not receive? I am probably doing some petty mistake, but where is it?

like image 898
jakebird451 Avatar asked Nov 01 '22 14:11

jakebird451


1 Answers

In the line

print 'GOT MESSAGE: {}'.format(message)

you advise Python to format a character string into a byte string, which fails if the character string contains non-ASCII characters. Simply use a character string (prefixed with u in Python 2.x) instead (parentheses optional):

print (u'GOT MESSAGE: {}'.format(message))
#      ^

Alternatively, if you want to inspect binary characters, use repr:

print ('GOT MESSAGE: {}'.format(repr(message)))
#                               ^^^^^       ^
like image 51
phihag Avatar answered Nov 15 '22 05:11

phihag