WPILibC++ 2023.4.3-108-ge5452e3
WebSocket.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#ifndef WPINET_WEBSOCKET_H_
6#define WPINET_WEBSOCKET_H_
7
8#include <stdint.h>
9
10#include <functional>
11#include <initializer_list>
12#include <memory>
13#include <span>
14#include <string>
15#include <string_view>
16#include <utility>
17
18#include <wpi/Signal.h>
19#include <wpi/SmallVector.h>
20
21#include "wpinet/uv/Buffer.h"
22#include "wpinet/uv/Error.h"
23#include "wpinet/uv/Timer.h"
24
25namespace wpi {
26
27namespace uv {
28class Stream;
29} // namespace uv
30
31/**
32 * RFC 6455 compliant WebSocket client and server implementation.
33 */
34class WebSocket : public std::enable_shared_from_this<WebSocket> {
35 struct private_init {};
36
37 static constexpr uint8_t kOpCont = 0x00;
38 static constexpr uint8_t kOpText = 0x01;
39 static constexpr uint8_t kOpBinary = 0x02;
40 static constexpr uint8_t kOpClose = 0x08;
41 static constexpr uint8_t kOpPing = 0x09;
42 static constexpr uint8_t kOpPong = 0x0A;
43 static constexpr uint8_t kOpMask = 0x0F;
44 static constexpr uint8_t kFlagFin = 0x80;
45
46 public:
47 WebSocket(uv::Stream& stream, bool server, const private_init&);
48 WebSocket(const WebSocket&) = delete;
49 WebSocket(WebSocket&&) = delete;
50 WebSocket& operator=(const WebSocket&) = delete;
53
54 /**
55 * Connection states.
56 */
57 enum State {
58 /** The connection is not yet open. */
60 /** The connection is open and ready to communicate. */
62 /** The connection is in the process of closing. */
64 /** The connection failed. */
66 /** The connection is closed. */
67 CLOSED
68 };
69
70 /**
71 * Client connection options.
72 */
74 ClientOptions() : handshakeTimeout{(uv::Timer::Time::max)()} {}
75
76 /** Timeout for the handshake request. */
78
79 /** Additional headers to include in handshake. */
80 std::span<const std::pair<std::string_view, std::string_view>> extraHeaders;
81 };
82
83 /**
84 * Frame. Used by SendFrames().
85 */
86 struct Frame {
87 static constexpr uint8_t kText = kFlagFin | kOpText;
88 static constexpr uint8_t kBinary = kFlagFin | kOpBinary;
89 static constexpr uint8_t kTextFragment = kOpText;
90 static constexpr uint8_t kBinaryFragment = kOpBinary;
91 static constexpr uint8_t kFragment = kOpCont;
92 static constexpr uint8_t kFinalFragment = kFlagFin | kOpCont;
93 static constexpr uint8_t kPing = kFlagFin | kOpPing;
94 static constexpr uint8_t kPong = kFlagFin | kOpPong;
95
96 Frame(uint8_t opcode, std::span<const uv::Buffer> data)
97 : opcode{opcode}, data{data} {}
98
100 std::span<const uv::Buffer> data;
101 };
102
103 /**
104 * Starts a client connection by performing the initial client handshake.
105 * An open event is emitted when the handshake completes.
106 * This sets the stream user data to the websocket.
107 * @param stream Connection stream
108 * @param uri The Request-URI to send
109 * @param host The host or host:port to send
110 * @param protocols The list of subprotocols
111 * @param options Handshake options
112 */
113 static std::shared_ptr<WebSocket> CreateClient(
115 std::span<const std::string_view> protocols = {},
116 const ClientOptions& options = {});
117
118 /**
119 * Starts a client connection by performing the initial client handshake.
120 * An open event is emitted when the handshake completes.
121 * This sets the stream user data to the websocket.
122 * @param stream Connection stream
123 * @param uri The Request-URI to send
124 * @param host The host or host:port to send
125 * @param protocols The list of subprotocols
126 * @param options Handshake options
127 */
128 static std::shared_ptr<WebSocket> CreateClient(
130 std::initializer_list<std::string_view> protocols,
131 const ClientOptions& options = {}) {
132 return CreateClient(stream, uri, host, {protocols.begin(), protocols.end()},
133 options);
134 }
135
136 /**
137 * Starts a server connection by performing the initial server side handshake.
138 * This should be called after the HTTP headers have been received.
139 * An open event is emitted when the handshake completes.
140 * This sets the stream user data to the websocket.
141 * @param stream Connection stream
142 * @param key The value of the Sec-WebSocket-Key header field in the client
143 * request
144 * @param version The value of the Sec-WebSocket-Version header field in the
145 * client request
146 * @param protocol The subprotocol to send to the client (in the
147 * Sec-WebSocket-Protocol header field).
148 */
149 static std::shared_ptr<WebSocket> CreateServer(
150 uv::Stream& stream, std::string_view key, std::string_view version,
151 std::string_view protocol = {});
152
153 /**
154 * Get connection state.
155 */
156 State GetState() const { return m_state; }
157
158 /**
159 * Return if the connection is open. Messages can only be sent on open
160 * connections.
161 */
162 bool IsOpen() const { return m_state == OPEN; }
163
164 /**
165 * Get the underlying stream.
166 */
167 uv::Stream& GetStream() const { return m_stream; }
168
169 /**
170 * Get the selected sub-protocol. Only valid in or after the open() event.
171 */
172 std::string_view GetProtocol() const { return m_protocol; }
173
174 /**
175 * Set the maximum message size. Default is 128 KB. If configured to combine
176 * fragments this maximum applies to the entire message (all combined
177 * fragments).
178 * @param size Maximum message size in bytes
179 */
180 void SetMaxMessageSize(size_t size) { m_maxMessageSize = size; }
181
182 /**
183 * Set whether or not fragmented frames should be combined. Default is to
184 * combine. If fragmented frames are combined, the text and binary callbacks
185 * will always have the second parameter (fin) set to true.
186 * @param combine True if fragmented frames should be combined.
187 */
188 void SetCombineFragments(bool combine) { m_combineFragments = combine; }
189
190 /**
191 * Initiate a closing handshake.
192 * @param code A numeric status code (defaults to 1005, no status code)
193 * @param reason A human-readable string explaining why the connection is
194 * closing (optional).
195 */
196 void Close(uint16_t code = 1005, std::string_view reason = {});
197
198 /**
199 * Send a text message.
200 * @param data UTF-8 encoded data to send
201 * @param callback Callback which is invoked when the write completes.
202 */
204 std::span<const uv::Buffer> data,
205 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
206 Send(kFlagFin | kOpText, data, std::move(callback));
207 }
208
209 /**
210 * Send a text message.
211 * @param data UTF-8 encoded data to send
212 * @param callback Callback which is invoked when the write completes.
213 */
215 std::initializer_list<uv::Buffer> data,
216 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
217 SendText({data.begin(), data.end()}, std::move(callback));
218 }
219
220 /**
221 * Send a binary message.
222 * @param data Data to send
223 * @param callback Callback which is invoked when the write completes.
224 */
226 std::span<const uv::Buffer> data,
227 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
228 Send(kFlagFin | kOpBinary, data, std::move(callback));
229 }
230
231 /**
232 * Send a binary message.
233 * @param data Data to send
234 * @param callback Callback which is invoked when the write completes.
235 */
237 std::initializer_list<uv::Buffer> data,
238 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
239 SendBinary({data.begin(), data.end()}, std::move(callback));
240 }
241
242 /**
243 * Send a text message fragment. This must be followed by one or more
244 * SendFragment() calls, where the last one has fin=True, to complete the
245 * message.
246 * @param data UTF-8 encoded data to send
247 * @param callback Callback which is invoked when the write completes.
248 */
250 std::span<const uv::Buffer> data,
251 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
252 Send(kOpText, data, std::move(callback));
253 }
254
255 /**
256 * Send a text message fragment. This must be followed by one or more
257 * SendFragment() calls, where the last one has fin=True, to complete the
258 * message.
259 * @param data UTF-8 encoded data to send
260 * @param callback Callback which is invoked when the write completes.
261 */
263 std::initializer_list<uv::Buffer> data,
264 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
265 SendTextFragment({data.begin(), data.end()}, std::move(callback));
266 }
267
268 /**
269 * Send a text message fragment. This must be followed by one or more
270 * SendFragment() calls, where the last one has fin=True, to complete the
271 * message.
272 * @param data Data to send
273 * @param callback Callback which is invoked when the write completes.
274 */
276 std::span<const uv::Buffer> data,
277 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
278 Send(kOpBinary, data, std::move(callback));
279 }
280
281 /**
282 * Send a text message fragment. This must be followed by one or more
283 * SendFragment() calls, where the last one has fin=True, to complete the
284 * message.
285 * @param data Data to send
286 * @param callback Callback which is invoked when the write completes.
287 */
289 std::initializer_list<uv::Buffer> data,
290 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
291 SendBinaryFragment({data.begin(), data.end()}, std::move(callback));
292 }
293
294 /**
295 * Send a continuation frame. This is used to send additional parts of a
296 * message started with SendTextFragment() or SendBinaryFragment().
297 * @param data Data to send
298 * @param fin Set to true if this is the final fragment of the message
299 * @param callback Callback which is invoked when the write completes.
300 */
302 std::span<const uv::Buffer> data, bool fin,
303 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
304 Send(kOpCont | (fin ? kFlagFin : 0), data, std::move(callback));
305 }
306
307 /**
308 * Send a continuation frame. This is used to send additional parts of a
309 * message started with SendTextFragment() or SendBinaryFragment().
310 * @param data Data to send
311 * @param fin Set to true if this is the final fragment of the message
312 * @param callback Callback which is invoked when the write completes.
313 */
315 std::initializer_list<uv::Buffer> data, bool fin,
316 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
317 SendFragment({data.begin(), data.end()}, fin, std::move(callback));
318 }
319
320 /**
321 * Send a ping frame with no data.
322 * @param callback Optional callback which is invoked when the ping frame
323 * write completes.
324 */
325 void SendPing(std::function<void(uv::Error)> callback = nullptr) {
326 SendPing({}, [f = std::move(callback)](auto bufs, uv::Error err) {
327 if (f) {
328 f(err);
329 }
330 });
331 }
332
333 /**
334 * Send a ping frame.
335 * @param data Data to send in the ping frame
336 * @param callback Callback which is invoked when the ping frame
337 * write completes.
338 */
340 std::span<const uv::Buffer> data,
341 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
342 Send(kFlagFin | kOpPing, data, std::move(callback));
343 }
344
345 /**
346 * Send a ping frame.
347 * @param data Data to send in the ping frame
348 * @param callback Callback which is invoked when the ping frame
349 * write completes.
350 */
352 std::initializer_list<uv::Buffer> data,
353 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
354 SendPing({data.begin(), data.end()}, std::move(callback));
355 }
356
357 /**
358 * Send a pong frame with no data.
359 * @param callback Optional callback which is invoked when the pong frame
360 * write completes.
361 */
362 void SendPong(std::function<void(uv::Error)> callback = nullptr) {
363 SendPong({}, [f = std::move(callback)](auto bufs, uv::Error err) {
364 if (f) {
365 f(err);
366 }
367 });
368 }
369
370 /**
371 * Send a pong frame.
372 * @param data Data to send in the pong frame
373 * @param callback Callback which is invoked when the pong frame
374 * write completes.
375 */
377 std::span<const uv::Buffer> data,
378 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
379 Send(kFlagFin | kOpPong, data, std::move(callback));
380 }
381
382 /**
383 * Send a pong frame.
384 * @param data Data to send in the pong frame
385 * @param callback Callback which is invoked when the pong frame
386 * write completes.
387 */
389 std::initializer_list<uv::Buffer> data,
390 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
391 SendPong({data.begin(), data.end()}, std::move(callback));
392 }
393
394 /**
395 * Send multiple frames.
396 *
397 * @param frames Frame type/data pairs
398 * @param callback Callback which is invoked when the write completes.
399 */
401 std::span<const Frame> frames,
402 std::function<void(std::span<uv::Buffer>, uv::Error)> callback);
403
404 /**
405 * Fail the connection.
406 */
407 void Fail(uint16_t code = 1002, std::string_view reason = "protocol error");
408
409 /**
410 * Forcibly close the connection.
411 */
412 void Terminate(uint16_t code = 1006, std::string_view reason = "terminated");
413
414 /**
415 * Gets user-defined data.
416 * @return User-defined data if any, nullptr otherwise.
417 */
418 template <typename T = void>
419 std::shared_ptr<T> GetData() const {
420 return std::static_pointer_cast<T>(m_data);
421 }
422
423 /**
424 * Sets user-defined data.
425 * @param data User-defined arbitrary data.
426 */
427 void SetData(std::shared_ptr<void> data) { m_data = std::move(data); }
428
429 /**
430 * Shuts down and closes the underlying stream.
431 */
432 void Shutdown();
433
434 /**
435 * Open event. Emitted when the connection is open and ready to communicate.
436 * The parameter is the selected subprotocol.
437 */
439
440 /**
441 * Close event. Emitted when the connection is closed. The first parameter
442 * is a numeric value indicating the status code explaining why the connection
443 * has been closed. The second parameter is a human-readable string
444 * explaining the reason why the connection has been closed.
445 */
447
448 /**
449 * Text message event. Emitted when a text message is received.
450 * The first parameter is the data, the second parameter is true if the
451 * data is the last fragment of the message.
452 */
454
455 /**
456 * Binary message event. Emitted when a binary message is received.
457 * The first parameter is the data, the second parameter is true if the
458 * data is the last fragment of the message.
459 */
461
462 /**
463 * Ping event. Emitted when a ping message is received.
464 */
466
467 /**
468 * Pong event. Emitted when a pong message is received.
469 */
471
472 private:
473 // user data
474 std::shared_ptr<void> m_data;
475
476 // constructor parameters
477 uv::Stream& m_stream;
478 bool m_server;
479
480 // subprotocol, set via constructor (server) or handshake (client)
481 std::string m_protocol;
482
483 // user-settable configuration
484 size_t m_maxMessageSize = 128 * 1024;
485 bool m_combineFragments = true;
486
487 // operating state
488 State m_state = CONNECTING;
489
490 // incoming message buffers/state
492 size_t m_headerSize = 0;
494 size_t m_frameStart = 0;
495 uint64_t m_frameSize = UINT64_MAX;
496 uint8_t m_fragmentOpcode = 0;
497
498 // temporary data used only during client handshake
499 class ClientHandshakeData;
500 std::unique_ptr<ClientHandshakeData> m_clientHandshake;
501
502 void StartClient(std::string_view uri, std::string_view host,
503 std::span<const std::string_view> protocols,
504 const ClientOptions& options);
506 std::string_view protocol);
507 void SendClose(uint16_t code, std::string_view reason);
508 void SetClosed(uint16_t code, std::string_view reason, bool failed = false);
509 void HandleIncoming(uv::Buffer& buf, size_t size);
510 void Send(uint8_t opcode, std::span<const uv::Buffer> data,
511 std::function<void(std::span<uv::Buffer>, uv::Error)> callback) {
512 SendFrames({{Frame{opcode, data}}}, std::move(callback));
513 }
514};
515
516} // namespace wpi
517
518#endif // WPINET_WEBSOCKET_H_
This file defines the SmallVector class.
and restrictions which apply to each piece of software is included later in this file and or inside of the individual applicable source files The disclaimer of warranty in the WPILib license above applies to all code in and nothing in any of the other licenses gives permission to use the names of FIRST nor the names of the WPILib contributors to endorse or promote products derived from this software The following pieces of software have additional or alternate and or Google Inc All rights reserved Redistribution and use in source and binary with or without are permitted provided that the following conditions are this list of conditions and the following disclaimer *Redistributions in binary form must reproduce the above copyright this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution *Neither the name of Google Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source code
Definition: ThirdPartyNotices.txt:110
RFC 6455 compliant WebSocket client and server implementation.
Definition: WebSocket.h:34
static std::shared_ptr< WebSocket > CreateClient(uv::Stream &stream, std::string_view uri, std::string_view host, std::initializer_list< std::string_view > protocols, const ClientOptions &options={})
Starts a client connection by performing the initial client handshake.
Definition: WebSocket.h:128
void SendFragment(std::initializer_list< uv::Buffer > data, bool fin, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a continuation frame.
Definition: WebSocket.h:314
void Shutdown()
Shuts down and closes the underlying stream.
void SendTextFragment(std::span< const uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a text message fragment.
Definition: WebSocket.h:249
void SendText(std::initializer_list< uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a text message.
Definition: WebSocket.h:214
sig::Signal< uint16_t, std::string_view > closed
Close event.
Definition: WebSocket.h:446
WebSocket & operator=(WebSocket &&)=delete
void SendFrames(std::span< const Frame > frames, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send multiple frames.
std::shared_ptr< T > GetData() const
Gets user-defined data.
Definition: WebSocket.h:419
void Fail(uint16_t code=1002, std::string_view reason="protocol error")
Fail the connection.
void SendPing(std::function< void(uv::Error)> callback=nullptr)
Send a ping frame with no data.
Definition: WebSocket.h:325
sig::Signal< std::span< const uint8_t >, bool > binary
Binary message event.
Definition: WebSocket.h:460
WebSocket & operator=(const WebSocket &)=delete
sig::Signal< std::string_view > open
Open event.
Definition: WebSocket.h:438
void SendFragment(std::span< const uv::Buffer > data, bool fin, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a continuation frame.
Definition: WebSocket.h:301
sig::Signal< std::string_view, bool > text
Text message event.
Definition: WebSocket.h:453
State GetState() const
Get connection state.
Definition: WebSocket.h:156
sig::Signal< std::span< const uint8_t > > ping
Ping event.
Definition: WebSocket.h:465
sig::Signal< std::span< const uint8_t > > pong
Pong event.
Definition: WebSocket.h:470
void SendPing(std::span< const uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a ping frame.
Definition: WebSocket.h:339
bool IsOpen() const
Return if the connection is open.
Definition: WebSocket.h:162
State
Connection states.
Definition: WebSocket.h:57
@ CLOSING
The connection is in the process of closing.
Definition: WebSocket.h:63
@ CLOSED
The connection is closed.
Definition: WebSocket.h:67
@ OPEN
The connection is open and ready to communicate.
Definition: WebSocket.h:61
@ FAILED
The connection failed.
Definition: WebSocket.h:65
@ CONNECTING
The connection is not yet open.
Definition: WebSocket.h:59
void SendPong(std::span< const uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a pong frame.
Definition: WebSocket.h:376
void SendBinaryFragment(std::span< const uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a text message fragment.
Definition: WebSocket.h:275
void Close(uint16_t code=1005, std::string_view reason={})
Initiate a closing handshake.
void SendPong(std::function< void(uv::Error)> callback=nullptr)
Send a pong frame with no data.
Definition: WebSocket.h:362
WebSocket(const WebSocket &)=delete
static std::shared_ptr< WebSocket > CreateServer(uv::Stream &stream, std::string_view key, std::string_view version, std::string_view protocol={})
Starts a server connection by performing the initial server side handshake.
void SetCombineFragments(bool combine)
Set whether or not fragmented frames should be combined.
Definition: WebSocket.h:188
void SetData(std::shared_ptr< void > data)
Sets user-defined data.
Definition: WebSocket.h:427
std::string_view GetProtocol() const
Get the selected sub-protocol.
Definition: WebSocket.h:172
WebSocket(uv::Stream &stream, bool server, const private_init &)
void SendBinary(std::initializer_list< uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a binary message.
Definition: WebSocket.h:236
static std::shared_ptr< WebSocket > CreateClient(uv::Stream &stream, std::string_view uri, std::string_view host, std::span< const std::string_view > protocols={}, const ClientOptions &options={})
Starts a client connection by performing the initial client handshake.
uv::Stream & GetStream() const
Get the underlying stream.
Definition: WebSocket.h:167
void SendBinary(std::span< const uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a binary message.
Definition: WebSocket.h:225
void SendBinaryFragment(std::initializer_list< uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a text message fragment.
Definition: WebSocket.h:288
void SetMaxMessageSize(size_t size)
Set the maximum message size.
Definition: WebSocket.h:180
void SendText(std::span< const uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a text message.
Definition: WebSocket.h:203
void SendPong(std::initializer_list< uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a pong frame.
Definition: WebSocket.h:388
void SendPing(std::initializer_list< uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a ping frame.
Definition: WebSocket.h:351
void SendTextFragment(std::initializer_list< uv::Buffer > data, std::function< void(std::span< uv::Buffer >, uv::Error)> callback)
Send a text message fragment.
Definition: WebSocket.h:262
void Terminate(uint16_t code=1006, std::string_view reason="terminated")
Forcibly close the connection.
WebSocket(WebSocket &&)=delete
SignalBase is an implementation of the observer pattern, through the use of an emitting object and sl...
Definition: Signal.h:495
Data buffer.
Definition: Buffer.h:23
Error code.
Definition: Error.h:15
Stream handle.
Definition: Stream.h:68
std::chrono::duration< uint64_t, std::milli > Time
Definition: Timer.h:31
basic_string_view< char > string_view
Definition: core.h:520
void StartServer(NT_Inst inst, std::string_view persist_filename, const char *listen_address, unsigned int port3, unsigned int port4)
Starts a server using the specified filename, listening address, and port.
constexpr common_t< T1, T2 > max(const T1 x, const T2 y) noexcept
Compile-time pairwise maximum function.
Definition: max.hpp:35
EIGEN_CONSTEXPR Index size(const T &x)
Definition: Meta.h:479
::uint64_t uint64_t
Definition: Meta.h:58
::uint16_t uint16_t
Definition: Meta.h:54
::uint8_t uint8_t
Definition: Meta.h:52
Definition: AprilTagFieldLayout.h:18
Definition: format.h:1552
Client connection options.
Definition: WebSocket.h:73
uv::Timer::Time handshakeTimeout
Timeout for the handshake request.
Definition: WebSocket.h:77
ClientOptions()
Definition: WebSocket.h:74
std::span< const std::pair< std::string_view, std::string_view > > extraHeaders
Additional headers to include in handshake.
Definition: WebSocket.h:80
Frame.
Definition: WebSocket.h:86
static constexpr uint8_t kPing
Definition: WebSocket.h:93
static constexpr uint8_t kPong
Definition: WebSocket.h:94
static constexpr uint8_t kFragment
Definition: WebSocket.h:91
static constexpr uint8_t kBinaryFragment
Definition: WebSocket.h:90
std::span< const uv::Buffer > data
Definition: WebSocket.h:100
static constexpr uint8_t kText
Definition: WebSocket.h:87
Frame(uint8_t opcode, std::span< const uv::Buffer > data)
Definition: WebSocket.h:96
static constexpr uint8_t kFinalFragment
Definition: WebSocket.h:92
uint8_t opcode
Definition: WebSocket.h:99
static constexpr uint8_t kTextFragment
Definition: WebSocket.h:89
static constexpr uint8_t kBinary
Definition: WebSocket.h:88