# WebSocket state monitoring

**URL:** <https://softwaremill.community/t/websocket-state-monitoring/308>\
**Category:** sttp client\
**Created:** [November 1, 2023, 10:07am UTC](https://softwaremill.community/t/websocket-state-monitoring/308 "2023-11-01T10:07:32Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![ycomb](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/ycomb/32/199_2.png) [@ycomb](https://softwaremill.community/u/ycomb)\
**Post date:** [November 1, 2023, 10:07am UTC](https://softwaremill.community/t/websocket-state-monitoring/308/1 "2023-11-01T10:07:32Z")

</div>

Hi,

I’m trying to adopt `sttp4` client to interact with a server via WebSockets. WebSockets seems unstable. For example, if the connection drops `sttp4` throws exception `Caused by: java.io.IOException: Software caused connection abort`. Sometimes exception `Caused by: java.io.IOException: Operation timed out` occurs.

I’m using code from an example:

```java
  implicit val runtime: IORuntime = cats.effect.unsafe.implicits.global

  private def webSocketFramePipe: Pipe[IO, WebSocketFrame.Data[_], WebSocketFrame] = { input =>
    Stream.emit(WebSocketFrame.text("""
                                      |{
                                      | "op": "subscribe",
                                      | "args": [
                                      | "topic-name"
                                      | ]
                                      |}
                                      |""".stripMargin)) ++ input.flatMap {
      case WebSocketFrame.Text(n, _, _) =>
        println(s"received: $n")
        Stream.emit(WebSocketFrame.Ping(Array(2)))

      case x =>
        println("...other...")
        Stream.empty // ignoring
    }
  }

  HttpClientFs2Backend
    .resource[IO]()
    .use { backend =>
      basicRequest
        .get(uri"wss://stream.server.com/public")
        .response(asWebSocketStream(Fs2Streams[IO])(webSocketFramePipe))
        .send(backend)
        .void
    }
    .unsafeRunSync()

```

How can I monitor the state of a websocket? And reconnect it if it fails?

I also tried and found out that sending `Stream.empty` in `case WebSocketFrame.Text(n, _, _) =>` stops streaming after ~30 frames. But if in send `WebSocketFrame.Ping` in response, then the server sends frames infinitely. What proper message should I send in response to `case WebSocketFrame.Text(...)=>`?

---

<div class="post-metadata">

**Author:** ![adamw](https://dub1.discourse-cdn.com/flex005/user_avatar/softwaremill.community/adamw/32/28_2.png) [@adamw](https://softwaremill.community/u/adamw)\
**Post date:** [November 21, 2023, 3:34pm UTC](https://softwaremill.community/t/websocket-state-monitoring/308/2 "2023-11-21T15:34:09Z")

</div>

Thanks for the report and sorry for the late response 🙂

I think you might be hitting several different problems, on various levels.

First, if the connection drops, I think an `IOException` is the correct behaviour, that is it’s something you would expect. You might get different results depending on the server - if it closed the connection properly (with a `Close` frame), or just silently stopped responding to packets.

Secondly, reconnecting a websocket I think requires performing the `.send` again, if there’s an error. You can do an infitie-loop style `def doSend = basicRequest.(...).send(backend).recover(doSend)`, but you’ll probably will want to add some limits to the number of iterations.

Thirdly, there’s the ping-pong behavior. The backend you are using doesn’t perform automatic pings, and it seems that is what your server requires (so that it knows that the client is alive). We should probably add it, along with fixing the example (so that it at least returns `Pong`s on `Ping`s). I’ve [created an issue](https://github.com/softwaremill/sttp/issues/2005) to cover this.

As for monitoring, what kind of monitoring would you need? There’s the [loggin backend](https://sttp.softwaremill.com/en/stable/backends/wrappers/logging.html), plus the [metrics backends](https://sttp.softwaremill.com/en/stable/backends/wrappers/opentelemetry.html). Or did you have something else in mind?
