Elixir 构建 TCP 应用

发布于 2023-10-31 10:29:26 字数 2017 浏览 28 评论 0

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

文章
评论
26 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文