0

我正在尝试使用Graphitex(Elixir 的 Graphite Carbon API 客户端)gen_udp代替gen_tcp.

客户端是包装 UDP 套接字的 GenServer,具有与问题无关的公共 API。

有问题的位似乎是connect/1,terminate/2handle_cast/2GenServer 回调。

原始实现可以在这里找到,我的 fork 在这里

我做了什么:

  • 用(获取操作系统选择的端口)替换:gen_tcp.connect(host, port, opts)(远程 Graphite Carbon UDP 端点的位置host和位置)port:gen_udp.open(0, opts)
  • 替换:gen_tcp.send(socket, msg)为通过操作系统选择的 UDP 套接字:gen_udp.send(socket, host, port, msg)发送msg到远程host:port

使用我的 fork 运行应用程序时遇到的错误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}.

4

1 回答 1

1

UDP 是无连接协议,这意味着您无需连接到远程套接字即可发送数据。您需要做的就是:

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

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

不需要连接,这就是为什么没有文档的原因:gen_udp.connect,因为它根本不应该使用。

于 2019-10-21T20:24:30.460 回答