Elm、Phoenix、およびElixirは私には全く新しいので、私はchannels test appという簡単なサンプルアプリケーションをphoenixチャンネルの使用をテストすると思っていました。このアプリは古い「部品」から作られているので、他のものもありますが、これで私と一緒に裸です。Elmアプリケーションがフェニックスチャンネルのブロードキャストの受信を停止します
phoenixエンドポイントにhttpコールを発信するいくつかのgenserversがあるという考えがあります。基本的には、エージェントプロセスで保持されているリストを更新するだけです。 このリストは、phoenixチャンネルを通じてElmアプリに表示されます。目標は、エージェントの状態が複数のプロセスで頻繁に更新される場合に何が起こるかを確認することでした。
これは私がこれまで持っているものです。私はElm appの設定を持つphoenixサイトとgenserversが更新を行う別のElixir appを持っています。すべてがうまくいくのは約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
はとても本質的にgenserversは常にそのハートビートエンドポイントへの呼び出しを行っています。私は問題がここにあることを疑う。だから、
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
問題が何であるか任意のアイデア:
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問題があるもう一つの可能性は次のようになりますチャネル設定ですか?それを推測するImは本当に簡単なことです。
これで、ソケットの転送がタイムアウトすることがわかりました。しかしそれはなぜそれをしますか?
何とかこの設定が無視され、60秒後にsocked接続が閉じられます。 – mxgrn