VLink 2.0.0
A high-performance communication middleware
载入中...
搜索中...
未找到
proxy_api.h
浏览该文件的文档.
1/*
2 * Copyright (C) 2026 by Thun Lu. All rights reserved.
3 * Author: Thun Lu <thun.lu@zohomail.cn>
4 * Repo: https://github.com/thun-res/vlink
5 * _ __ __ _ __
6 * | | / / / / (_) ____ / /__
7 * | | / / / / / / / __ \ / //_/
8 * | |/ / / /___ / / / / / / / ,<
9 * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24/**
25 * @file proxy_api.h
26 * @brief Client-side VLink proxy monitoring and control API.
27 *
28 * @details
29 * @c ProxyAPI provides a C++ interface for connecting to a running @c ProxyServer
30 * daemon. It inherits from @c MessageLoop, but incoming DDS/SHM callbacks may
31 * execute on transport-managed receive threads. The inherited @c MessageLoop is
32 * used for posted tasks and timers when @c run() or @c async_run() is started.
33 *
34 * @par Roles
35 * A @c ProxyAPI instance operates in one of two roles:
36 *
37 * | Role | Description |
38 * | ------------- | ------------------------------------------------------------------------ |
39 * | kController | Can send Control messages to direct the server's observation/playback. |
40 * | kListener | Passive observer only; send_control() and send_data() are rejected. |
41 *
42 * @par Operation Modes
43 * The proxy server supports eight operation modes, selectable by @c kController:
44 *
45 * | Mode | Value | Description |
46 * | ----------------- | ----- | ------------------------------------------------------- |
47 * | kOffline | 0 | Disconnected; server releases all subscriptions. |
48 * | kObserveOne | 1 | Observe a single selected topic. |
49 * | kObserveAll | 2 | Observe all discovered topics. |
50 * | kRecord | 3 | Record all topics matching the subscription URL list. |
51 * | kPlay | 4 | Replay previously recorded data via the server. |
52 * | kEdit | 5 | Edit mode: injects data through the server. |
53 * | kAuto | 6 | Auto mode: observe specified topics. |
54 * | kAutoAndObserveAll| 7 | Auto + observe all topics simultaneously. |
55 *
56 * @par Error Codes
57 *
58 * | Error | Value | Description |
59 * | --------------------- | ----- | ------------------------------------------------- |
60 * | kNoError | 0 | No error. |
61 * | kModeError | 1 | Unsupported mode requested. |
62 * | kControlError | 2 | Control ID mismatch with the server. |
63 * | kReliableCompError | 3 | reliable setting mismatch between client/server. |
64 * | kTcpCompError | 4 | enable_tcp setting mismatch. |
65 * | kDirectCompError | 5 | direct setting mismatch. |
66 * | kMultiProxyError | 7 | Multiple proxy servers detected on the network. |
67 * | kVersionCompError | 8 | VLink version mismatch between client and server. |
68 * | kUnknownError | 9 | Unknown error. |
69 *
70 * @par Connectivity and Heartbeat
71 * Internally the API subscribes to a 1-second Time heartbeat published by
72 * @c ProxyServer over a security-authenticated DDS channel. If no heartbeat is
73 * received for 5 consecutive seconds the connection is declared lost and
74 * @c ConnectCallback is invoked with @c connected = @c false. A @c kController
75 * client also sends an initial @c Control message at construction and re-sends
76 * the last control automatically when the server reconnects.
77 *
78 * @par Communication Channels
79 * The transport channels are determined by @c Config::direct:
80 *
81 * | direct | Data path | Control/Info/Time path |
82 * | ------ | --------------------------- | -------------------------- |
83 * | false | DDS (reliable or best-effort) | DDS (security-enabled) |
84 * | true | SHM (Iceoryx) | DDS (security-enabled) |
85 *
86 * @par Version Matching
87 * When @c Config::match_version is @c true (default) the client checks that
88 * the server's reported @c VLINK_VERSION string matches its own at connection
89 * time. A mismatch triggers @c kVersionCompError.
90 *
91 * @par Usage Example (Controller)
92 * @code
93 * vlink::ProxyAPI::Config cfg;
94 * cfg.role = vlink::ProxyAPI::kController;
95 * cfg.dds_impl = "dds";
96 * cfg.domain_id = 0;
97 * cfg.reliable = false;
98 * cfg.match_version = true;
99 *
100 * vlink::ProxyAPI api(cfg);
101 *
102 * api.register_connect_callback([](bool connected) {
103 * if (connected) {
104 * // server is online
105 * }
106 * });
107 *
108 * api.register_info_callback([](const std::vector<vlink::ProxyAPI::Info>& list) {
109 * for (const auto& info : list) {
110 * // info.url, info.freq, info.status, ...
111 * }
112 * });
113 *
114 * // Start observing a specific topic
115 * vlink::ProxyAPI::Control ctrl;
116 * ctrl.mode = vlink::ProxyAPI::kObserveOne;
117 * ctrl.url_meta_list.emplace_back(
118 * {"dds://my/topic", "demo.proto.PointCloud", vlink::SchemaType::kProtobuf, vlink::kSubscriber});
119 * api.send_control(ctrl);
120 *
121 * api.async_run(); // optional: runs the inherited MessageLoop on a background thread
122 * @endcode
123 *
124 * @note
125 * - Only one @c ProxyServer should exist on a given DDS domain/channel at a time;
126 * connecting to two will trigger @c kMultiProxyError.
127 * - @c send_control() and @c send_data() return @c false immediately when the
128 * role is @c kListener.
129 */
130
131#pragma once
132
133#undef VLINK_PROXY_API_EXPORT
134#ifdef VLINK_PROXY_API_LIBRARY_STATIC
135#define VLINK_PROXY_API_EXPORT
136#elif defined(_WIN32) || defined(__CYGWIN__)
137#ifdef VLINK_PROXY_API_LIBRARY
138#define VLINK_PROXY_API_EXPORT __declspec(dllexport)
139#else
140#define VLINK_PROXY_API_EXPORT __declspec(dllimport)
141#endif
142#else
143#define VLINK_PROXY_API_EXPORT __attribute__((visibility("default")))
144#endif
145
146#include <cstdint>
147#include <memory>
148#include <string>
149#include <unordered_set>
150#include <vector>
151
152#include "../base/bytes.h"
153#include "../base/message_loop.h"
154#include "../impl/types.h"
155
156namespace vlink {
157
158/**
159 * @class ProxyAPI
160 * @brief Client-side proxy monitoring and control API backed by a MessageLoop.
161 *
162 * @details
163 * Connects to a @c ProxyServer daemon over DDS (or SHM in direct mode) and
164 * exposes callbacks for connection state, error codes, heartbeat timestamps,
165 * topic statistics, and raw data payloads. Inherits @c MessageLoop; start the
166 * loop explicitly if you need queued tasks, timers, or async control posts to
167 * execute on that loop.
168 */
170 public:
171 /**
172 * @enum Mode
173 * @brief Proxy operation modes sent via @c send_control().
174 *
175 * @details
176 * The mode governs what the @c ProxyServer observes or replays.
177 * Only a @c kController client may change the mode.
178 */
179 enum Mode : uint8_t {
180 kOffline = 0, ///< Disconnected; server releases all subscriptions.
181 kObserveOne = 1, ///< Observe a single topic from the URL list.
182 kObserveAll = 2, ///< Observe all discovered topics on the network.
183 kRecord = 3, ///< Record data from topics in the URL list.
184 kPlay = 4, ///< Replay: inject previously recorded data.
185 kEdit = 5, ///< Edit: forward data injected by the controller.
186 kAuto = 6, ///< Auto: observe specified URLs and forward to subscribers.
187 kAutoAndObserveAll = 7, ///< Auto + observe every discovered topic.
188 };
189
190 /**
191 * @enum Error
192 * @brief Compatibility and protocol error codes reported via @c ErrorCallback.
193 *
194 * @details
195 * Errors are detected when the client parses an incoming @c Time heartbeat.
196 * The callback fires only when the error state changes.
197 */
198 enum Error : uint8_t {
199 kNoError = 0, ///< No error; connection is healthy.
200 kModeError = 1, ///< Unsupported mode requested.
201 kControlError = 2, ///< Server responded with a different control_id.
202 kReliableCompError = 3, ///< Client and server have mismatched reliable setting.
203 kTcpCompError = 4, ///< Client and server have mismatched enable_tcp setting.
204 kDirectCompError = 5, ///< Client and server have mismatched direct setting.
205 kMultiProxyError = 7, ///< Multiple proxy servers detected on the same domain.
206 kVersionCompError = 8, ///< VLINK_VERSION string differs between client and server.
207 kUnknownError = 9, ///< Unknown or unclassified error.
208 };
209
210 /**
211 * @enum Status
212 * @brief Per-topic activity status reported in @c Info.
213 */
214 enum Status : uint8_t {
215 kActive = 0, ///< Topic is actively receiving data.
216 kInActive = 1, ///< Topic exists but has not received data recently.
217 kPending = 2, ///< Topic was just discovered; statistics are still accumulating.
218 kInvalid = 3, ///< Topic type does not support observation (e.g., subscriber-only).
219 };
220
221 /**
222 * @enum Role
223 * @brief Role of this @c ProxyAPI instance.
224 *
225 * @details
226 * - @c kController can call @c send_control() and @c send_data().
227 * - @c kListener is a passive observer; control/data send calls return @c false.
228 */
229 enum Role : uint8_t { kController = 0, kListener };
230
231 /**
232 * @struct Process
233 * @brief Describes a VLink node process attached to a topic endpoint.
234 */
235 struct Process final {
236 uint32_t type{0}; ///< Node type bitmask (kPublisher / kSubscriber / kServer / kClient / kSetter / kGetter).
237 std::string host; ///< Hostname of the machine running the process.
238 uint32_t pid{0}; ///< Operating-system process ID.
239 std::string name; ///< Human-readable process name.
240 std::string ip; ///< IP address of the network interface.
241 };
242
243 /**
244 * @struct Info
245 * @brief Statistics and metadata for a single discovered topic endpoint.
246 *
247 * @details
248 * Delivered in batches via @c InfoCallback once per second. The fields
249 * @c freq, @c rate, @c loss, and @c latency are weighted moving averages
250 * computed over the last two 1-second collection intervals.
251 */
252 struct Info final {
253 uint32_t type{0}; ///< Node type bitmask for this endpoint.
254 std::string url; ///< Full topic URL, e.g. @c "dds://my/topic".
255 std::string ser; ///< Serialisation type, e.g. @c "demo.proto.PointCloud".
256 SchemaType schema{SchemaType::kUnknown}; ///< Coarse schema family of the payload.
257 Status status{kInvalid}; ///< Activity status of the topic.
258 float freq{0}; ///< Observed message frequency in messages/s.
259 uint64_t rate{0}; ///< Observed throughput in bytes/s.
260 float loss{0}; ///< Sample loss ratio in the range [0, 1].
261 float latency{0}; ///< End-to-end latency in milliseconds.
262 std::vector<Process> process_list; ///< List of connected publisher/subscriber processes.
263 };
264
265 /**
266 * @struct UrlMeta
267 * @brief Associates a topic URL with its serialisation type and node role.
268 *
269 * @details
270 * Used in @c Control::url_meta_list to instruct the server which topics to
271 * subscribe to or publish on.
272 */
273 struct UrlMeta final {
274 std::string url; ///< Full topic URL.
275 std::string ser; ///< Required serialisation type carried on this proxy route.
276 SchemaType schema{SchemaType::kUnknown}; ///< Required coarse schema family carried on this proxy route.
277 ImplType type{kSubscriber}; ///< Whether the server should act as publisher or subscriber for this URL.
278 };
279
280 /**
281 * @struct Control
282 * @brief Control message sent from a @c kController client to @c ProxyServer.
283 *
284 * @details
285 * Sets the server's operating mode and the list of topics to observe or play.
286 * The @c filter_str is a space-separated list of substrings; topics (or process
287 * names when @c filter_by_process is @c true) must contain at least one
288 * substring to be included.
289 */
290 struct Control final {
291 Mode mode{kOffline}; ///< Target operation mode.
292 std::vector<UrlMeta> url_meta_list; ///< Topics to observe / inject (mode-dependent).
293 bool filter_by_process{false}; ///< When true, filter_str matches process names; otherwise matches URLs.
294 std::string filter_str; ///< Space-separated filter keywords (case-insensitive).
295 uint32_t filter_type{0}; ///< Type filter: 0=all, 1=pub+sub pair, 2=srv+cli pair, etc.
296 };
297
298 /**
299 * @struct Data
300 * @brief Raw message payload delivered via @c DataCallback or sent via @c send_data().
301 *
302 * @details
303 * In record/observe mode the server relays raw serialised bytes together with
304 * routing metadata. @c timestamp is the elapsed time in microseconds since the
305 * current proxy data session / control generation started; @c seq is the proxy
306 * relay sequence number for the URL.
307 */
308 struct Data final {
309 std::string url; ///< Topic URL the data was captured on.
310 std::string ser; ///< Serialisation type of the payload.
311 SchemaType schema{SchemaType::kUnknown}; ///< Coarse schema family of the payload.
312 Bytes raw; ///< Raw serialised message bytes.
313 int64_t timestamp{-1}; ///< Elapsed time in microseconds since session start; -1 if unset.
314 int64_t seq{0}; ///< Publisher sequence number.
315 };
316
317 /**
318 * @struct Config
319 * @brief Construction-time configuration for @c ProxyAPI.
320 *
321 * @details
322 * All fields must be set consistently with the @c ProxyServer::Config they
323 * connect to; a mismatch on @c reliable, @c enable_tcp, or @c direct will
324 * trigger the corresponding @c Error code once the client receives the first
325 * heartbeat.
326 */
327 struct Config final {
328 Role role{kController}; ///< Role of this client instance.
329 int domain_id{0}; ///< DDS domain ID; must match the server's domain_id.
330 std::string dds_impl{"dds"}; ///< DDS implementation transport: "dds", "ddsc", "ddsr", etc.
331 std::string security_key; ///< Optional security key for encrypted DDS channels; must match the server key.
332 bool native{false}; ///< When true, restricts all DDS traffic to 127.0.0.1 (loopback only).
333 bool reliable{false}; ///< Use reliable DDS QoS; must match the server's reliable setting.
334 bool direct{false}; ///< Use direct SHM channels for data; must match the server's direct setting.
335 bool enable_tcp{false}; ///< Use TCP transport for data channels; must match the server's enable_tcp.
336 bool match_version{true}; ///< Reject connections when the server's VLINK_VERSION differs from the client.
337 std::string allow_ip; ///< Bind DDS sockets to this IP address (empty = any).
338 std::string peer_ip; ///< Unicast peer IP for DDS discovery (empty = multicast).
339 int buf_size{0}; ///< Socket send/receive buffer size in bytes; 0 uses the built-in default.
340 int mtu_size{0}; ///< DDS MTU size in bytes; 0 uses the built-in default.
341 };
342
343 /**
344 * @brief Callback invoked when the connection state with @c ProxyServer changes.
345 *
346 * @details
347 * @c connected is @c true when the first valid heartbeat is received; @c false
348 * when 5 seconds pass without a heartbeat or when the control channel disconnects.
349 */
350 using ConnectCallback = std::function<void(bool connected)>;
351
352 /**
353 * @brief Callback invoked when an error or error-clear event is detected.
354 *
355 * @details
356 * Only fired when the @c Error state transitions (e.g. @c kNoError to
357 * @c kVersionCompError, or back to @c kNoError).
358 */
359 using ErrorCallback = std::function<void(Error error)>;
360
361 /**
362 * @brief Callback delivering the server's wall-clock and boot-time from each heartbeat.
363 *
364 * @param sys_time Server system time in microseconds since the Unix epoch.
365 * @param boot_time Server uptime in microseconds since boot.
366 */
367 using TimeCallback = std::function<void(uint64_t sys_time, uint64_t boot_time)>;
368
369 /**
370 * @brief Callback delivering the per-topic statistics list once per second.
371 *
372 * @param info_list List of @c Info records for all currently observed topics.
373 */
374 using InfoCallback = std::function<void(const std::vector<Info>& info_list)>;
375
376 /**
377 * @brief Callback delivering raw message data relayed by @c ProxyServer.
378 *
379 * @details
380 * Fired for every message forwarded by the server in observe, record, or
381 * play mode. The @c Data::raw bytes are shallow-borrowed; copy if you need
382 * to retain them beyond the callback.
383 */
384 using DataCallback = std::function<void(const Data& data)>;
385
386 /**
387 * @brief Constructs a @c ProxyAPI with the given configuration.
388 *
389 * @details
390 * Initialises all DDS/SHM channels based on @c config. A unique @c control_id
391 * is derived from the CPU timestamp at construction time so that the server can
392 * distinguish simultaneous controllers. The inherited @c MessageLoop is not
393 * started automatically; call @c run() or @c async_run() yourself if you need
394 * timer-driven reconnect logic or queued control posts to execute.
395 *
396 * @param config Configuration for the proxy connection.
397 */
398 explicit ProxyAPI(const Config& config);
399
400 /**
401 * @brief Destructor.
402 *
403 * @details
404 * Quits the inherited @c MessageLoop (if it is running), waits for it to stop,
405 * and then releases DDS/SHM handles. Destruction does not publish an extra
406 * @c kOffline control message.
407 */
408 ~ProxyAPI() override;
409
410 /**
411 * @brief Registers a callback for connection state changes.
412 *
413 * @details
414 * If the API is already connected when this method is called the callback
415 * is invoked immediately with @c connected = @c true inside this call.
416 * The callback is replaced atomically; only one callback is active at a time.
417 *
418 * @param callback Callable with signature @c void(bool connected).
419 */
421
422 /**
423 * @brief Registers a callback for error state transitions.
424 *
425 * @details
426 * If a non-zero error is already active when this method is called the
427 * callback is invoked immediately with the current error inside this call.
428 *
429 * @param callback Callable with signature @c void(Error error).
430 */
432
433 /**
434 * @brief Registers a callback for heartbeat timestamp delivery.
435 *
436 * @details
437 * If timestamps have already been received (timers are active) the callback
438 * is invoked immediately with the latest extrapolated times inside this call.
439 *
440 * @param callback Callable with signature @c void(uint64_t sys_time, uint64_t boot_time).
441 */
443
444 /**
445 * @brief Registers a callback for per-topic statistics updates.
446 *
447 * @details
448 * Invoked once per second with the full @c Info list from the server.
449 * No immediate invocation occurs at registration; data arrives on the next
450 * server broadcast cycle.
451 *
452 * @param callback Callable with signature @c void(const std::vector<Info>& info_list).
453 */
455
456 /**
457 * @brief Registers a callback for raw message data relayed by the server.
458 *
459 * @details
460 * No immediate invocation occurs at registration. Data arrives when the
461 * server is in a mode that forwards messages (kObserveOne, kObserveAll,
462 * kRecord, kAuto, kAutoAndObserveAll).
463 *
464 * @param callback Callable with signature @c void(const Data& data).
465 */
467
468 /**
469 * @brief Sends a @c Control message to the @c ProxyServer.
470 *
471 * @details
472 * Only valid when the role is @c kController; returns @c false immediately
473 * for @c kListener. The control is cached internally and automatically
474 * re-sent if the server reconnects after a dropout.
475 *
476 * When @c async is @c true (default) the DDS publish is posted to the
477 * MessageLoop thread; when @c false it is executed synchronously on the
478 * calling thread.
479 *
480 * Every entry in @c control.url_meta_list must provide both @c ser and a
481 * known @c schema value. Proxy no longer back-fills missing routing
482 * metadata from discovery caches because that would hide broken
483 * schema-propagation paths.
484 *
485 * If @c direct mode is configured, corresponding SHM publishers are created
486 * or destroyed to match publisher entries in @c url_meta_list. Direct
487 * subscribers are synchronised either from subscriber entries in
488 * @c url_meta_list or, for @c kObserveAll / @c kAutoAndObserveAll, from the
489 * latest @c Info list reported by the server.
490 *
491 * @param control Control message to send.
492 * @param async @c true to post asynchronously (default); @c false to block.
493 * @return @c true on success; @c false if role is @c kListener or
494 * the API is shutting down.
495 */
496 bool send_control(const Control& control, bool async = true);
497
498 /**
499 * @brief Sends raw message data to the @c ProxyServer for injection.
500 *
501 * @details
502 * Only valid when the role is @c kController; returns @c false for @c kListener.
503 * In direct mode the data is published directly on the SHM publisher
504 * corresponding to @c data.url. In non-direct mode it is wrapped in a
505 * @c ProxyData envelope and forwarded over the DDS data channel.
506 *
507 * Returns @c false if no subscribers are listening on the target channel.
508 *
509 * The caller must provide both @c data.ser and a known @c data.schema.
510 * Proxy no longer guesses the decode stack from cached discovery metadata.
511 *
512 * @param data Data to inject, including URL, serialisation type, schema
513 * family, raw bytes, timestamp, and sequence number.
514 * @return @c true if data was published; @c false otherwise.
515 */
516 bool send_data(const Data& data);
517
518 /**
519 * @brief Returns the configuration passed at construction.
520 *
521 * @return Const reference to the internal @c Config.
522 */
523 [[nodiscard]] const Config& get_current_config() const;
524
525 /**
526 * @brief Returns the current proxy operation mode.
527 *
528 * @details
529 * Reflects the mode most recently set by @c send_control(). Updated
530 * immediately on the calling thread before any async DDS publish.
531 *
532 * @return Current @c Mode value.
533 */
534 [[nodiscard]] Mode get_current_mode() const;
535
536 /**
537 * @brief Returns the current error state.
538 *
539 * @return Current @c Error value; @c kNoError when no error is active.
540 */
541 [[nodiscard]] Error get_current_error() const;
542
543 /**
544 * @brief Returns the hostname of the connected @c ProxyServer.
545 *
546 * @details
547 * Populated from the server's @c Time heartbeat. Returns an empty string
548 * before the first heartbeat is received or after disconnection.
549 *
550 * @return Hostname string, or empty if not yet connected.
551 */
552 [[nodiscard]] std::string get_current_hostname() const;
553
554 /**
555 * @brief Returns the machine ID of the connected @c ProxyServer.
556 *
557 * @details
558 * Populated from the server's @c Time heartbeat. Returns an empty string
559 * before the first heartbeat is received.
560 *
561 * @return Machine ID string, or empty if not yet connected.
562 */
563 [[nodiscard]] std::string get_current_machine_id() const;
564
565 /**
566 * @brief Returns the best estimate of the server's current wall-clock time.
567 *
568 * @details
569 * Computed as the last received @c sys_time plus the elapsed microseconds
570 * since that heartbeat, extrapolated via an @c ElapsedTimer. Returns the
571 * raw @c sys_time field if the timer is not yet running.
572 *
573 * @return Estimated server system time in microseconds since the Unix epoch.
574 */
575 [[nodiscard]] uint64_t get_current_sys_time() const;
576
577 /**
578 * @brief Returns the best estimate of the server's current boot time.
579 *
580 * @details
581 * Computed as the last received @c boot_time plus the elapsed microseconds
582 * since that heartbeat, extrapolated via an @c ElapsedTimer.
583 *
584 * @return Estimated server uptime in microseconds since boot.
585 */
586 [[nodiscard]] uint64_t get_current_boot_time() const;
587
588 /**
589 * @brief Returns the server's most recently reported CPU utilisation.
590 *
591 * @return CPU usage as a percentage in the range [0, 100]. Returns 0 when
592 * disconnected.
593 */
594 [[nodiscard]] double get_current_cpu_usage() const;
595
596 /**
597 * @brief Returns the server's most recently reported memory utilisation.
598 *
599 * @return Memory usage as a percentage in the range [0, 100]. Returns 0 when
600 * disconnected.
601 */
602 [[nodiscard]] double get_current_memory_usage() const;
603
604 /**
605 * @brief Returns the measured round-trip latency on the data channel.
606 *
607 * @details
608 * In direct (SHM) mode this always returns 0 because latency measurement is
609 * not available on the SHM data channel. In DDS mode it delegates to the
610 * underlying data subscriber's latency tracker.
611 *
612 * @return Latency in microseconds, or 0 in direct mode.
613 */
614 [[nodiscard]] int64_t get_latency() const;
615
616 /**
617 * @brief Returns the sample loss statistics on the data channel.
618 *
619 * @details
620 * In direct (SHM) mode returns a default-constructed (zero) @c SampleLostInfo.
621 * In DDS mode it delegates to the underlying data subscriber.
622 *
623 * @return @c SampleLostInfo with total and lost sample counts.
624 */
625 [[nodiscard]] SampleLostInfo get_lost() const;
626
627 /**
628 * @brief Returns @c true when a valid connection to @c ProxyServer exists.
629 *
630 * @details
631 * Set to @c true on receipt of a valid @c Time heartbeat; set to @c false
632 * when 5 seconds elapse without a heartbeat or when the control channel
633 * reports disconnection.
634 *
635 * @return @c true if connected, @c false otherwise.
636 */
637 [[nodiscard]] bool is_connected() const;
638
639 /**
640 * @brief Returns the @c VLINK_VERSION string reported by the server.
641 *
642 * @details
643 * Populated from the first valid heartbeat. Returns an empty string before
644 * connection or after disconnection.
645 *
646 * @return Server VLink version string, e.g. @c "2.0.0".
647 */
648 [[nodiscard]] std::string get_proxy_version() const;
649
650 /**
651 * @brief Returns the set of all server hostnames seen during this session.
652 *
653 * @details
654 * Hostnames are accumulated over the lifetime of the connection; they are
655 * NOT cleared on disconnection, only when a new @c reset_handle() is triggered.
656 *
657 * @return Unordered set of hostname strings.
658 */
659 [[nodiscard]] std::unordered_set<std::string> get_proxy_hostnames() const;
660
661 /**
662 * @brief Returns the set of all server machine IDs seen during this session.
663 *
664 * @details
665 * Analogous to @c get_proxy_hostnames(); accumulated over the lifetime of
666 * the connection.
667 *
668 * @return Unordered set of machine ID strings.
669 */
670 [[nodiscard]] std::unordered_set<std::string> get_proxy_machine_ids() const;
671
672 /**
673 * @brief Returns @c true if the build includes SHM (Iceoryx) support.
674 *
675 * @details
676 * Determined at compile time by the @c VLINK_SUPPORT_SHM macro. Useful for
677 * checking whether @c Config::direct can be used.
678 *
679 * @return @c true when SHM support is compiled in.
680 */
681 [[nodiscard]] static bool is_support_shm();
682
683 /**
684 * @brief Returns @c true if topic filtering support is compiled in.
685 *
686 * @details
687 * Determined at compile time by @c VLINK_PROXY_ENABLE_FILTER. When @c false
688 * the @c filter_str and @c filter_by_process fields in @c Control are ignored
689 * by the server.
690 *
691 * @return @c true when filtering is enabled.
692 */
693 [[nodiscard]] static bool is_enable_filter();
694
695 /**
696 * @brief Formats a microsecond wall-clock timestamp as a human-readable string.
697 *
698 * @details
699 * Output format: @c "YYYY/MM/DD HH:MM:SS:mmm" where @c mmm is milliseconds.
700 * Uses @c localtime_r by default; @c gmtime_r when @c enable_utc is @c true.
701 *
702 * @param time Microseconds since the Unix epoch.
703 * @param enable_utc @c true for UTC; @c false for local time (default).
704 * @return Formatted timestamp string, or empty on conversion error.
705 */
706 [[nodiscard]] static std::string get_format_sys_time(uint64_t time, bool enable_utc = false);
707
708 /**
709 * @brief Formats a microsecond boot-time duration as a human-readable string.
710 *
711 * @details
712 * Converts @p time (microseconds since boot) to a formatted elapsed-time
713 * string, e.g. @c "0d 01:23:45.678".
714 *
715 * @param time Microseconds since boot.
716 * @return Formatted elapsed-time string.
717 */
718 [[nodiscard]] static std::string get_format_boot_time(uint64_t time);
719
720 protected:
721 size_t get_max_task_count() const override;
722
723 uint32_t get_max_elapsed_time() const override;
724
725 void on_begin() override;
726
727 void on_end() override;
728
729 private:
730 bool send_control_sync(const Control& control);
731
732 void sync_direct_maps(const Control& control);
733
734 void reset_handle();
735
736 void process_connected(bool connected);
737
738 void process_time(uint64_t sys_time, uint64_t boot_time);
739
740 void process_error(Error error);
741
742 std::unique_ptr<struct ProxyAPIImpl> impl_;
743
745};
746
747} // namespace vlink
Versatile byte buffer with small-buffer optimisation, ownership semantics and compression.
#define VLINK_DISALLOW_COPY_AND_ASSIGN(classname)
Deletes the copy constructor and copy-assignment operator of classname.
定义 macros.h:184
Single-threaded event loop with three queue types, timer management and task scheduling.
#define VLINK_PROXY_API_EXPORT
定义 proxy_api.h:143
Core type definitions shared across all VLink node implementations.