首页 > 代码库 > [Erlang之旅 0004] gen_server

[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>