From a48d0b5eefb1d830e0dbb41fcc0a903501178296 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Tue, 28 Jan 2020 14:06:28 +0100 Subject: [PATCH] Disable Nagle's algorithm for WebSocket TCP. This should greatly decrease latency for the most common use cases. A new function WebSocketPeer::set_no_delay will allow to configure it if so desired. --- modules/websocket/doc_classes/WebSocketPeer.xml | 10 ++++++++++ modules/websocket/emws_peer.cpp | 5 +++++ modules/websocket/emws_peer.h | 1 + modules/websocket/websocket_peer.cpp | 1 + modules/websocket/websocket_peer.h | 1 + modules/websocket/wsl_client.cpp | 1 + modules/websocket/wsl_peer.cpp | 6 ++++++ modules/websocket/wsl_peer.h | 1 + modules/websocket/wsl_server.cpp | 1 + 9 files changed, 27 insertions(+) diff --git a/modules/websocket/doc_classes/WebSocketPeer.xml b/modules/websocket/doc_classes/WebSocketPeer.xml index d084e1c6e65..6293b35fbf3 100644 --- a/modules/websocket/doc_classes/WebSocketPeer.xml +++ b/modules/websocket/doc_classes/WebSocketPeer.xml @@ -53,6 +53,16 @@ Returns [code]true[/code] if this peer is currently connected. + + + + + + + Disable Nagle's algorithm on the underling TCP socket (default). See [method StreamPeerTCP.set_no_delay] for more information. + [b]Note:[/b] Not available in the HTML5 export. + + diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index d07360c5255..effed8e4d9f 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -139,6 +139,11 @@ uint16_t EMWSPeer::get_connected_port() const { ERR_FAIL_V_MSG(0, "Not supported in HTML5 export."); }; +void EMWSPeer::set_no_delay(bool p_enabled) { + + ERR_FAIL_MSG("'set_no_delay' is not supported in HTML5 export."); +} + EMWSPeer::EMWSPeer() { peer_sock = -1; write_mode = WRITE_MODE_BINARY; diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h index 9fe7fb8edc3..43b42f9be65 100644 --- a/modules/websocket/emws_peer.h +++ b/modules/websocket/emws_peer.h @@ -68,6 +68,7 @@ public: virtual WriteMode get_write_mode() const; virtual void set_write_mode(WriteMode p_mode); virtual bool was_string_packet() const; + virtual void set_no_delay(bool p_enabled); EMWSPeer(); ~EMWSPeer(); diff --git a/modules/websocket/websocket_peer.cpp b/modules/websocket/websocket_peer.cpp index 474b11f0121..30a59723304 100644 --- a/modules/websocket/websocket_peer.cpp +++ b/modules/websocket/websocket_peer.cpp @@ -46,6 +46,7 @@ void WebSocketPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("close", "code", "reason"), &WebSocketPeer::close, DEFVAL(1000), DEFVAL("")); ClassDB::bind_method(D_METHOD("get_connected_host"), &WebSocketPeer::get_connected_host); ClassDB::bind_method(D_METHOD("get_connected_port"), &WebSocketPeer::get_connected_port); + ClassDB::bind_method(D_METHOD("set_no_delay", "enabled"), &WebSocketPeer::set_no_delay); BIND_ENUM_CONSTANT(WRITE_MODE_TEXT); BIND_ENUM_CONSTANT(WRITE_MODE_BINARY); diff --git a/modules/websocket/websocket_peer.h b/modules/websocket/websocket_peer.h index c4e1984aa06..d4173600ec8 100644 --- a/modules/websocket/websocket_peer.h +++ b/modules/websocket/websocket_peer.h @@ -64,6 +64,7 @@ public: virtual IP_Address get_connected_host() const = 0; virtual uint16_t get_connected_port() const = 0; virtual bool was_string_packet() const = 0; + virtual void set_no_delay(bool p_enabled) = 0; WebSocketPeer(); ~WebSocketPeer(); diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp index 88a306c7f52..088f266f186 100644 --- a/modules/websocket/wsl_client.cpp +++ b/modules/websocket/wsl_client.cpp @@ -90,6 +90,7 @@ void WSLClient::_do_handshake() { data->is_server = false; data->id = 1; _peer->make_context(data, _in_buf_size, _in_pkt_size, _out_buf_size, _out_pkt_size); + _peer->set_no_delay(true); _on_connect(protocol); break; } diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index d7914295e91..08079145e45 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -318,6 +318,12 @@ uint16_t WSLPeer::get_connected_port() const { return _data->tcp->get_connected_port(); } +void WSLPeer::set_no_delay(bool p_enabled) { + + ERR_FAIL_COND(!is_connected_to_host() || _data->tcp.is_null()); + _data->tcp->set_no_delay(p_enabled); +} + void WSLPeer::invalidate() { if (_data) _data->valid = false; diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h index 2fbb7aeec3f..f1c45ee859a 100644 --- a/modules/websocket/wsl_peer.h +++ b/modules/websocket/wsl_peer.h @@ -109,6 +109,7 @@ public: virtual WriteMode get_write_mode() const; virtual void set_write_mode(WriteMode p_mode); virtual bool was_string_packet() const; + virtual void set_no_delay(bool p_enabled); void make_context(PeerData *p_data, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size, unsigned int p_out_pkt_size); Error parse_message(const wslay_event_on_msg_recv_arg *arg); diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index 44bfb4441d7..4db650a0c16 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -206,6 +206,7 @@ void WSLServer::poll() { Ref ws_peer = memnew(WSLPeer); ws_peer->make_context(data, _in_buf_size, _in_pkt_size, _out_buf_size, _out_pkt_size); + ws_peer->set_no_delay(true); _peer_map[id] = ws_peer; remove_peers.push_back(ppeer);