blob: 68367860c697e43ad62ec5c258d6f9a5ecde7ada [file] [log] [blame]
James Kuszmaul0de4feb2022-04-15 12:16:59 -07001#ifndef AOS_UTIL_FOXGLOVE_WEBSOCKET_LIB_H_
2#define AOS_UTIL_FOXGLOVE_WEBSOCKET_LIB_H_
Stephan Pleinesb1177672024-05-27 17:48:32 -07003#include <stdint.h>
4
James Kuszmaul0de4feb2022-04-15 12:16:59 -07005#include <map>
Stephan Pleinesb1177672024-05-27 17:48:32 -07006#include <memory>
James Kuszmaul0de4feb2022-04-15 12:16:59 -07007#include <set>
8
James Kuszmaul0de4feb2022-04-15 12:16:59 -07009#include "foxglove/websocket/server.hpp"
10
Philipp Schrader790cb542023-07-05 21:06:52 -070011#include "aos/events/event_loop.h"
12
James Kuszmaul0de4feb2022-04-15 12:16:59 -070013namespace aos {
14// This class implements a live AOS -> Foxglove Websocket Protocol connection,
15// making use of the implementation at
16// https://github.com/foxglove/ws-protocol/tree/main/cpp to send JSON messages
17// to a foxglove studio client.
18// See foxglove_websocket.cc for some usage notes.
19class FoxgloveWebsocketServer {
20 public:
James Kuszmaulf1dbaff2023-02-08 21:17:32 -080021 // Whether to serialize the messages into the MCAP file as JSON or
22 // flatbuffers.
23 enum class Serialization {
24 kJson,
25 kFlatbuffer,
26 };
27 enum class FetchPinnedChannels {
28 kYes,
29 kNo,
30 };
James Kuszmaul1e418f62023-02-26 14:40:20 -080031 // Whether to attempt to shorten channel names.
32 enum class CanonicalChannelNames {
33 // Just use the full, unambiguous, channel names.
34 kCanonical,
35 // Use GetChannelAliases() to determine the shortest possible name for the
36 // channel for the current node, and use that in the MCAP file. This makes
37 // it so that the channels in the resulting file are more likely to match
38 // the channel names that are used in "real" applications.
39 kShortened,
40 };
James Kuszmaulf1dbaff2023-02-08 21:17:32 -080041 FoxgloveWebsocketServer(aos::EventLoop *event_loop, uint32_t port,
42 Serialization serialization,
James Kuszmaul1e418f62023-02-26 14:40:20 -080043 FetchPinnedChannels fetch_pinned_channels,
44 CanonicalChannelNames canonical_channels);
James Kuszmaul0de4feb2022-04-15 12:16:59 -070045 ~FoxgloveWebsocketServer();
46
47 private:
48 typedef foxglove::websocket::ChannelId ChannelId;
49
50 struct FetcherState {
51 std::unique_ptr<aos::RawFetcher> fetcher;
52 // Whether the current message in the fetcher has been sent to the client.
53 // Starts as true because the fetcher starts with no data.
54 // This is necessary because we have to send all of our messages out
55 // in order, which we can only do once we know the timestamp of each
56 // message. And we can only know the timestamp after having called Fetch()
57 // on the fetcher. Once we get around to actually sending the data, we can
58 // set this to true so that we know it is safe to call FetchNext() again.
59 bool sent_current_message = true;
60 };
61
62 aos::EventLoop *event_loop_;
James Kuszmaulf1dbaff2023-02-08 21:17:32 -080063 const Serialization serialization_;
64 const FetchPinnedChannels fetch_pinned_channels_;
James Kuszmaul1e418f62023-02-26 14:40:20 -080065 const CanonicalChannelNames canonical_channels_;
James Kuszmaul0de4feb2022-04-15 12:16:59 -070066 foxglove::websocket::Server server_;
67 // A map of fetchers for every single channel that could be subscribed to.
68 std::map<ChannelId, FetcherState> fetchers_;
69 // The set of channels that we have clients actively subscribed to.
70 std::set<ChannelId> active_channels_;
71};
72} // namespace aos
73#endif // AOS_UTIL_FOXGLOVE_WEBSOCKET_LIB_H_