榆树应用程序停止接收凤凰频道广播

时间:2016-09-24 08:28:54

标签: phoenix-framework elm phoenix-channels

Elm,phoenix和elixir对我来说都是新手,所以我想我会用channels test app简单的示例应用来测试凤凰频道的使用。该应用程序还包含其他内容,因为它是由旧的“部件”制成的,但在此依赖我。

这个想法是你有几个genservers对phoenix端点进行http调用。基本上他们只是更新代理进程中的列表。 该列表通过凤凰频道显示在Elm应用程序中。目标只是看看如果代理状态经常通过多个进程更新会发生什么。

所以这就是我到目前为止所拥有的。我有凤凰网站与榆树应用程序设置和一个单独的Elixir应用程序与genservers进行更新。一切都可以正常工作大约20秒,但是除非我在浏览器上点击刷新,否则通道连接会被切断而不会重新建立。我可以从日志记录中看到后端仍然正常工作,浏览器控制台上也没有错误。那么这笔交易是什么?我认为如果丢失了频道连接应该自动重新连接,为什么它会断开连接?

我猜测问题出在elm-phoenix-socket上。这是在榆树应用程序中设置:

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

因此,本质上,gen服务器不断地调用该心跳端点。我怀疑这个问题在这里。问题所在的另一种可能性是通道设置,如下所示:

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

所以任何想法是什么问题?我猜这是非常简单的事情。

好的,我现在知道套接字传输超时了。但为什么会这样呢?

1 个答案:

答案 0 :(得分:2)

好吧,我解决了这个问题:

yield :sidebar

不知道有多害,但这是一个测试应用并不重要。