问题描述:

How to do multiplexing sockets in Elixir? I need connect to core banking, but it only accepts just one tcp connection and my app received many concurrent connections. Any suggestions?

网友答案:

I'd wrap the whole socket handling in a GenServer, which will then act as a gateway and only process one message at a time. For example:

defmodule Client do
  use GenServer
  @name __MODULE__

  # API

  def start_link do
    GenServer.start_link(__MODULE__, :ok, [name: @name])
  end

  def command(data) do
    GenServer.call(@name, {:command, data})
  end

  # GenServer implementation

  def init(:ok) do
    :gen_tcp.connect('localhost', 9999, [active: false, packet: :line])
  end

  def handle_call({:command, data}, _from, socket) do
    :gen_tcp.send(socket, data <> "\n")
    {:ok, result} = :gen_tcp.recv(socket, 0)
    {:reply, result, socket}
  end
end

Then you can send many commands to the API client, but it will only process one message at a time. For example if you send 10 messages at the same time, these will get sent over the socket one after another all using a single TCP connection.

Client.start_link

tasks = for x <- 1..10 do
  Task.async fn ->
    IO.puts Client.command("Hello world #{x}!")
  end
end

for task <- tasks do
  Task.await(task)
end

You can test this locally by creating a simple echo server with socat:

socat -v tcp-l:9999,reuseaddr,fork exec:cat
相关阅读:
Top