mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-04-12 11:48:30 +00:00
Enhance WebSocket support with unresponsive-peer detection and documentation updates
- Added `set_websocket_max_missed_pongs` method to configure unresponsive-peer detection. - Updated README and documentation to clarify WebSocket limitations and features. - Introduced tests for detecting non-responsive peers and ensuring responsive peers do not trigger timeouts.
This commit is contained in:
@@ -57,4 +57,24 @@ Too short wastes bandwidth; too long and connections get dropped. As a rule of t
|
||||
|
||||
> **Warning:** A very short ping interval spawns background work per connection and increases CPU usage. For servers with many connections, keep the interval modest.
|
||||
|
||||
## Detecting an unresponsive peer
|
||||
|
||||
Sending pings alone doesn't tell you anything if the peer just silently dies — the TCP socket might still look open while the process on the other end is long gone. To catch that, enable the max-missed-pongs check: if N consecutive pings go unanswered, the connection is closed.
|
||||
|
||||
```cpp
|
||||
cli.set_websocket_max_missed_pongs(2); // close after 2 consecutive unacked pings
|
||||
```
|
||||
|
||||
The server side has the same `set_websocket_max_missed_pongs()`.
|
||||
|
||||
With a 30-second ping interval and `max_missed_pongs = 2`, a dead peer is detected within roughly 60 seconds and the connection is closed with `CloseStatus::GoingAway` and the reason `"pong timeout"`.
|
||||
|
||||
The counter is reset whenever `read()` consumes an incoming Pong frame, so this only works if your code is actively calling `read()` in a loop — which is what a normal WebSocket client does anyway.
|
||||
|
||||
### Why the default is 0
|
||||
|
||||
`max_missed_pongs` defaults to `0`, which means "never close the connection because of missing pongs." Pings are still sent on the heartbeat interval, but their responses aren't checked. If you want unresponsive-peer detection, set it explicitly to `1` or higher.
|
||||
|
||||
Even with `0`, a dead connection won't linger forever: while your code is inside `read()`, `CPPHTTPLIB_WEBSOCKET_READ_TIMEOUT_SECOND` (default **300 seconds = 5 minutes**) acts as a backstop and `read()` fails if no frame arrives in time. Think of `max_missed_pongs` as the knob for detecting an unresponsive peer **faster** than that.
|
||||
|
||||
> For handling a closed connection, see [W03. Handle connection close](w03-websocket-close).
|
||||
|
||||
@@ -57,4 +57,24 @@ WebSocketプロトコルでは、PingフレームにはPongフレームで応答
|
||||
|
||||
> **Warning:** Ping間隔を極端に短くすると、WebSocket接続ごとにバックグラウンドでスレッドが走るので、CPU負荷が上がります。接続数が多いサーバーでは控えめな値に設定しましょう。
|
||||
|
||||
## 無応答のピアを検出する
|
||||
|
||||
Pingを送るだけでは、相手が「黙って落ちた」場合に気付けません。TCPの接続自体は生きているように見えるのに、相手のプロセスはもう応答しない、というケースです。これを検出するには、送ったPingに対してPongがN回連続で返ってこなかったら接続を切る、というオプションを有効にします。
|
||||
|
||||
```cpp
|
||||
cli.set_websocket_max_missed_pongs(2); // 2回連続でPongが返ってこなければ切断
|
||||
```
|
||||
|
||||
サーバー側にも同じ`set_websocket_max_missed_pongs()`があります。
|
||||
|
||||
たとえばPing間隔が30秒で`max_missed_pongs = 2`なら、無応答のピアは約60秒で検出され、`CloseStatus::GoingAway`(理由は`"pong timeout"`)で接続が閉じられます。
|
||||
|
||||
この仕組みは`read()`を呼んでPongフレームを消費したタイミングでカウンタがリセットされます。つまり通常のWebSocketクライアントのように`read()`をループで回していれば、特に意識することなく動きます。
|
||||
|
||||
### デフォルトは無効
|
||||
|
||||
`max_missed_pongs`のデフォルトは`0`で、これは「Pongが何回返ってこなくてもこの仕組みでは切断しない」という意味です。Ping自体は送られ続けますが、応答の有無はチェックされません。無応答ピアを検出したい場合は明示的に`1`以上を設定してください。
|
||||
|
||||
ただし`0`のままでも最終的に接続が残り続けることはありません。`read()`を呼んでいる間は`CPPHTTPLIB_WEBSOCKET_READ_TIMEOUT_SECOND`(デフォルト**300秒 = 5分**)が保険として働き、フレームが一定時間来なければ`read()`が失敗します。つまり`max_missed_pongs`は「**もっと速く**無応答を検出したい」ときに使うオプションだと考えてください。
|
||||
|
||||
> 接続が閉じたときの処理は[W03. 接続クローズをハンドリングする](w03-websocket-close)を参照してください。
|
||||
|
||||
Reference in New Issue
Block a user