Commit Graph

3 Commits (4820d0f6cd03b315f8c56f7b9bb3e4768fed97d7)

Author SHA1 Message Date
Dustin 4820d0f6cd Begin MQTT control implementation
The pieces are starting to come together.  To control the browser via
MQTT messages, the `MqttClient` dispatches messages via a
`MessageHandler`, which parses them and makes the appropriate Marionette
requests.  The `MessageHandler` trait defines callback methods for each
MQTT control operation, which currently is just `navigate`.  The
operation type is determined by the MQTT topic on which the message was
received.

Several new types are necessary to make this work.  The `MessageHandler`
trait and implementation are of course the core, reacting to incoming
MQTT messages.  In order for the handler to be able to *send* MQTT
messages, though, it needs a reference to the Paho MQTT client.  The
`MqttPublisher` provides a convenient wrapper around the client, with
specific methods for each type of message to send.  Finally, there's the
`MessageType` enumeration, which works in conjunction with the
`TopicMatcher` to match topic names to message types using topic filter
patterns.
2022-12-30 19:06:27 -06:00
Dustin c8386f9dee marionette: Handle concurrent communication
The Marionette protocol is designed to facilitate concurrent,
asynchronous messages.  Each request message includes a message
ID, and the corresponding response includes the same message ID.  This
allows several requests to be in flight at once.  In order for this to
be useful, the client needs to maintain a record of each request it has
sent so that it knows how to handle responses, even if they arrive out
of order.

To implement this functionality in *mqttmarionette*, the
`MarionetteConnection` structure spawns a Tokio task to handle all
incoming messages from the server.  When a message arrives, its ID is
looked up in a registry that maps message IDs to Tokio "oneshot"
channels.  If a channel is found in the map, the response is sent back
to the caller through the channel.

In order to handle incoming messages in a separate task, the TCP stream
has to be split into its read and write parts.  The receiver task cannot
be spawned, though, until after the first unsolicited message is read
from the socket, since a) there is no caller to send the message back to
and b) it does not follow the same encoding scheme as the rest of the
Marionette messages.  As such, I've refactored the
`MarionetteConnection` structure to handle the initial message in the
`connect` function and dropped the `handshake` method.  A new
`start_session` method is responsible for initiating the Marionette
session.
2022-12-30 10:02:15 -06:00
Dustin f3815e2b12 Initial commit 2022-12-30 09:10:05 -06:00