From 32fceac4e06f39e421d5c84a2387bc8dd5303da1 Mon Sep 17 00:00:00 2001 From: ki6080 Date: Sun, 11 Sep 2022 18:34:12 +0900 Subject: [PATCH 1/5] websocket: Reduce number of re-allocation of string parameters --- include/crow/websocket.h | 51 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/include/crow/websocket.h b/include/crow/websocket.h index f961055a4..f8534a53e 100644 --- a/include/crow/websocket.h +++ b/include/crow/websocket.h @@ -22,13 +22,13 @@ namespace crow /// A base class for websocket connection. struct connection { - virtual void send_binary(const std::string& msg) = 0; - virtual void send_text(const std::string& msg) = 0; - virtual void send_ping(const std::string& msg) = 0; - virtual void send_pong(const std::string& msg) = 0; - virtual void close(const std::string& msg = "quit") = 0; + virtual void send_binary(std::string msg) = 0; + virtual void send_text(std::string msg) = 0; + virtual void send_ping(std::string msg) = 0; + virtual void send_pong(std::string msg) = 0; + virtual void close(std::string msg = "quit") = 0; virtual std::string get_remote_ip() = 0; - virtual ~connection() {} + virtual ~connection() = default; void userdata(void* u) { userdata_ = u; } void* userdata() { return userdata_; } @@ -136,12 +136,12 @@ namespace crow /// /// Usually invoked to check if the other point is still online. - void send_ping(const std::string& msg) override + void send_ping(std::string msg) override { - dispatch([this, msg] { + dispatch([this, msg = std::move(msg)]() mutable { auto header = build_header(0x9, msg.size()); write_buffers_.emplace_back(std::move(header)); - write_buffers_.emplace_back(msg); + write_buffers_.emplace_back(std::move(msg)); do_write(); }); } @@ -150,34 +150,34 @@ namespace crow /// /// Usually automatically invoked as a response to a "Ping" message. - void send_pong(const std::string& msg) override + void send_pong(std::string msg) override { - dispatch([this, msg] { + dispatch([this, msg = std::move(msg)]() mutable { auto header = build_header(0xA, msg.size()); write_buffers_.emplace_back(std::move(header)); - write_buffers_.emplace_back(msg); + write_buffers_.emplace_back(std::move(msg)); do_write(); }); } /// Send a binary encoded message. - void send_binary(const std::string& msg) override + void send_binary(std::string msg) override { - dispatch([this, msg] { + dispatch([this, msg = std::move(msg)]() mutable { auto header = build_header(2, msg.size()); write_buffers_.emplace_back(std::move(header)); - write_buffers_.emplace_back(msg); + write_buffers_.emplace_back(std::move(msg)); do_write(); }); } /// Send a plaintext message. - void send_text(const std::string& msg) override + void send_text(std::string msg) override { - dispatch([this, msg] { + dispatch([this, msg = std::move(msg)]() mutable { auto header = build_header(1, msg.size()); write_buffers_.emplace_back(std::move(header)); - write_buffers_.emplace_back(msg); + write_buffers_.emplace_back(std::move(msg)); do_write(); }); } @@ -186,9 +186,9 @@ namespace crow /// /// Sets a flag to destroy the object once the message is sent. - void close(const std::string& msg) override + void close(std::string msg) override { - dispatch([this, msg] { + dispatch([this, msg = std::move(msg)]() mutable { has_sent_close_ = true; if (has_recv_close_ && !is_close_handler_called_) { @@ -198,7 +198,7 @@ namespace crow } auto header = build_header(0x8, msg.size()); write_buffers_.emplace_back(std::move(header)); - write_buffers_.emplace_back(msg); + write_buffers_.emplace_back(std::move(msg)); do_write(); }); } @@ -244,10 +244,11 @@ namespace crow /// Finishes the handshake process, then starts reading messages from the socket. void start(std::string&& hello) { - static std::string header = "HTTP/1.1 101 Switching Protocols\r\n" - "Upgrade: websocket\r\n" - "Connection: Upgrade\r\n" - "Sec-WebSocket-Accept: "; + static const std::string header = + "HTTP/1.1 101 Switching Protocols\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Accept: "; write_buffers_.emplace_back(header); write_buffers_.emplace_back(std::move(hello)); write_buffers_.emplace_back(crlf); From 202be36eab291f879336e451a9e14235a3d5b12e Mon Sep 17 00:00:00 2001 From: ki6080 Date: Sun, 11 Sep 2022 19:02:39 +0900 Subject: [PATCH 2/5] websocket: Remove copying completion token on dispatch/post --- include/crow/websocket.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/crow/websocket.h b/include/crow/websocket.h index f8534a53e..148ea68a1 100644 --- a/include/crow/websocket.h +++ b/include/crow/websocket.h @@ -120,16 +120,16 @@ namespace crow /// Send data through the socket. template - void dispatch(CompletionHandler handler) + void dispatch(CompletionHandler&& handler) { - adaptor_.get_io_service().dispatch(handler); + adaptor_.get_io_service().dispatch(std::forward(handler)); } /// Send data through the socket and return immediately. template - void post(CompletionHandler handler) + void post(CompletionHandler&& handler) { - adaptor_.get_io_service().post(handler); + adaptor_.get_io_service().post(std::forward(handler)); } /// Send a "Ping" message. From 99217d8b4076bf9d67de14c3861d29c259887d0d Mon Sep 17 00:00:00 2001 From: ki6080 Date: Mon, 12 Sep 2022 12:55:21 +0900 Subject: [PATCH 3/5] websocket: Remove generalized-lambda-capture to make c++11 compatible --- include/crow/websocket.h | 64 +++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/include/crow/websocket.h b/include/crow/websocket.h index 148ea68a1..6a86ac5fd 100644 --- a/include/crow/websocket.h +++ b/include/crow/websocket.h @@ -138,12 +138,7 @@ namespace crow /// Usually invoked to check if the other point is still online. void send_ping(std::string msg) override { - dispatch([this, msg = std::move(msg)]() mutable { - auto header = build_header(0x9, msg.size()); - write_buffers_.emplace_back(std::move(header)); - write_buffers_.emplace_back(std::move(msg)); - do_write(); - }); + send_data(0x9, std::move(msg)); } /// Send a "Pong" message. @@ -152,34 +147,19 @@ namespace crow /// Usually automatically invoked as a response to a "Ping" message. void send_pong(std::string msg) override { - dispatch([this, msg = std::move(msg)]() mutable { - auto header = build_header(0xA, msg.size()); - write_buffers_.emplace_back(std::move(header)); - write_buffers_.emplace_back(std::move(msg)); - do_write(); - }); + send_data(0xA, std::move(msg)); } /// Send a binary encoded message. void send_binary(std::string msg) override { - dispatch([this, msg = std::move(msg)]() mutable { - auto header = build_header(2, msg.size()); - write_buffers_.emplace_back(std::move(header)); - write_buffers_.emplace_back(std::move(msg)); - do_write(); - }); + send_data(0x2, std::move(msg)); } /// Send a plaintext message. void send_text(std::string msg) override { - dispatch([this, msg = std::move(msg)]() mutable { - auto header = build_header(1, msg.size()); - write_buffers_.emplace_back(std::move(header)); - write_buffers_.emplace_back(std::move(msg)); - do_write(); - }); + send_data(0x1, std::move(msg)); } /// Send a close signal. @@ -657,6 +637,42 @@ namespace crow delete this; } + + struct SendMessageType + { + std::string payload; + Connection* self; + int opcode; + + void operator()() + { + self->send_data_impl(this); + } + }; + + static_assert( + std::is_nothrow_move_assignable::value && + std::is_nothrow_move_constructible::value, + "SendMessageType must be nothrow movable!"); + + void send_data_impl(SendMessageType* s) + { + auto header = build_header(s->opcode, s->payload.size()); + write_buffers_.emplace_back(std::move(header)); + write_buffers_.emplace_back(std::move(s->payload)); + do_write(); + } + + void send_data(int opcode, std::string&& msg) + { + SendMessageType event_arg{ + std::move(msg), + this, + opcode}; + + post(std::move(event_arg)); + } + private: Adaptor adaptor_; Handler* handler_; From b6ec1bc540c643fa7ff6bf71f017d2a08854d0e6 Mon Sep 17 00:00:00 2001 From: ki6080 Date: Mon, 12 Sep 2022 13:00:27 +0900 Subject: [PATCH 4/5] websocket: Change completion token not to be copied --- include/crow/websocket.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/crow/websocket.h b/include/crow/websocket.h index 6a86ac5fd..feff1922d 100644 --- a/include/crow/websocket.h +++ b/include/crow/websocket.h @@ -122,14 +122,14 @@ namespace crow template void dispatch(CompletionHandler&& handler) { - adaptor_.get_io_service().dispatch(std::forward(handler)); + asio::dispatch(adaptor_.get_io_service(), std::forward(handler)); } /// Send data through the socket and return immediately. template void post(CompletionHandler&& handler) { - adaptor_.get_io_service().post(std::forward(handler)); + asio::post(adaptor_.get_io_service(), std::forward(handler)); } /// Send a "Ping" message. @@ -648,6 +648,14 @@ namespace crow { self->send_data_impl(this); } + + SendMessageType() noexcept = default; + + SendMessageType(SendMessageType const&) = delete; + SendMessageType& operator=(SendMessageType const&) = delete; + + SendMessageType(SendMessageType&&) noexcept = default; + SendMessageType& operator=(SendMessageType&&) noexcept = default; }; static_assert( From 02c0f8db129f0042da3de4ded3e8b3b6f15927c3 Mon Sep 17 00:00:00 2001 From: ki6080 Date: Sat, 17 Sep 2022 13:50:23 +0900 Subject: [PATCH 5/5] websocket: Fix c++14 feature warning --- include/crow/websocket.h | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/include/crow/websocket.h b/include/crow/websocket.h index feff1922d..6d4bf22a7 100644 --- a/include/crow/websocket.h +++ b/include/crow/websocket.h @@ -26,7 +26,7 @@ namespace crow virtual void send_text(std::string msg) = 0; virtual void send_ping(std::string msg) = 0; virtual void send_pong(std::string msg) = 0; - virtual void close(std::string msg = "quit") = 0; + virtual void close(std::string const& msg = "quit") = 0; virtual std::string get_remote_ip() = 0; virtual ~connection() = default; @@ -166,9 +166,9 @@ namespace crow /// /// Sets a flag to destroy the object once the message is sent. - void close(std::string msg) override + void close(std::string const& msg) override { - dispatch([this, msg = std::move(msg)]() mutable { + dispatch([this, msg]() mutable { has_sent_close_ = true; if (has_recv_close_ && !is_close_handler_called_) { @@ -178,7 +178,7 @@ namespace crow } auto header = build_header(0x8, msg.size()); write_buffers_.emplace_back(std::move(header)); - write_buffers_.emplace_back(std::move(msg)); + write_buffers_.emplace_back(msg); do_write(); }); } @@ -648,21 +648,8 @@ namespace crow { self->send_data_impl(this); } - - SendMessageType() noexcept = default; - - SendMessageType(SendMessageType const&) = delete; - SendMessageType& operator=(SendMessageType const&) = delete; - - SendMessageType(SendMessageType&&) noexcept = default; - SendMessageType& operator=(SendMessageType&&) noexcept = default; }; - static_assert( - std::is_nothrow_move_assignable::value && - std::is_nothrow_move_constructible::value, - "SendMessageType must be nothrow movable!"); - void send_data_impl(SendMessageType* s) { auto header = build_header(s->opcode, s->payload.size());