Приложение Elm перестает получать трансляции канала Phoenix
Вяз, феникс и эликсир довольно новы для меня, поэтому я подумал, что я сделаю приложение для тестирования каналов простым примером приложения для проверки использования каналов Феникса. В приложении есть и другие вещи, потому что оно сделано из старых "деталей", но потерпите меня.
Идея состоит в том, что у вас есть несколько genservers, делающих http-вызовы к конечной точке феникса. По сути, они просто обновляют список, содержащийся в процессе агента. Этот список отображается в приложении Elm через канал Phoenix. Цель состояла в том, чтобы просто посмотреть, что произойдет, если состояние агента часто обновляется несколькими процессами.
Так что это то, что я до сих пор. У меня есть сайт phoenix с настройкой приложения Elm и отдельным приложением Elixir с genservers, делающим обновления. Все работает нормально около 20 секунд, но затем соединение с каналом обрывается и не восстанавливается, пока я не нажму кнопку "Обновить" в браузере. Из журнала видно, что бэкэнд по-прежнему работает нормально, и в консоли браузера также нет ошибок. Так в чем здесь дело? Я думал, что соединение канала должно автоматически переподключиться, если оно потеряно, и почему оно все равно отключается?
Я предполагаю, что проблема с гнездом вяза-феникса. Вот это настройка в приложении 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
по сути, genservers постоянно обращаются к этой конечной точке сердцебиения. Я сомневаюсь, что проблема здесь, хотя. Другая возможность, где проблема заключается в настройке канала, которая выглядит следующим образом:
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 ответ
Ну, я решил это с этим:
transport :websocket, Phoenix.Transports.WebSocket,
timeout: :infinity
Не знаю, насколько это вредно, но это тестовое приложение не имеет большого значения.