From 56f28c5393d85688cf805112d62d8b1119580d46 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Dec 2025 01:37:25 +0000 Subject: [PATCH 1/5] Initial plan From 47583fba30f80d9136a1bbba2b2890ffd178c433 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Dec 2025 01:55:19 +0000 Subject: [PATCH 2/5] Fix WebSocket sendFrame delay by enabling TCP_NODELAY - Enable TCP_NODELAY in WebSocketImpl constructor to prevent Nagle's algorithm from buffering small WebSocket frames - Add check to skip TCP_NODELAY for Unix domain sockets - Add documentation about TCP_NODELAY behavior to WebSocket class - Tested with existing WebSocket test suite - all tests pass Co-authored-by: aleks-f <2429093+aleks-f@users.noreply.github.com> --- Net/include/Poco/Net/WebSocket.h | 4 ++++ Net/src/WebSocketImpl.cpp | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/Net/include/Poco/Net/WebSocket.h b/Net/include/Poco/Net/WebSocket.h index 8034ca2480..d0af70f324 100644 --- a/Net/include/Poco/Net/WebSocket.h +++ b/Net/include/Poco/Net/WebSocket.h @@ -54,6 +54,10 @@ class Net_API WebSocket: public StreamSocket /// mode, by calling setBlocking(false). /// Please refer to the sendFrame() and receiveFrame() documentation /// for non-blocking behavior. + /// + /// TCP_NODELAY is automatically enabled on the underlying socket + /// to prevent delays from Nagle's algorithm when sending small + /// WebSocket frames. { public: enum Mode diff --git a/Net/src/WebSocketImpl.cpp b/Net/src/WebSocketImpl.cpp index 64873cd280..5fba4743a0 100644 --- a/Net/src/WebSocketImpl.cpp +++ b/Net/src/WebSocketImpl.cpp @@ -18,6 +18,7 @@ #include "Poco/Net/NetException.h" #include "Poco/Net/WebSocket.h" #include "Poco/Net/HTTPSession.h" +#include "Poco/Net/SocketAddress.h" #include "Poco/Buffer.h" #include "Poco/BinaryWriter.h" #include "Poco/BinaryReader.h" @@ -42,6 +43,18 @@ WebSocketImpl::WebSocketImpl(StreamSocketImpl* pStreamSocketImpl, HTTPSession& s poco_check_ptr(pStreamSocketImpl); _pStreamSocketImpl->duplicate(); session.drainBuffer(_buffer); + // Enable TCP_NODELAY to prevent delays caused by Nagle's algorithm + // for small WebSocket frames. Skip for Unix domain sockets. + try + { + SocketAddress addr = _pStreamSocketImpl->address(); + if (addr.family() != SocketAddress::UNIX_LOCAL) + _pStreamSocketImpl->setNoDelay(true); + } + catch (...) + { + // Ignore errors (e.g., if socket is not connected yet or doesn't support TCP options) + } } From 8a3b177c5c7b24c402c5f888c76ff5610520bdf5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Dec 2025 01:58:26 +0000 Subject: [PATCH 3/5] Address code review feedback - Avoid unnecessary SocketAddress object construction by calling family() directly - Use specific exception type (Poco::Exception) instead of catch-all Co-authored-by: aleks-f <2429093+aleks-f@users.noreply.github.com> --- Net/src/WebSocketImpl.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Net/src/WebSocketImpl.cpp b/Net/src/WebSocketImpl.cpp index 5fba4743a0..e9c58d9a2f 100644 --- a/Net/src/WebSocketImpl.cpp +++ b/Net/src/WebSocketImpl.cpp @@ -47,11 +47,10 @@ WebSocketImpl::WebSocketImpl(StreamSocketImpl* pStreamSocketImpl, HTTPSession& s // for small WebSocket frames. Skip for Unix domain sockets. try { - SocketAddress addr = _pStreamSocketImpl->address(); - if (addr.family() != SocketAddress::UNIX_LOCAL) + if (_pStreamSocketImpl->address().family() != SocketAddress::UNIX_LOCAL) _pStreamSocketImpl->setNoDelay(true); } - catch (...) + catch (Poco::Exception&) { // Ignore errors (e.g., if socket is not connected yet or doesn't support TCP options) } From ca9b05072a3149390a1f3223acd4f3f3b144f2db Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Dec 2025 02:03:16 +0000 Subject: [PATCH 4/5] Refine exception handling for TCP_NODELAY configuration - Catch specific exception types (NetException, IOException, InvalidArgumentException) instead of broad Poco::Exception - Improve error handling comments for clarity Co-authored-by: aleks-f <2429093+aleks-f@users.noreply.github.com> --- Net/src/WebSocketImpl.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Net/src/WebSocketImpl.cpp b/Net/src/WebSocketImpl.cpp index e9c58d9a2f..04e039b6a2 100644 --- a/Net/src/WebSocketImpl.cpp +++ b/Net/src/WebSocketImpl.cpp @@ -50,9 +50,17 @@ WebSocketImpl::WebSocketImpl(StreamSocketImpl* pStreamSocketImpl, HTTPSession& s if (_pStreamSocketImpl->address().family() != SocketAddress::UNIX_LOCAL) _pStreamSocketImpl->setNoDelay(true); } - catch (Poco::Exception&) + catch (NetException&) { - // Ignore errors (e.g., if socket is not connected yet or doesn't support TCP options) + // Ignore socket errors (e.g., socket not connected or doesn't support TCP options) + } + catch (IOException&) + { + // Ignore I/O errors from socket configuration + } + catch (InvalidArgumentException&) + { + // Ignore invalid argument errors from socket configuration } } From f1879733b6d56f5edefcec9135fa02579f411eb0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Dec 2025 02:04:21 +0000 Subject: [PATCH 5/5] Consolidate exception handling for better maintainability - Combine catch blocks since all exceptions are handled identically - Improve code clarity with more descriptive comments Co-authored-by: aleks-f <2429093+aleks-f@users.noreply.github.com> --- Net/src/WebSocketImpl.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Net/src/WebSocketImpl.cpp b/Net/src/WebSocketImpl.cpp index 04e039b6a2..795c6c7068 100644 --- a/Net/src/WebSocketImpl.cpp +++ b/Net/src/WebSocketImpl.cpp @@ -52,15 +52,11 @@ WebSocketImpl::WebSocketImpl(StreamSocketImpl* pStreamSocketImpl, HTTPSession& s } catch (NetException&) { - // Ignore socket errors (e.g., socket not connected or doesn't support TCP options) + // Ignore - socket errors (e.g., not connected or doesn't support TCP options) } - catch (IOException&) + catch (Poco::Exception&) { - // Ignore I/O errors from socket configuration - } - catch (InvalidArgumentException&) - { - // Ignore invalid argument errors from socket configuration + // Ignore - other configuration errors (IOException, InvalidArgumentException, etc.) } }