blob: 7c326c222b490723f41e76bf4ec2be2359e8eea2 [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_
3#include <map>
4#include <set>
5
6#include "aos/events/event_loop.h"
7#include "foxglove/websocket/server.hpp"
8
9namespace aos {
10// This class implements a live AOS -> Foxglove Websocket Protocol connection,
11// making use of the implementation at
12// https://github.com/foxglove/ws-protocol/tree/main/cpp to send JSON messages
13// to a foxglove studio client.
14// See foxglove_websocket.cc for some usage notes.
15class FoxgloveWebsocketServer {
16 public:
James Kuszmaulf1dbaff2023-02-08 21:17:32 -080017 // Whether to serialize the messages into the MCAP file as JSON or
18 // flatbuffers.
19 enum class Serialization {
20 kJson,
21 kFlatbuffer,
22 };
23 enum class FetchPinnedChannels {
24 kYes,
25 kNo,
26 };
James Kuszmaul1e418f62023-02-26 14:40:20 -080027 // Whether to attempt to shorten channel names.
28 enum class CanonicalChannelNames {
29 // Just use the full, unambiguous, channel names.
30 kCanonical,
31 // Use GetChannelAliases() to determine the shortest possible name for the
32 // channel for the current node, and use that in the MCAP file. This makes
33 // it so that the channels in the resulting file are more likely to match
34 // the channel names that are used in "real" applications.
35 kShortened,
36 };
James Kuszmaulf1dbaff2023-02-08 21:17:32 -080037 FoxgloveWebsocketServer(aos::EventLoop *event_loop, uint32_t port,
38 Serialization serialization,
James Kuszmaul1e418f62023-02-26 14:40:20 -080039 FetchPinnedChannels fetch_pinned_channels,
40 CanonicalChannelNames canonical_channels);
James Kuszmaul0de4feb2022-04-15 12:16:59 -070041 ~FoxgloveWebsocketServer();
42
43 private:
44 typedef foxglove::websocket::ChannelId ChannelId;
45
46 struct FetcherState {
47 std::unique_ptr<aos::RawFetcher> fetcher;
48 // Whether the current message in the fetcher has been sent to the client.
49 // Starts as true because the fetcher starts with no data.
50 // This is necessary because we have to send all of our messages out
51 // in order, which we can only do once we know the timestamp of each
52 // message. And we can only know the timestamp after having called Fetch()
53 // on the fetcher. Once we get around to actually sending the data, we can
54 // set this to true so that we know it is safe to call FetchNext() again.
55 bool sent_current_message = true;
56 };
57
58 aos::EventLoop *event_loop_;
James Kuszmaulf1dbaff2023-02-08 21:17:32 -080059 const Serialization serialization_;
60 const FetchPinnedChannels fetch_pinned_channels_;
James Kuszmaul1e418f62023-02-26 14:40:20 -080061 const CanonicalChannelNames canonical_channels_;
James Kuszmaul0de4feb2022-04-15 12:16:59 -070062 foxglove::websocket::Server server_;
63 // A map of fetchers for every single channel that could be subscribed to.
64 std::map<ChannelId, FetcherState> fetchers_;
65 // The set of channels that we have clients actively subscribed to.
66 std::set<ChannelId> active_channels_;
67};
68} // namespace aos
69#endif // AOS_UTIL_FOXGLOVE_WEBSOCKET_LIB_H_