我正在使用elixir-socket库作为将我的后端应用程序连接到外部 websocket 的一种方式。我需要管理此过程(如果出现故障则重新启动,如果无法连接则以指数方式回退等)。
目前,我创建了一个管理 GenServer 进程,该进程在给定时间后生成一个循环套接字(如下所示)。我有一个主管管理SocketManager
(以及链接的Socket
)流程:
socket_manager.ex
defmodule MyApp.SocketManager do
def init(_) do
Process.flag(:trap_exit, true)
state = %{socket: nil}
{:ok, state, {:continue, :init}}
end
def handle_continue(:init, state) do
Task.start_link(fn ->
Socket.connect!()
end)
{:noreply, state}
end
end
套接字
defmodule MyApp.Socket do
def connect! do
socket = Socket.Web.connect!("xx.xx.com", secure: true, path: "/api/xxx")
SocketManager.socket_connected(socket) # save the socket in the SocketManager state
listen(socket)
end
defp listen(socket) do
case socket |> Socket.Web.recv!() do
{:text, data} ->
# handle message
{:close, :abnormal, _} ->
Process.exit(self(), :kill)
{:pong, _} ->
nil
end
listen(socket)
end
end
上面的效果很好,但是我不确定这是构造它的最佳方法。据我了解,Task
应该只针对具有确定生命周期的任务,而不是针对永久过程。此外,在运行时,mix dialyzer
我得到以下输出(参考 中的Task.spawn_link
行SocketManager
):
lib/myapp/socket_manager.ex:40:no_return
The created fun has no local return.
任何人都可以帮助我就如何构建它以及我如何能够满足 Dialyzer 提出建议?
谢谢!