I’m building a simple WebSocket client using the WebSockex library. I want to add a basic heartbeat mechanism to keep the connection alive and detect disconnects. Since the client is pretty simple, I was thinking of sending a ping message every few seconds like this:
@impl true
def handle_connect(_conn, state) do
IO.puts("Connected ....")
Process.send_after(self(), :heartbeat, 10_000)
{:ok, state}
end
def handle_info(:heartbeat, state) do
pid = WebSockex.Utils.whereis(...)
WebSockex.send_frame(pid, {:text, "ping"})
Process.send_after(self(), :heartbeat, 10_000)
{:ok, state}
end
This crashes with:
shell process exited with reason: {%WebSockex.CallingSelfError{function: :send_frame}, []}
However, it works fine if I extract the ping logic to a separate function and call it manually.
So my questions are:
- Why does calling
WebSockex.send_frame(...)
directly fromhandle_info
cause this crash? - What’s the idiomatic way to implement a heartbeat in WebSockex?
- How do you personally structure your WebSockex heartbeat logic?
Any pointers or code examples would be appreciated.