CppServer  1.0.4.0
C++ Server Library
ws_client.h
Go to the documentation of this file.
1 
9 #ifndef CPPSERVER_HTTP_WS_CLIENT_H
10 #define CPPSERVER_HTTP_WS_CLIENT_H
11 
13 #include "server/ws/ws.h"
14 
15 namespace CppServer {
16 namespace WS {
17 
19 
26 class WSClient : public HTTP::HTTPClient, protected WebSocket
27 {
28 public:
29  using HTTPClient::HTTPClient;
30 
31  WSClient(const WSClient&) = delete;
32  WSClient(WSClient&&) = delete;
33  virtual ~WSClient() = default;
34 
35  WSClient& operator=(const WSClient&) = delete;
36  WSClient& operator=(WSClient&&) = delete;
37 
38  // WebSocket connection methods
39  bool Connect() override;
40  bool Connect(const std::shared_ptr<Asio::TCPResolver>& resolver) override;
41  bool ConnectAsync() override;
42  bool ConnectAsync(const std::shared_ptr<Asio::TCPResolver>& resolver) override;
43  virtual bool Close() { return Close(0, nullptr, 0); }
44  virtual bool Close(int status) { return Close(status, nullptr, 0); }
45  virtual bool Close(int status, const void* buffer, size_t size) { SendClose(status, buffer, size); HTTPClient::Disconnect(); return true; }
46  virtual bool Close(int status, std::string_view text) { SendClose(status, text); HTTPClient::Disconnect(); return true; }
47  virtual bool CloseAsync() { return CloseAsync(0, nullptr, 0); }
48  virtual bool CloseAsync(int status) { return CloseAsync(status, nullptr, 0); }
49  virtual bool CloseAsync(int status, const void* buffer, size_t size) { SendCloseAsync(status, buffer, size); HTTPClient::DisconnectAsync(); return true; }
50  virtual bool CloseAsync(int status, std::string_view text) { SendCloseAsync(status, text); HTTPClient::DisconnectAsync(); return true; }
51 
52  // WebSocket send text methods
53  size_t SendText(const void* buffer, size_t size) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_TEXT, true, buffer, size); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size()); }
54  size_t SendText(std::string_view text) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_TEXT, true, text.data(), text.size()); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size()); }
55  size_t SendText(const void* buffer, size_t size, const CppCommon::Timespan& timeout) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_TEXT, true, buffer, size); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size(), timeout); }
56  size_t SendText(std::string_view text, const CppCommon::Timespan& timeout) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_TEXT, true, text.data(), text.size()); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size(), timeout); }
57  bool SendTextAsync(const void* buffer, size_t size) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_TEXT, true, buffer, size); return HTTPClient::SendAsync(_ws_send_buffer.data(), _ws_send_buffer.size()); }
58  bool SendTextAsync(std::string_view text) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_TEXT, true, text.data(), text.size()); return HTTPClient::SendAsync(_ws_send_buffer.data(), _ws_send_buffer.size()); }
59 
60  // WebSocket send binary methods
61  size_t SendBinary(const void* buffer, size_t size) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_BINARY, true, buffer, size); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size()); }
62  size_t SendBinary(std::string_view text) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_BINARY, true, text.data(), text.size()); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size()); }
63  size_t SendBinary(const void* buffer, size_t size, const CppCommon::Timespan& timeout) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_BINARY, true, buffer, size); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size(), timeout); }
64  size_t SendBinary(std::string_view text, const CppCommon::Timespan& timeout) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_BINARY, true, text.data(), text.size()); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size(), timeout); }
65  bool SendBinaryAsync(const void* buffer, size_t size) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_BINARY, true, buffer, size); return HTTPClient::SendAsync(_ws_send_buffer.data(), _ws_send_buffer.size()); }
66  bool SendBinaryAsync(std::string_view text) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_BINARY, true, text.data(), text.size()); return HTTPClient::SendAsync(_ws_send_buffer.data(), _ws_send_buffer.size()); }
67 
68  // WebSocket close methods
69  size_t SendClose(int status, const void* buffer, size_t size) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_CLOSE, true, buffer, size, status); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size()); }
70  size_t SendClose(int status, std::string_view text) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_CLOSE, true, text.data(), text.size(), status); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size()); }
71  size_t SendClose(int status, const void* buffer, size_t size, const CppCommon::Timespan& timeout) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_CLOSE, true, buffer, size, status); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size(), timeout); }
72  size_t SendClose(int status, std::string_view text, const CppCommon::Timespan& timeout) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_CLOSE, true, text.data(), text.size(), status); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size(), timeout); }
73  bool SendCloseAsync(int status, const void* buffer, size_t size) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_CLOSE, true, buffer, size, status); return HTTPClient::SendAsync(_ws_send_buffer.data(), _ws_send_buffer.size()); }
74  bool SendCloseAsync(int status, std::string_view text) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_CLOSE, true, text.data(), text.size(), status); return HTTPClient::SendAsync(_ws_send_buffer.data(), _ws_send_buffer.size()); }
75 
76  // WebSocket ping methods
77  size_t SendPing(const void* buffer, size_t size) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PING, true, buffer, size); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size()); }
78  size_t SendPing(std::string_view text) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PING, true, text.data(), text.size()); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size()); }
79  size_t SendPing(const void* buffer, size_t size, const CppCommon::Timespan& timeout) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PING, true, buffer, size); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size(), timeout); }
80  size_t SendPing(std::string_view text, const CppCommon::Timespan& timeout) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PING, true, text.data(), text.size()); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size(), timeout); }
81  bool SendPingAsync(const void* buffer, size_t size) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PING, true, buffer, size); return HTTPClient::SendAsync(_ws_send_buffer.data(), _ws_send_buffer.size()); }
82  bool SendPingAsync(std::string_view text) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PING, true, text.data(), text.size()); return HTTPClient::SendAsync(_ws_send_buffer.data(), _ws_send_buffer.size()); }
83 
84  // WebSocket pong methods
85  size_t SendPong(const void* buffer, size_t size) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PONG, true, buffer, size); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size()); }
86  size_t SendPong(std::string_view text) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PONG, true, text.data(), text.size()); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size()); }
87  size_t SendPong(const void* buffer, size_t size, const CppCommon::Timespan& timeout) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PONG, true, buffer, size); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size(), timeout); }
88  size_t SendPong(std::string_view text, const CppCommon::Timespan& timeout) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PONG, true, text.data(), text.size()); return HTTPClient::Send(_ws_send_buffer.data(), _ws_send_buffer.size(), timeout); }
89  bool SendPongAsync(const void* buffer, size_t size) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PONG, true, buffer, size); return HTTPClient::SendAsync(_ws_send_buffer.data(), _ws_send_buffer.size()); }
90  bool SendPongAsync(std::string_view text) { std::scoped_lock locker(_ws_send_lock); PrepareSendFrame(WS_FIN | WS_PONG, true, text.data(), text.size()); return HTTPClient::SendAsync(_ws_send_buffer.data(), _ws_send_buffer.size()); }
91 
92  // WebSocket receive methods
93  std::string ReceiveText();
94  std::string ReceiveText(const CppCommon::Timespan& timeout);
95  std::vector<uint8_t> ReceiveBinary();
96  std::vector<uint8_t> ReceiveBinary(const CppCommon::Timespan& timeout);
97 
98 protected:
99  void onConnected() override;
100  void onDisconnected() override;
101  void onReceived(const void* buffer, size_t size) override;
102  void onReceivedResponseHeader(const HTTP::HTTPResponse& response) override;
103  void onReceivedResponse(const HTTP::HTTPResponse& response) override;
104  void onReceivedResponseError(const HTTP::HTTPResponse& response, const std::string& error) override;
105 
107  void onWSClose(const void* buffer, size_t size, int status = 1000) override { CloseAsync(); }
109  void onWSPing(const void* buffer, size_t size) override { SendPongAsync(buffer, size); }
111  void onWSError(const std::string& message) override { onError(asio::error::fault, "WebSocket error", message); }
112 
113 private:
114  // Sync connect flag
115  bool _sync_connect;
116 
117  // WebSocket clients cannot send response
118  void SendResponse(const HTTP::HTTPResponse& response) override {}
119 };
120 
123 } // namespace WS
124 } // namespace CppServer
125 
126 #endif // CPPSERVER_HTTP_WS_CLIENT_H
virtual void onError(int error, const std::string &category, const std::string &message)
Handle error notification.
Definition: tcp_client.h:320
WebSocket client.
Definition: ws_client.h:27
virtual bool Close(int status, const void *buffer, size_t size)
Definition: ws_client.h:45
bool SendCloseAsync(int status, std::string_view text)
Definition: ws_client.h:74
virtual bool CloseAsync(int status, const void *buffer, size_t size)
Definition: ws_client.h:49
virtual bool CloseAsync()
Definition: ws_client.h:47
virtual bool Close(int status, std::string_view text)
Definition: ws_client.h:46
bool SendPingAsync(std::string_view text)
Definition: ws_client.h:82
WSClient & operator=(const WSClient &)=delete
virtual ~WSClient()=default
size_t SendClose(int status, const void *buffer, size_t size)
Definition: ws_client.h:69
bool SendBinaryAsync(std::string_view text)
Definition: ws_client.h:66
bool ConnectAsync() override
Connect the client (asynchronous)
Definition: ws_client.cpp:26
bool SendTextAsync(const void *buffer, size_t size)
Definition: ws_client.h:57
size_t SendText(std::string_view text, const CppCommon::Timespan &timeout)
Definition: ws_client.h:56
void onWSPing(const void *buffer, size_t size) override
Handle WebSocket ping notification.
Definition: ws_client.h:109
size_t SendPong(const void *buffer, size_t size, const CppCommon::Timespan &timeout)
Definition: ws_client.h:87
size_t SendPong(const void *buffer, size_t size)
Definition: ws_client.h:85
std::string ReceiveText()
Definition: ws_client.cpp:129
WSClient(const WSClient &)=delete
void onReceivedResponse(const HTTP::HTTPResponse &response) override
Handle HTTP response received notification.
Definition: ws_client.cpp:103
size_t SendPing(const void *buffer, size_t size)
Definition: ws_client.h:77
virtual bool CloseAsync(int status, std::string_view text)
Definition: ws_client.h:50
void onReceivedResponseHeader(const HTTP::HTTPResponse &response) override
Handle HTTP response header received notification.
Definition: ws_client.cpp:89
size_t SendClose(int status, std::string_view text)
Definition: ws_client.h:70
size_t SendPing(std::string_view text)
Definition: ws_client.h:78
void onDisconnected() override
Handle client disconnected notification.
Definition: ws_client.cpp:56
bool Connect() override
Connect the client (synchronous)
Definition: ws_client.cpp:14
size_t SendBinary(std::string_view text, const CppCommon::Timespan &timeout)
Definition: ws_client.h:64
void onReceivedResponseError(const HTTP::HTTPResponse &response, const std::string &error) override
Handle HTTP response error notification.
Definition: ws_client.cpp:117
size_t SendPong(std::string_view text, const CppCommon::Timespan &timeout)
Definition: ws_client.h:88
bool SendCloseAsync(int status, const void *buffer, size_t size)
Definition: ws_client.h:73
std::vector< uint8_t > ReceiveBinary()
Definition: ws_client.cpp:191
void onConnected() override
Handle client connected notification.
Definition: ws_client.cpp:38
size_t SendText(const void *buffer, size_t size)
Definition: ws_client.h:53
virtual bool Close(int status)
Definition: ws_client.h:44
virtual bool CloseAsync(int status)
Definition: ws_client.h:48
bool SendPingAsync(const void *buffer, size_t size)
Definition: ws_client.h:81
virtual bool Close()
Definition: ws_client.h:43
size_t SendClose(int status, std::string_view text, const CppCommon::Timespan &timeout)
Definition: ws_client.h:72
void onWSError(const std::string &message) override
Handle WebSocket error notification.
Definition: ws_client.h:111
bool SendBinaryAsync(const void *buffer, size_t size)
Definition: ws_client.h:65
WSClient(WSClient &&)=delete
size_t SendPong(std::string_view text)
Definition: ws_client.h:86
size_t SendClose(int status, const void *buffer, size_t size, const CppCommon::Timespan &timeout)
Definition: ws_client.h:71
size_t SendPing(const void *buffer, size_t size, const CppCommon::Timespan &timeout)
Definition: ws_client.h:79
size_t SendBinary(std::string_view text)
Definition: ws_client.h:62
size_t SendText(const void *buffer, size_t size, const CppCommon::Timespan &timeout)
Definition: ws_client.h:55
bool SendPongAsync(std::string_view text)
Definition: ws_client.h:90
size_t SendBinary(const void *buffer, size_t size, const CppCommon::Timespan &timeout)
Definition: ws_client.h:63
size_t SendBinary(const void *buffer, size_t size)
Definition: ws_client.h:61
size_t SendText(std::string_view text)
Definition: ws_client.h:54
bool SendPongAsync(const void *buffer, size_t size)
Definition: ws_client.h:89
bool SendTextAsync(std::string_view text)
Definition: ws_client.h:58
void onReceived(const void *buffer, size_t size) override
Handle buffer received notification.
Definition: ws_client.cpp:76
void onWSClose(const void *buffer, size_t size, int status=1000) override
Handle WebSocket close notification.
Definition: ws_client.h:107
size_t SendPing(std::string_view text, const CppCommon::Timespan &timeout)
Definition: ws_client.h:80
WSClient & operator=(WSClient &&)=delete
WebSocket utility class.
Definition: ws.h:30
static const uint8_t WS_CLOSE
Close frame.
Definition: ws.h:39
void PrepareSendFrame(uint8_t opcode, bool mask, const void *buffer, size_t size, int status=0)
Prepare WebSocket send frame.
Definition: ws.cpp:212
static const uint8_t WS_TEXT
Text frame.
Definition: ws.h:35
static const uint8_t WS_BINARY
Binary frame.
Definition: ws.h:37
static const uint8_t WS_PING
Ping frame.
Definition: ws.h:41
static const uint8_t WS_FIN
Final frame.
Definition: ws.h:33
std::mutex _ws_send_lock
Send buffer lock.
Definition: ws.h:189
static const uint8_t WS_PONG
Pong frame.
Definition: ws.h:43
std::vector< uint8_t > _ws_send_buffer
Send buffer.
Definition: ws.h:191
HTTP client definition.
C++ Server project definitions.
Definition: asio.h:56
WebSocket C++ Library definition.