Visitar URL original
Do websockets NEED a ping thread? [ResponseRaw auto-closes on no-traffic] · Issue #1054 · yesodweb/wai · GitHub
Skip to content

Do websockets NEED a ping thread? [ResponseRaw auto-closes on no-traffic] #1054

Description

@Vlix

I've been looking through the code and noticed that the handling of RspRaw will only tickle the time-manager's Handle if there is traffic.
Seeing as the ResponseRaw variant is used for websockets, this is probably the reason lots of people who use warp + websockets for the first time encounter the sudden closing of the websocket and fix it by using a ping thread.

-- warp/Network.Wai.Handler.Warp.Response:L281
sendRsp conn _ th _ _ _ _ _ _ (RspRaw withApp src) = do
    withApp recv send
    return (Nothing, Nothing)
  where
    recv = do
        bs <- src
        unless (S.null bs) $ T.tickle th
        return bs
    send bs = connSendAll conn bs >> T.tickle th

Is it maybe a good idea to have more control over the usage of ResponseRaw, so we can disable the timeout (or use a different configurable timeout) for the ResponseRaw constructor? I don't feel like we need to avoid a slow-loris attack after the websocket is already established, right?

If there are other reasons a websocket connection should be terminated on lack of traffic, I hope someone will share them here.

Activity

  1. added theissue type on Jan 9, 2026
  2. kazu-yamamoto commented on Jan 13, 2026

    @kazu-yamamoto
    Contributor

    It's OK to change RspRaw as you like.
    For example, you can add functions to make response (like responseRaw) to WAI and extend RspRaw with an auxiliary data structure.
    I believe this does not break the compatibility.

  3. thomasjm commented on May 19, 2026

    @thomasjm
    Contributor

    I believe the reason pretty much everyone uses a ping thread for websockets is because network equipment in the middle (NAT, load balancers, proxies) may terminate idle TCP connections.

    But I agree that Warp shouldn't add to the problem by terminating idle WebSocket connections itself. It would be great if we could fix this.

  4. Vlix commented on May 19, 2026

    @Vlix
    ContributorAuthor

    When I mentioned a "ping thread", I meant a thread that pends pings as message frames (e.g. from JavaScript apps) instead of the protocol ping frames. Though now that I look at it again, it should work with ping frames already, since a pong frame coming back would trigger the tickle (AFAICT)

    We'll have to look at the implementation of websockets using the RspRaw constructor to see if that's true. But even then, the RspRaw connection should be completely up to the user to implement, so it might be better to give the option of killing connections that don't receive any data, or not. That way, whoever implements a custom connection "style" (like websockets) can decide how it should function 🤔

  5. thomasjm commented on May 19, 2026

    @thomasjm
    Contributor

    FWIW I've always used protocol ping/pong frames and it's worked fine with Warp.

  6. Vlix commented on May 19, 2026

    @Vlix
    ContributorAuthor

    In our customer-facing application, we'd had a lot of connections dropping when there was low traffic (even with a ping thread sending ping frames)
    And sending PING/PONG message frames seemed to fix most of that issue, but that could also just have been a JavaScript/browser issue, and not a server/warp issue. 🤔

    Regardless, giving the user more options seems like the right course of action.

  7. thomasjm commented on May 19, 2026

    @thomasjm
    Contributor

    Yeah that's weird, browsers are supposed to auto-respond to protocol pings. But yeah I agree!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions