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