James Kuszmaul | 0de4feb | 2022-04-15 12:16:59 -0700 | [diff] [blame] | 1 | #ifndef AOS_UTIL_FOXGLOVE_WEBSOCKET_LIB_H_ |
| 2 | #define AOS_UTIL_FOXGLOVE_WEBSOCKET_LIB_H_ |
Stephan Pleines | b117767 | 2024-05-27 17:48:32 -0700 | [diff] [blame^] | 3 | #include <stdint.h> |
| 4 | |
James Kuszmaul | 0de4feb | 2022-04-15 12:16:59 -0700 | [diff] [blame] | 5 | #include <map> |
Stephan Pleines | b117767 | 2024-05-27 17:48:32 -0700 | [diff] [blame^] | 6 | #include <memory> |
James Kuszmaul | 0de4feb | 2022-04-15 12:16:59 -0700 | [diff] [blame] | 7 | #include <set> |
| 8 | |
James Kuszmaul | 0de4feb | 2022-04-15 12:16:59 -0700 | [diff] [blame] | 9 | #include "foxglove/websocket/server.hpp" |
| 10 | |
Philipp Schrader | 790cb54 | 2023-07-05 21:06:52 -0700 | [diff] [blame] | 11 | #include "aos/events/event_loop.h" |
| 12 | |
James Kuszmaul | 0de4feb | 2022-04-15 12:16:59 -0700 | [diff] [blame] | 13 | namespace 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. |
| 19 | class FoxgloveWebsocketServer { |
| 20 | public: |
James Kuszmaul | f1dbaff | 2023-02-08 21:17:32 -0800 | [diff] [blame] | 21 | // 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 Kuszmaul | 1e418f6 | 2023-02-26 14:40:20 -0800 | [diff] [blame] | 31 | // 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 Kuszmaul | f1dbaff | 2023-02-08 21:17:32 -0800 | [diff] [blame] | 41 | FoxgloveWebsocketServer(aos::EventLoop *event_loop, uint32_t port, |
| 42 | Serialization serialization, |
James Kuszmaul | 1e418f6 | 2023-02-26 14:40:20 -0800 | [diff] [blame] | 43 | FetchPinnedChannels fetch_pinned_channels, |
| 44 | CanonicalChannelNames canonical_channels); |
James Kuszmaul | 0de4feb | 2022-04-15 12:16:59 -0700 | [diff] [blame] | 45 | ~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 Kuszmaul | f1dbaff | 2023-02-08 21:17:32 -0800 | [diff] [blame] | 63 | const Serialization serialization_; |
| 64 | const FetchPinnedChannels fetch_pinned_channels_; |
James Kuszmaul | 1e418f6 | 2023-02-26 14:40:20 -0800 | [diff] [blame] | 65 | const CanonicalChannelNames canonical_channels_; |
James Kuszmaul | 0de4feb | 2022-04-15 12:16:59 -0700 | [diff] [blame] | 66 | 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_ |