Erlang OTP UDP服务器

时间:2015-02-06 11:11:32

标签: erlang udp

这是一个简单的UDP服务器:

-module(kvstore_udpserver).
-author("mylesmcdonnell").

%% API
-export([start/0]).

start() ->
  spawn(fun() -> server(2346) end).

server(Port) ->
  {ok, Socket} = gen_udp:open(Port, [binary]),
  loop(Socket).

loop(Socket) ->
  receive
    {udp, Socket, Host, Port, Bin} ->
      case binary_to_term(Bin) of
        {store, Value} ->
          io:format("kvstore_udpserver:{store, Value}~n"),
          gen_udp:send(Socket,Host,Port,term_to_binary(kvstore:store(Value)));
        {retrieve, Key} ->
          io:format("kvstore_udpserver:{retrieve, Value}~n"),
          gen_udp:send(Socket,Host,Port,term_to_binary(kvstore:retrieve(Key)))
      end,
      loop(Socket)
  end.

我如何重组这个

a)它,或者至少它的相关部分是gen_server,以便我可以添加到监督树

b)通过在单独的进程中处理每条消息来增加并发性。

我已经为我的TCP服务器重新实现了来自Learn You Some Erlang的sockserv示例,但是我很难确定UDP的类似模型。

1 个答案:

答案 0 :(得分:3)

对于a):

  1. 您需要对gen_server行为进行delcare并实现所有回调函数(这很明显,但它值得明确调用)。如果安装了rebar,则可以使用命令rebar create template=simplesrv srvid=your_server_name添加样板函数。

  2. 您可能希望将服务器启动业务逻辑(gen_udp:open/2调用)移至服务器的init/1功能。 (gen_server行为需要初始化。您也可以在那里启动loop/1功能。

  3. 您可能希望确保模块的terminate/2功能关闭了udp服务器。

  4. 将处理来自解析消息的请求的业务逻辑移动到您的loop/1函数中,移动到模块中的handle_call/3handle_cast/2(见下文)。

  5. 对于b): 您有几个选项,但基本上,每当您收到消息时,您都可以使用gen_server:cast/2(如果您不关心响应)或gen_server:call/2,3(如果您这样做)。演员表或电话将由您模块中的handle_cast/2handle_call/3函数处理。

    强制转换本质上是非阻塞的,this question的答案具有良好的设计模式,可以在gen_servers中异步处理调用操作。你可以从中受益。