Elixir应用启动后立即退出,如何使其持续运行?
Elixir WebSocket客户端启动后立即退出的解决办法
我编写了一个简单的Elixir应用,用于启动WebSocket客户端并监听消息。期望它能持续运行,但使用mix app.start启动后,应用会立即退出。以下是相关代码,请问需要如何修改才能让应用一直运行?
defmodule Example.WsClient do use WebSockex def start_link(state) do IO.puts "Starting WS Client" WebSockex.start_link("ws://example.com/ws", __MODULE__, state) end def handle_frame({type, msg}, state) do IO.puts "Received Message - Type: #{inspect type} -- Message: #{inspect msg}" {:ok, state} end def handle_cast({:send, {type, msg} = frame}, state) do IO.puts "Sending #{type} frame with payload: #{msg}" {:reply, frame, state} end end
defmodule Example.Application do # See https://hexdocs.pm/elixir/Application.html # for more information on OTP Applications @moduledoc false use Application @impl true def start(_type, _args) do children = [ # Starts a worker by calling: Example.Worker.start_link(arg) {Example.WsClient, []} ] # See https://hexdocs.pm/elixir/Supervisor.html # for other strategies and supported options opts = [strategy: :one_for_one, name: Example.Supervisor] Supervisor.start_link(children, opts) end end
解决办法
问题核心是WebSocket客户端进程没有被正确维持运行,或者启动方式没有让应用保持活跃。可以从以下几个方面修改:
1. 确保进程异常时自动重启
给Supervisor的子进程配置明确的重启策略,保证客户端进程意外退出后能被自动拉起:
修改后的Example.Application代码:
defmodule Example.Application do @moduledoc false use Application @impl true def start(_type, _args) do children = [ # 明确设置重启策略为:permanent,进程退出时自动重启 {Example.WsClient, [restart: :permanent]} ] opts = [strategy: :one_for_one, name: Example.Supervisor] Supervisor.start_link(children, opts) end end
2. 使用正确的启动命令保持应用运行
- 若要前台运行并保持不退出,使用:
mix run --no-halt - 若要后台运行,先构建发布包再启动:
mix release _build/prod/rel/example/bin/example start
mix app.start默认是启动后立即返回当前终端,不会阻塞进程,看起来像是退出,但如果客户端进程正常运行,应用其实在后台。但如果连接失败导致进程退出,上面的重启策略会自动重试连接。
3. 可选:添加断连重连逻辑
在客户端模块中添加handle_disconnect回调,处理断开连接的情况,实现自动重连:
修改后的Example.WsClient代码:
defmodule Example.WsClient do use WebSockex def start_link(state) do IO.puts "Starting WS Client" WebSockex.start_link("ws://example.com/ws", __MODULE__, state) end def handle_frame({type, msg}, state) do IO.puts "Received Message - Type: #{inspect type} -- Message: #{inspect msg}" {:ok, state} end def handle_cast({:send, {type, msg} = frame}, state) do IO.puts "Sending #{type} frame with payload: #{msg}" {:reply, frame, state} end # 处理断连,触发自动重连 def handle_disconnect(_reason, state) do IO.puts "Disconnected, attempting to reconnect..." {:reconnect, state} end end
内容的提问来源于stack exchange,提问作者Pavan Kumar
相关产品推荐
相关产品推荐

