overthesun / simoc-sam

Back-end system to support SIMOC Live air quality monitor sensor array as used at the SAM Mars habitat analog.
https://samb2.space/
2 stars 1 forks source link

Implement a redirect event for intra-client communication #11

Open ezio-melotti opened 2 years ago

ezio-melotti commented 2 years ago

Currently all clients (both the ones that provide data like sensors, and the ones that read them like the frontend) are connected to the server, and they can't communicate directly with each other -- a sensor cannot talk directly with another sensor.

The SCD30 sensor can provide better readings if the current pressure is known, and the BNE688 can provide that value if there was a way for the SCD30 driver to request it directly.

We could implement a msg-to event in the socketio server, that accepts the id of another client, an event, and possibly extra args. The socketio server could then redirect the message to the right client, and send back the response to the original client.

This is a rough outline of how it might work:

  1. The SCD30 client does sio.emit('msg-to', 'BNE688', 'get-pressure')
  2. The socketio server receives the msg-to event
  3. The socketio server does res = sio.emit('get-pressure', to='BNE688')
  4. The BNE688 client receives the get-pressure event and returns the value
  5. The socketio server receives the pressure value
  6. The socketio server does sio.emit('pressure', to='SCD30')

Socketios have different features that can be leveraged to achieve this, such as using client IDs directly, rooms, namespaces, and callbacks. See the server and client docs.

Since I'm not familiar with all these options, it would be good to experiment and test them and see which one works best.

It would be ideal if:

If rooms or namespaces allow transparent client-to-client communication, then it's even better.

kstaats commented 2 years ago

Is there any chance of a race condition, or a stall if one sensor is waiting for another sensor, before it delivers?

On 1/26/22 8:09 PM, Ezio Melotti wrote:

Currently all clients (both the ones that provide data like sensors, and the ones that read them like the frontend) are connected to the server, and they can't communicate directly with each other -- a sensor cannot talk directly with another sensor.

The SCD30 sensor can provide better readings if the current pressure is known, and the BNE688 can provide that value if there was a way for the SCD30 driver to request it directly.

We could implement a msg-to event in the socketio server, that accepts the id of another client, an event, and possibly extra args. The socketio server could then redirect the message to the right client, and send back the response to the original client.

This is a rough outline of how it might work:

  1. The SCD30 client does sio.emit('msg-to', 'BNE688', 'get-pressure')
  2. The socketio server receives the msg-to event
  3. The socketio server does res = sio.emit('get-pressure', to='BNE688')
  4. The BNE688 client receives the get-pressure event and returns the value
  5. The socketio server receives the pressure value
  6. The socketio server does sio.emit('pressure', to='SCD30')

Socketios have different features that can be leveraged to achieve this, such as using client IDs directly, rooms, namespaces, and callbacks. See the server and client docs.

Since I'm not familiar with all these options, it would be good to experiment and test them and see which one works best.

It would be ideal if:

  • The server only defines a single flexible redirect event
  • The server dispatches the messages between the two clients
  • The client that received the request doesn't know who sent it
  • The client that received the request only replies to the server
  • The server receives the result and redirects it to the original client

If rooms or namespaces allow transparent client-to-client communication, then it's even better.

ezio-melotti commented 2 years ago

I think the worse that could happen with the current architecture is that it waits forever while everything else (including the sensor waiting) will continue normally. The SCD30 could request the pressure every ~15s or so while sending out data every second whether it got a pressure reading or not. Normally the pressure doesn't change often, so updating it every once in a while should be enough, but something catastrophic that can cause a sudden loss of pressure might happen as well.

We could also implement a timeout so that if the BNE688 doesn't reply within a few seconds, the server returns an error to the SCD30. Depending on how we identify the sensors, the server might reject the request if it sees/knows that the BNE688 is not connected.