8000 No reconnection (and lack of debugger) · Issue #129 · dominicletz/websockex · GitHub
[go: up one dir, main page]

Skip to content

No reconnection (and lack of debugger) #129

Open

Description

@centuriononon

Conditions

OS: Arch Linux x86_64
Kernel: 6.8.1-arch1-1
Erlang: 26.0
Elixir: 1.16.0-otp-26

Dependencies:
Jason: 0.4.3
WebSockex: 1.4.1

Description

The problem is that when disconnecting the ethernet device, the WebSockex server does not always reconnect.

It reconnects only if the connection is lost for no more than 5 seconds. If more time has passed, it does not reconnect anymore and the debugger does not register anything useful.

Flow I expected

  1. Check ethernet status: eno1 connected
  2. Connect WebSockex: start my BasicSocket, establish connection, and subscribe on events (exchange stuff)
  3. Disconnect ethernet, socket lost connection and does not receive events
  4. Wait for a while...
  5. Connect ethernet, socket establishes connection and continue receive events

Flow 1: Fast reconnection, as I expected

  1. Check ethernet status...
  2. Connect WebSockex...
  3. Disconnect ethernet...
  4. Wait for at most 5 seconds
  5. Connect ethernet, socket maybe establishes connection and receive events anymore!

Flow 2: Long reconnection, as I did not expected

  1. Check ethernet status...
  2. Connect WebSockex...
  3. Disconnect ethernet...
  4. Wait for at least 5 seconds
  5. Connect ethernet, socket maybe establishes connection and does not receive events anymore!

Initial setup 15:01:47 (eno1 connected, socket receives events):
image

  • I started new WebSockex server, and subscribed on events with a special subscription message -- socket established connection, socket began receiving events.

Disconnection 15:02:10 (eno1 disconnected, socket does not receive events):
image

  • I disconnected eno1 (my ethernet), and it stopped socket.

Reconnection 15:07:12 (eno1 connected, socket still does not receive events)
image

  • I reconnected eno1 again. But still no events. And even no logs. It even does not try to establish connection again.

BasicSocket:

defmodule Experiments.BasicSocket do
  use WebSockex

  require Logger

  alias :zlib, as: Zlib
  alias Experiments.BasicSocket.Helpers

  @origin "wss://open-api-swap.bingx.com/swap-market"

  def start_link(state, options \\ []) do
    WebSockex.start_link(@origin, __MODULE__, state, options)
  end

  def send(pid, message) do
    WebSockex.cast(pid, {:"$send", message})
  end

  @impl true
  def handle_connect(_conn, state) do
    channel = Helpers.sub_message()
    __MODULE__.send(self(), channel)

    {:ok, state}
  end

  @impl true
  def handle_disconnect(_details, state) do
    {:reconnect, state}
  end

  @impl true
  def handle_frame({:binary, frame}, state) do
    case Zlib.gunzip(frame) do
      "Ping" ->
        {:reply, {:text, "Pong"}, state}

      _ ->
        Logger.info("*INFO* event received")
        {:ok, state}
    end
  end

  @impl true
  def handle_cast({:"$send", message}, state) do
    {:reply, {:text, message}, state}
  end
end

Main question

Why WebSockex reconnects for a short disconnection periods, and does not reconnect for long periods in this case?

Side question

Why is the debugger so laggy in iex sessions?

Are there other options to debug my case? How can I get additional information about what happens under the "hood"?

Activity

  1. roylez commented on May 2, 2024

    @roylez

    Thanks for pointing me to the right direction as this has been troubling me for some time.

    A workaround is to send a ping frame every 30 seconds.

      def handle_pong(_, %{ connected: false }=state), do: {:ok, state}
      def handle_pong(_, %{ connected: true }=state),  do: {:ok, %{ state| pong_received: true }}
    
      def handle_connect(_conn, _state) do
        Process.send_after(self(), :ping_timeout, @ping_timeout)
        { :ok, %__MODULE__{ pong_received: true, connected: true } }
      end
    
      def handle_info(:ping_timeout, state) do
        case state do
          %{ pong_received: true } ->
            Process.send_after(self(), :ping_timeout, @ping_timeout)
            {:reply, {:ping, ""}, %{ state| pong_received: false }}
          %{ pong_received: false } ->
            {:close, state}
        end
      end
  2. kyleboe commented on Mar 3, 2026

    @kyleboe

    Amazing! I think this is the issue I've been having as well with an app deployed to Fly.

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

      0