pymeasure / leco-protocol

Design notes for a generic communication protocol to control experiments and measurement hardware
https://leco-laboratory-experiment-control-protocol.readthedocs.io
MIT License
6 stars 3 forks source link

How to transmit binary data? #65

Open BenediktBurger opened 4 months ago

BenediktBurger commented 4 months ago

Sometime you have to transmit binary data, like an image. JSON (our main encoding scheme) does not support binary data. What do we recommend?

Several options, which are all compatible with current LECO definitions:

  1. You can send the binary data in the first (and more) payload frame, while setting the message_type to some specific (TBD) value
  2. You can send a JSON message in the first payload frame and add the binary objects in additional payload frames. This requires, however, that the code looks at the whole message and makes the additional frames available to the json-rpc interpreter somehow. Here it might be good to define its own message type as well. (I implemented this for PyMoDAQ)
  3. You can encode the binary data with some binary-to-text encoding to plain ASCII text, which can be sent via JSON. The most common encoding seems to be base64.

All three approaches have their advantages and disadvantages. I guess the choice depends on the circumstances. Here I want to present them, maybe we can recommend one or the other, or even all three as

BenediktBurger commented 1 month ago

More elaborate discussion of the different methods.

1. Binary data as the only payload

Implementation

The payload of the LECO message is the binary data, without any (pre-defined) other information.

Pro

From the LECO side quite simple: put the binary data in one or several payload frames (several for several binary objects).

Cons

2. JSON message and additional payload

Implementation

example mehod (based on PyLECO):

current_message: Message  # contains the LECO message
additional_response: bytes  # will later contain the additional, binary, response

def method_with_binary(json_parameter):
    binary_data = current_message.payload[1]
    result = do_something(json_parameter, binary_data)
    additional_response = result
    return None

# afterwards the additional_response has to be added to the response message before sending

Pros

Cons

Open questions

3. Encode binary data to string and send it via JSON

Implementation

Encode your binary data to a string and use that as a parameter for JSON-RPC.

Pros

Cons

Comments