Elixir 构建 TCP 应用
defmodule EliApp do use Application def start(_type, _args) do TCPServer.Supervisor.start_link([]) end end defmodule TCPServer do use GenServer def start_link(config \\ [{0,0,0,0}, 8010]) do GenServer.start_link(__MODULE__, config, name: __MODULE__) end def init([ip, port]) do {:ok, socket}= :gen_tcp.listen(port,[:binary, packet: :line, active: false, reuseaddr: true, ip: ip]) IO.puts("TCP listened at #{port} ...") loop_accept(socket) end def loop_accept(socket) do {:ok, client} = :gen_tcp.accept(socket) # 每一个连接单独开启一个进程,当多个客户端连接的时候,每个客户端对应不同的独立进程,不会相互影响和阻塞, # 每个独立进程都由 Supervisor 来管理,当一个进程崩溃的时候,不会影响到主进程,增加可用性和容错性 {:ok, pid} = Task.Supervisor.start_child(TCPServer.TaskSupervisor, fn ->server(client) end) :ok = :gen_tcp.controlling_process(client, pid) loop_accept(socket) end def server(socket) do socket |> read_line() |> String.split(" ") |> Enum.filter(& &1 != "") |> handler() |> write_line(socket) server(socket) end defp read_line(socket) do {:ok, data} = :gen_tcp.recv(socket, 0) data end defp handler(line) do case line do ["PUT", msg] -> "put " <> msg ["GET", msg] -> "get " <> msg ["ERROR", msg] -> raise "error: " <> msg [_] -> "what ever\r\n" end end defp write_line(line, socket) do :gen_tcp.send(socket, line) end end defmodule TCPServer.Task do use Task, restart: :permanent def start_link(opts) do Task.start_link(__MODULE__, :run, [opts]) end def run(opts) do TCPServer.start_link(opts) end end defmodule TCPServer.Supervisor do use Supervisor def start_link(opts) do Supervisor.start_link(__MODULE__, :ok, opts) end def init(:ok) do children = [ {Task.Supervisor, name: TCPServer.TaskSupervisor}, {TCPServer.Task, [{0, 0, 0, 0}, 8020]} ] Supervisor.init(children, strategy: :one_for_one) end end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: 使用 R 发送邮件
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论