[Erlang脚印 0004] gen_server

 

gen_server:start_link(ServerName, Module, Args, Options) -> Result

     ServerName={local, Name}|{global, GlobalName}|{via, Module, ViaName}

     Option = {debug, Dbgs}|{timeout, Time}|{spawn ——opt, Sopts}

     Module: 回调模块的名称

     Args: 传给回调模块中init函数的参数

call(ServerRef, Request) -> Reply    %%handle_call之间的交互, 实现远程调用

abcast(Name, Request) -> abcast

muti_call(Name, Request) -> Result

gen_server 和回调模块中的回调函数对应关系

gen_server module                         Callback module

--------------------------                  -----------------------

gen_server:start_link       --------> Module:init/1

gen_server:call

gen_server:multi_call      ---------> Module:handle_call/3    %% 函数的同步调用

gen_server:cast

gen_server:abcast          ----------> Module:handle_cast/2   %% 函数的异步调用

-                                   ----------> Module:handle_info/2    %% 处理发给服务器的原生消息,handle_call /handle_cast不处理的消息

-                                   ----------> Module:terminate/2       %% 服务器终止,可以对State 的数据进行处理

-                                   ----------> Module:code_change/3    %% 对于代码的升级和替换

 

 以代码说明其使用

 1 -module(tcp_socket2).                                                           
  2 -behaviour(gen_server).                                                         
  3                                                                                 
  4 -export([start/0, stop/0, login/1]).                                                                                                                                               
  5                                                                                 
  6 -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
  7                                                                                 
  8 start() ->                                                                      
  9     io:format("[~p] start()~n", [calendar:now_to_local_time(erlang:now())]),    
 10     gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).                   
 11                                                                                 
 12                                                                                 
 13 stop() ->                                                                       
 14     io:format("[~p] stop() ~n", [calendar:now_to_local_time(erlang:now())]),    
 15     gen_server:call(?MODULE, stop).                                             
 16                                                                                 
 17                                                                                 
 18 login(Who) ->                                                                   
 19     io:format("[~p] login(~p) ~n", [calendar:now_to_local_time(erlang:now()), Who]),
 20     gen_server:call(?MODULE, {login, Who}).                                     
 21                                                                                 
 22 init([]) ->                                                                     
 23     io:format("[~p] init() ~n", [calendar:now_to_local_time(erlang:now())]),    
 24     {ok, ets:new(?MODULE, [])}.                                                 
 25                                                                                 
 26 handle_call({login, Who}, _From, Tab) ->                                        
 27     io:format("[~p] handle_call({login, ~p})", [calendar:now_to_local_time(erlang:now()), Who]),
 28     Reply = case ets:lookup(Tab, Who) of                                        
 29         [] -> ets:insert(Tab, {Who,0}),                                         
 30             {welcome, Who}                                                      
 31     end,                                                                        
 32     {reply, Reply, Tab};                                                        
 33 handle_call(stop, _From, Tab) ->                                                
 34     {stop, normal, stopped, Tab}.                                               
 35 handle_cast(_Msg, State) -> {noreply, State}.                                   
 36 handle_info(_Info, State) -> {noreply, State}.                                  
 37 terminate(_Reason, _State) ->                                                   
 38     ok.                                                                         
 39 code_change(_OldVsn, State, Extra) -> {ok, State}.       

在一个终端显示的信息,可以观察其启动函数的顺序 start -> init   login -> handle_call

1> c(tcp_socket2).

tcp_socket2.erl:39: Warning: variable 'Extra' is unused

{ok,tcp_socket2}

2> tcp_socket2:start().

[{{2014,7,15},{14,34,21}}] start()

[{{2014,7,15},{14,34,21}}] init() 

{ok,<0.40.0>}

3> tcp_socket2:login("nike").

[{{2014,7,15},{14,34,45}}] login("nike") 

[{{2014,7,15},{14,34,45}}] handle_call({login, "nike"}){welcome,"nike"}

4> tcp_socket2:stop().

[{{2014,7,15},{14,45,26}}] stop() 

stopped

5>

posted @ 2014-07-23 09:59  懒惰菜鸟  阅读(334)  评论(0编辑  收藏  举报