Browse Source

[WebSocket] Ensure TCP_NODELAY is always set

Almost all WebSocket implementations (including all major browsers)
disable Nagle's algorithm to favor low latency over packet overhead.

This was also the case in Godot 3.x, while in Godot 4.0 this was only
being done for clients and wasn't even always working due to a bug.

This commit fixes the aforementioned bug, and forces TCP_NODELAY when
accepting a stream as a server.
Fabio Alessandrelli 1 year ago
parent
commit
d65e7aab76
2 changed files with 3 additions and 2 deletions
  1. 1 1
      modules/websocket/doc_classes/WebSocketPeer.xml
  2. 2 1
      modules/websocket/wsl_peer.cpp

+ 1 - 1
modules/websocket/doc_classes/WebSocketPeer.xml

@@ -139,7 +139,7 @@
 			<return type="void" />
 			<param index="0" name="enabled" type="bool" />
 			<description>
-				Disable Nagle's algorithm on the underling TCP socket (default). See [method StreamPeerTCP.set_no_delay] for more information.
+				Disable Nagle's algorithm on the underlying TCP socket (default). See [method StreamPeerTCP.set_no_delay] for more information.
 				[b]Note:[/b] Not available in the Web export.
 			</description>
 		</method>

+ 2 - 1
modules/websocket/wsl_peer.cpp

@@ -99,7 +99,6 @@ void WSLPeer::Resolver::try_next_candidate(Ref<StreamPeerTCP> &p_tcp) {
 		p_tcp->poll();
 		StreamPeerTCP::Status status = p_tcp->get_status();
 		if (status == StreamPeerTCP::STATUS_CONNECTED) {
-			p_tcp->set_no_delay(true);
 			ip_candidates.clear();
 			return;
 		} else if (status == StreamPeerTCP::STATUS_CONNECTING) {
@@ -113,6 +112,7 @@ void WSLPeer::Resolver::try_next_candidate(Ref<StreamPeerTCP> &p_tcp) {
 	while (ip_candidates.size()) {
 		Error err = p_tcp->connect_to_host(ip_candidates.pop_front(), port);
 		if (err == OK) {
+			p_tcp->set_no_delay(true);
 			return;
 		} else {
 			p_tcp->disconnect_from_host();
@@ -142,6 +142,7 @@ Error WSLPeer::accept_stream(Ref<StreamPeer> p_stream) {
 	}
 	ERR_FAIL_COND_V(connection.is_null() || tcp.is_null(), ERR_INVALID_PARAMETER);
 	is_server = true;
+	tcp->set_no_delay(true);
 	ready_state = STATE_CONNECTING;
 	handshake_buffer->resize(WSL_MAX_HEADER_SIZE);
 	handshake_buffer->seek(0);