pjfanning opened a new pull request, #1369:
URL: https://github.com/apache/pekko-http/pull/1369

   ### Motivation
   A WebSocket connection whose network path is lost (e.g. a peer that 
disappears without closing the TCP connection) can go unnoticed for a long 
time. Periodic keep-alive Pings alone don't fail the connection when no Pong 
comes back.
   
   ### Modification
   - New settings `pekko.http.{server,client}.websocket.receive-idle-timeout` 
and `send-idle-timeout`, default `infinite` (disabled). `WebSocketSettings` 
gets `receiveIdleTimeout`/`sendIdleTimeout`, Java 
`getReceiveIdleTimeout`/`getSendIdleTimeout`, and 
`withReceiveIdleTimeout`/`withSendIdleTimeout` for Scala and 
`java.time.Duration`, following the existing `periodicKeepAliveMaxIdle` pattern 
(all `@since 2.0.0`).
   - An idle-timeout layer in the WebSocket stack fails the flow when no frame 
is received or sent within the configured time.
   - Docs: `reference.conf`, plus an "Idle timeouts" section in the server and 
client WebSocket pages.
   - MiMa: new `websocket-idle-timeouts.excludes` for the abstract methods 
added to the `@DoNotInherit` `WebSocketSettings`. Its license header is copied 
from the sibling excludes files, since sbt's header plugin doesn't manage 
`.excludes` files.
   
   #### Differences from akka/akka-http#4289
   - **Layer placement.** akka-http put the idle-timeout layer above 
`frameHandling`. But `FrameHandler` drops incoming Pong frames, so Pong replies 
to keep-alive Pings never reached it, and a connection that was idle but alive 
timed out anyway. That defeats the "combine with 
`periodic-keep-alive-max-idle`" use case. Here the layer sits directly above 
masking, so every frame, Pings and Pongs included, counts as activity.
   - **Exception type.** akka-http failed with `StreamIdleTimeoutException`. 
Pekko's client TCP connection (`TcpIdleTimeout` in pekko-stream) rewrites any 
`TimeoutException` heading to the network into `TcpIdleTimeoutException("TCP 
idle-timeout ..., no bytes passed in the last 60 seconds")`, so a client 
`send-idle-timeout` was reported as a TCP idle timeout. This PR adds 
`WebSocketIdleTimeoutException` (a `RuntimeException`, `@since 2.0.0`), thrown 
by a small private stage in both directions (downstream failure and upstream 
cancellation), with a message naming the WebSocket setting and value.
   - **Tests and setters.** akka-http needed separate spec classes to change 
server settings through actor system config. With the `withX` setters, one spec 
(`WebSocketIdleTimeoutSpec`) covers server and client in both directions, the 
keep-alive case, and the settings themselves.
   
   ### Result
   Users can detect lost WebSocket connections, e.g. by combining 
`receive-idle-timeout` with `periodic-keep-alive-max-idle` in `ping` mode, as 
long as the peer answers Pings.
   
   ### Tests
   - `sbt "http-core/Test/testOnly 
org.apache.pekko.http.impl.engine.ws.WebSocketIdleTimeoutSpec 
org.apache.pekko.http.impl.engine.ws.WebSocketIntegrationSpec"`: 12 passed 
(Scala 2.13); `WebSocketIdleTimeoutSpec`: 6 passed on Scala 3.3.8
   - With the idle layer moved above frame handling (akka-http's placement), 
the keep-alive test fails with `WebSocketIdleTimeoutException` (directional)
   - `sbt http-core/mimaReportBinaryIssues`: pass
   - `sbt docs/paradox`: pass
   - `scalafmt --mode diff-ref=upstream/main`: no changes
   
   ### References
   Port of akka/akka-http#4289 (Apache 2.0 now applies, since the Akka HTTP 
10.6.0 license change date of 2026-10-23), with the differences above. The 
tests in `WebSocketIdleTimeoutSpec` are adapted from that PR's tests.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to