2015-02-06 53 views
3

下面是一個簡單的UDP服務器:二郎OTP 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. 

我如何重組這使

一)它,或者至少它的相關部分,是一個gen_server使我可以添加到監督樹

b)用一個單獨的進程處理每封郵件增加併發。

我已經重新實現了從瞭解你對我的TCP服務器的一些二郎山sockserv例子,但我掙扎,以確定UDP一個類似的模式。

回答

3

對於):

  1. 您需要delcare的gen_server行爲和執行所有的回調函數(這是顯而易見的,但它是值得呼喚明確)。如果安裝了rebar,則可以使用命令rebar create template=simplesrv srvid=your_server_name添加樣板函數。

  2. 您可能希望將啓動業務邏輯的服務器(gen_udp:open/2調用)移動到您的服務器的init/1函數。 (初始化由gen_server行爲必需的。你也可以開始你的loop/1功能存在。

  3. 你可能會想,以確保UDP服務器通過模塊的terminate/2功能關閉。

  4. 移動業務邏輯處理,從解析郵件到您loop/1功能爲handle_call/3handle_cast/2您的模塊中進來的請求(見下文)

對於b): 你有幾種選擇,但基本上,當你收到一條消息,你可以使用gen_server:cast/2(如果你不關心響應)或gen_server:call/2,3如果你這樣做。演員或電話將由模塊中的handle_cast/2handle_call/3功能處理。

強制轉換本質上是非阻塞的並且this question的答案在gen_servers中具有異步處理呼叫操作的良好設計模式。你可以從這個嬰兒牀。