Приложение Elm перестает принимать трансляции канала phoenix

Вяз, феникс и эликсир для меня совершенно новые, поэтому я решил сделать приложение для тестирования каналов простой пример приложения для проверки использования каналов phoenix. В приложении есть и другие вещи, потому что оно сделано из старых «деталей», но потерпите меня в этом.

Идея состоит в том, что у вас есть несколько серверов генерации, выполняющих http-вызовы на конечную точку phoenix. По сути, они просто обновляют список, хранящийся в процессе агента. Этот список отображается в приложении Elm через канал phoenix. Цель состояла в том, чтобы просто посмотреть, что произойдет, если состояние агента будет часто обновляться несколькими процессами.

Так что это то, что у меня есть до сих пор. У меня есть сайт phoenix с настройкой приложения Elm и отдельное приложение Elixir с генерирующими серверами, делающими обновления. Все работает нормально около 20 секунд, но затем соединение канала обрывается и не восстанавливается, пока я не нажму «Обновить» в браузере. Из журнала я вижу, что серверная часть все еще работает нормально, и в консоли браузера также нет ошибок. Так в чем же дело? Я думал, что соединение с каналом должно автоматически переподключаться при потере и почему оно все равно отключается?

Я предполагаю, что проблема связана с elm-phoenix-socket . Вот как это настроено в приложении elm:

socketServer : String
socketServer =
    "ws://localhost:4000/socket/websocket"

initPhxSocket : Phoenix.Socket.Socket Msg
initPhxSocket =
    Phoenix.Socket.init socketServer
        |> Phoenix.Socket.withDebug
        |> Phoenix.Socket.on "new:heartbeats" "heartbeats:lobby" ReceiveHeartbeats

Вот как выполняется трансляция на бэкенде:

defmodule AbottiWeb.ApiController do
  use AbottiWeb.Web, :controller

  def index(conn, _params) do
    beats = AbottiWeb.HeartbeatAgent.get()
    json conn, beats
  end
  def heartbeat(conn, %{"agent" => agent} ) do
    AbottiWeb.HeartbeatAgent.update(agent)
    beats = AbottiWeb.HeartbeatAgent.get()
    AbottiWeb.Endpoint.broadcast("heartbeats:lobby", "new:heartbeats", beats)
    json conn, :ok
  end
end

так что, по сути, генераторы постоянно звонят в эту конечную точку пульса. Я сомневаюсь, что проблема здесь, хотя. Другая возможность, в которой кроется проблема, — это настройка канала, которая выглядит следующим образом:

user_socket.ex:

defmodule AbottiWeb.UserSocket do
  use Phoenix.Socket

  channel "heartbeats:*", AbottiWeb.HeartbeatChannel

  transport :websocket, Phoenix.Transports.WebSocket

  def connect(_params, socket) do
    {:ok, socket}
  end

  def id(_socket), do: nil
end

и heartbeat_channel.ex:

defmodule AbottiWeb.HeartbeatChannel do
  use AbottiWeb.Web, :channel
  require Logger
  def join("heartbeats:lobby", payload, socket) do
    Logger.debug "Hearbeats:lobby joined: #{inspect payload}"
    if authorized?(payload) do
      {:ok, socket}
    else
      {:error, %{reason: "unauthorized"}}
    end
  end

  # Channels can be used in a request/response fashion
  # by sending replies to requests from the client
  def handle_in("ping", payload, socket) do
    {:reply, {:ok, payload}, socket}
  end

  # It is also common to receive messages from the client and
  # broadcast to everyone in the current topic (heartbeats:lobby).
  def handle_in("shout", payload, socket) do
    broadcast socket, "shout", payload
    {:noreply, socket}
  end

  # This is invoked every time a notification is being broadcast
  # to the client. The default implementation is just to push it
  # downstream but one could filter or change the event.
  def handle_out(event, payload, socket) do
    Logger.debug "Broadcasting #{inspect event} #{inspect payload}"
    push socket, event, payload
    {:noreply, socket}
  end

  # Add authorization logic here as required.
  defp authorized?(_payload) do
    true
  end
end

Итак, есть идеи, в чем проблема? Я предполагаю, что это что-то очень простое.

Хорошо, теперь я знаю, что время передачи сокетов истекло. Но почему это происходит?


person Jukka Puranen    schedule 24.09.2016    source источник


Ответы (1)


Ну, я решил это с помощью:

  transport :websocket, Phoenix.Transports.WebSocket,
    timeout: :infinity

Не знаю, насколько это вредно, но поскольку это тестовое приложение, это не имеет большого значения.

person Jukka Puranen    schedule 24.09.2016
comment
Каким-то образом этот параметр игнорируется для меня, и закрытое соединение закрывается через 60 секунд. - person mxgrn; 10.10.2017