Search code examples
javascriptpythonwebsockettornado

Can I send gzip compressed data through tornado websocket in Python?


I would like to send gzip compressed data from tornado server to javascript client. Here is my code.

buf = StringIO()
gfile = gzip.GzipFile(mode='wb', fileobj=buf)
try:
    gfile.write( "hello world" )
finally:
    gfile.close()

compressed_data = buf.getvalue()    
self.write_message( compressed_data )

Server side doesn't provide error. But chrome produces an error "Could not decode a text frame as UTF8".

Is there any workaround here?


Solution

  • Use self.write_message(compressed_data, binary=True) to send a binary message. You'll also need to change the client side of the application to decompress it.

    Note that binary data can be difficult to work with in javascript, so you may want to use the websocket compression extension instead of compressing the data yourself (this will make Tornado compress the data automatically, and the browser will decompress it).

    To enable this, override get_compression_options() in your WebSocketHandler subclass:

    def get_compression_options(self):
        return {}
    

    An empty dict uses the defaults, or you can return parameters like {'compression_level': 9}. When using this mode you'd just write your message as usual instead of compressing it.