gen_udp в Elixir не может подключиться к UDP-сокету - PullRequest
0 голосов
/ 08 октября 2019

Я пытаюсь заставить Graphitex (клиент Graphite Carbon API для Elixir) использовать gen_udp вместо gen_tcp.

Клиент - это GenServer, который упаковывает UDPсокет с общедоступным API, который не связан с вопросом.

Кажущиеся биты выглядят как connect/1, terminate/2 и handle_cast/2 GenServer callbacks.

Исходная реализация может бытьнашел здесь , моя вилка здесь .

Что я сделал:

  • заменил :gen_tcp.connect(host, port, opts) (где host и port - это значения удаленной конечной точки Graphite Carbon UDP) с :gen_udp.open(0, opts) (чтобы получить выбранный ОС порт)
  • заменено :gen_tcp.send(socket, msg) на :gen_udp.send(socket, host, port, msg) для отправки msg на удаленный host:port черезВыбранный ОС сокет UDP

Ошибка, возникающая при запуске приложения с моим форком graphitex:

12:12:14.160 [info]  Connecting to carbon at localhost:2003
12:12:14.383 [error] GenServer Graphitex.Client terminating
** (FunctionClauseError) no function clause matching in Graphitex.Client.terminate/2
    (graphitex) lib/graphitex/client.ex:78: Graphitex.Client.terminate({{:badmatch, {:error, :econnrefused}}, [{Graphitex.Client, :connect, 1, [file: 'lib/graphitex/client.ex', line: 73]}, {Graphitex.Client, :handle_cast, 2, [file: 'lib/graphitex/client.ex', line: 86]}, {:gen_server, :try_dispatch, 4, [file: 'gen_server.erl', line: 637]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 711]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}]}, %{socket: nil})
    (stdlib) gen_server.erl:673: :gen_server.try_terminate/3
    (stdlib) gen_server.erl:858: :gen_server.terminate/10
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", {:metric, 'graphite_consumer 1000 1570525934\n'}}
State: %{socket: nil}

Кажется, что сокет (который я четко вставил всостояние в connect/1) равно nil. Я озадачен, почему это может быть;:gen_udp.open(0) в IEx работает нормально и возвращает {:ok, socket}.

1 Ответ

1 голос
/ 21 октября 2019

UDP - это протокол без установления соединения, что означает, что вам не нужно подключаться к удаленному сокету для отправки данных. Все, что вам нужно сделать, это:

{:ok, socket} = :gen_udp.open(0)

:ok = :gen_udp.send(socket, host, port, msg)

Нет необходимости в подключении, поэтому нет документации для :gen_udp.connect, так как она вообще не должна использоваться.

...