9WebsocketsClient::WebsocketsClient() : WebsocketsClient(std::make_shared<websockets::network::TcpClient>()) {
14WebsocketsClient::WebsocketsClient(std::shared_ptr<network::TcpClient> client)
15 : _client(client), _endpoint(client), _connectionOpen(client->available()),
16 _messagesCallback([](WebsocketsClient &, WebsocketsMessage) {}),
17 _eventsCallback([](WebsocketsClient &, WebsocketsEvent, std::string) {}), _sendMode(SendMode_Normal) {
22WebsocketsClient::WebsocketsClient(
const WebsocketsClient &other)
23 : _client(other._client), _endpoint(other._endpoint), _connectionOpen(other._client->available()),
24 _messagesCallback(other._messagesCallback), _eventsCallback(other._eventsCallback),
25 _sendMode(other._sendMode) {
28 const_cast<WebsocketsClient &
>(other)._client =
nullptr;
29 const_cast<WebsocketsClient &
>(other)._connectionOpen =
false;
33WebsocketsClient::WebsocketsClient(
const WebsocketsClient &&other)
34 : _client(other._client), _endpoint(other._endpoint), _connectionOpen(other._client->available()),
35 _messagesCallback(other._messagesCallback), _eventsCallback(other._eventsCallback),
36 _sendMode(other._sendMode) {
39 const_cast<WebsocketsClient &
>(other)._client =
nullptr;
40 const_cast<WebsocketsClient &
>(other)._connectionOpen =
false;
44WebsocketsClient &WebsocketsClient::operator=(
const WebsocketsClient &other) {
46 _endpoint = other._endpoint;
49 this->_client = other._client;
50 this->_messagesCallback = other._messagesCallback;
51 this->_eventsCallback = other._eventsCallback;
52 this->_connectionOpen = other._connectionOpen;
53 this->_sendMode = other._sendMode;
56 const_cast<WebsocketsClient &
>(other)._client =
nullptr;
57 const_cast<WebsocketsClient &
>(other)._connectionOpen =
false;
62WebsocketsClient &WebsocketsClient::operator=(
const WebsocketsClient &&other) {
64 _endpoint = other._endpoint;
67 this->_client = other._client;
68 this->_messagesCallback = other._messagesCallback;
69 this->_eventsCallback = other._eventsCallback;
70 this->_connectionOpen = other._connectionOpen;
71 this->_sendMode = other._sendMode;
74 const_cast<WebsocketsClient &
>(other)._client =
nullptr;
75 const_cast<WebsocketsClient &
>(other)._connectionOpen =
false;
80bool isWhitespace(
char ch) {
return ch ==
' ' || ch ==
'\t' || ch ==
'\r' || ch ==
'\n'; }
84 if (lhs.size() != rhs.size())
87 for (
size_t i = 0; i < lhs.size(); i++) {
88 char leftLowerCaseChar = lhs[i] >=
'A' && lhs[i] <=
'Z' ? lhs[i] -
'A' +
'a' : lhs[i];
89 char righerLowerCaseChar = rhs[i] >=
'A' && rhs[i] <=
'Z' ? rhs[i] -
'A' +
'a' : rhs[i];
90 if (leftLowerCaseChar != righerLowerCaseChar)
99 if (str.size() < prefix.size())
101 for (
size_t i = 0; i < prefix.size(); i++) {
102 if (str[i] != prefix[i])
110void WebsocketsClient::addHeader(
const std::string key,
const std::string value) {
111 _customHeaders.push_back({internals::fromInterfaceString(key), internals::fromInterfaceString(value)});
115void WebsocketsClient::onMessage(MessageCallback callback) { this->_messagesCallback = callback; }
118void WebsocketsClient::onMessage(PartialMessageCallback callback) {
119 this->_messagesCallback = [callback](WebsocketsClient &, WebsocketsMessage
msg) { callback(
msg); };
123void WebsocketsClient::onEvent(EventCallback callback) { this->_eventsCallback = callback; }
126void WebsocketsClient::onEvent(PartialEventCallback callback) {
127 this->_eventsCallback = [callback](WebsocketsClient &, WebsocketsEvent event, std::string data) {
128 callback(event, data);
133bool WebsocketsClient::poll() {
134 bool messageReceived =
false;
135 while (available() && _endpoint.poll()) {
136 auto msg = _endpoint.recv();
140 messageReceived =
true;
142 if (
msg.isBinary() ||
msg.isText()) {
143 this->_messagesCallback(*
this, std::move(
msg));
144 }
else if (
msg.isContinuation()) {
146 this->_messagesCallback(*
this, std::move(
msg));
147 }
else if (
msg.isPing()) {
148 _handlePing(std::move(
msg));
149 }
else if (
msg.isPong()) {
150 _handlePong(std::move(
msg));
151 }
else if (
msg.isClose()) {
152 this->_connectionOpen =
false;
153 _handleClose(std::move(
msg));
157 return messageReceived;
160WebsocketsMessage WebsocketsClient::readBlocking() {
161 while (available()) {
162#ifdef PLATFORM_DOES_NOT_SUPPORT_BLOCKING_READ
163 while (available() && _endpoint.poll() ==
false)
166 auto msg = _endpoint.recv();
173bool WebsocketsClient::send(
const std::string &data) {
174 auto str = internals::fromInterfaceString(data);
175 return this->send(str.c_str(), str.size());
178bool WebsocketsClient::send(
const std::string &&data) {
179 auto str = internals::fromInterfaceString(data);
180 return this->send(str.c_str(), str.size());
183bool WebsocketsClient::send(
const char *data) {
return this->send(data, strlen(data)); }
186bool WebsocketsClient::send(
const char *data,
const size_t len) {
189 if (this->_sendMode == SendMode_Normal) {
191 return _endpoint.send(data, len, internals::ContentType::Text,
true);
194 else if (this->_sendMode == SendMode_Streaming) {
196 return _endpoint.send(data, len, internals::ContentType::Continuation,
false);
202bool WebsocketsClient::sendBinary(std::string data) {
203 auto str = internals::fromInterfaceString(data);
204 return this->sendBinary(str.c_str(), str.size());
208bool WebsocketsClient::sendBinary(
const char *data,
const size_t len) {
211 if (this->_sendMode == SendMode_Normal) {
213 return _endpoint.send(data, len, internals::ContentType::Binary,
true);
216 else if (this->_sendMode == SendMode_Streaming) {
218 return _endpoint.send(data, len, internals::ContentType::Continuation,
false);
224bool WebsocketsClient::stream(
const std::string data) {
225 if (available() && this->_sendMode == SendMode_Normal) {
226 this->_sendMode = SendMode_Streaming;
227 return _endpoint.send(internals::fromInterfaceString(data), internals::ContentType::Text,
false);
232bool WebsocketsClient::streamBinary(
const std::string data) {
233 if (available() && this->_sendMode == SendMode_Normal) {
234 this->_sendMode = SendMode_Streaming;
235 return _endpoint.send(internals::fromInterfaceString(data), internals::ContentType::Binary,
false);
240bool WebsocketsClient::end(
const std::string data) {
241 if (available() && this->_sendMode == SendMode_Streaming) {
242 this->_sendMode = SendMode_Normal;
243 return _endpoint.send(internals::fromInterfaceString(data), internals::ContentType::Continuation,
true);
248void WebsocketsClient::setFragmentsPolicy(
const FragmentsPolicy newPolicy) {
249 _endpoint.setFragmentsPolicy(newPolicy);
253bool WebsocketsClient::available(
const bool activeTest) {
258 bool updatedConnectionOpen = this->_connectionOpen && this->_client && this->_client->available();
260 if (updatedConnectionOpen != this->_connectionOpen) {
261 _endpoint.close(CloseReason_AbnormalClosure);
262 this->_eventsCallback(*
this, WebsocketsEvent::ConnectionClosed,
"");
265 this->_connectionOpen = updatedConnectionOpen;
266 return this->_connectionOpen;
269bool WebsocketsClient::ping(
const std::string data) {
271 return _endpoint.ping(internals::fromInterfaceString(data));
276bool WebsocketsClient::pong(
const std::string data) {
278 return _endpoint.pong(internals::fromInterfaceString(data));
283void WebsocketsClient::close(
const CloseReason reason) {
285 this->_connectionOpen =
false;
286 _endpoint.close(reason);
291CloseReason WebsocketsClient::getCloseReason()
const {
return _endpoint.getCloseReason(); }
293void WebsocketsClient::_handlePing(
const WebsocketsMessage message) {
294 this->_eventsCallback(*
this, WebsocketsEvent::GotPing, message.data());
297void WebsocketsClient::_handlePong(
const WebsocketsMessage message) {
298 this->_eventsCallback(*
this, WebsocketsEvent::GotPong, message.data());
301void WebsocketsClient::_handleClose(
const WebsocketsMessage message) {
302 this->_eventsCallback(*
this, WebsocketsEvent::ConnectionClosed, message.data());
305WebsocketsClient::~WebsocketsClient() {
307 this->close(CloseReason_GoingAway);