python-websocket-server icon indicating copy to clipboard operation
python-websocket-server copied to clipboard

Binary support

Open Toshinaki opened this issue 8 years ago • 3 comments

I'm trying to combine this websocket server with matplotlib's webagg so that I can make a web GUI for plots. It seems that webagg sends bytes instead of string. However, as far as I saw in the code, the handler tries to decode the bytes and only sends strings. How can I send bytes using this websocket server?

Toshinaki avatar Apr 20 '16 06:04 Toshinaki

At the moment binary transfer is not supported. It shouldn't be significantly hard to add this support but atm unfortunately I have limited time.

However a workaround is to convert the data to 64base and send that via the websocket. Then ofcourse you would need to decode it back to its original format if you want that. By converting the data to base 64, you can send any type of data as text. The only downside is a small increase in the size of data and an overhead for encoding/decoding.

Pithikos avatar Apr 20 '16 06:04 Pithikos

Sorry again. I think I kind of solved the problem. Just set the OPCODE_TEXT to 0x02 before send the text in send_text(self, message) of WebSocketHandler, and don't change bytes to string. This is my change:

        # Validate message
        if isinstance(message, bytes):
            OPCODE_TEXT = 0x02
            payload = message
        elif isinstance(message, str):
            OPCODE_TEXT = 0x01
            payload = encode_to_UTF8(message)
        else:
            timeprint("[!] Can't send message, message has to be a string or bytes. Given type is {}".format(type(message)))
            return False

        header = bytearray()
        payload_length = len(payload)

And this is the original code:

# Validate message
        if isinstance(message, bytes):
            message = try_decode_UTF8(message) # this is slower but assures we have UTF-8
            if not message:
                print("Can\'t send message, message is not valid UTF-8")
                return False
        elif isinstance(message, str) or isinstance(message, unicode):
            pass
        else:
            print('Can\'t send message, message has to be a string or bytes. Given type is %s' % type(message))
            return False

        header  = bytearray()
        payload = encode_to_UTF8(message)
        payload_length = len(payload)

Not sure if this change would break something, it worked for me with matplotlib, for now. I'll keep digging further.

Toshinaki avatar Apr 20 '16 06:04 Toshinaki

@flasker this is an amazing workaround!! thank you so much u saved my day :smile:

hasan-dot avatar May 15 '19 07:05 hasan-dot