[练习]简单的名字服务
使用gen_server做的简单的名字服务
?
步奏很简单 启动gen_server local注册一下服务名方便被引用
?
然后将字典放在State里面 提供查询等服务
?
代码如下:
%% @author cc fairjm%% @doc @todo Add description to naming.-module(naming).-behaviour(gen_server).-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).%% ====================================================================%% API functions%% ====================================================================-export([start/0,stop/0,insert/2,remove/1,lookup/1]).-define(SERVER,?MODULE).%% ====================================================================%% Behavioural functions %% ====================================================================-record(state, {dic}).start() ->gen_server:start_link({local,?SERVER}, ?MODULE, [], []).insert(Key,Value) ->gen_server:cast(?SERVER,{insert,{Key,Value}}).remove(Key) ->gen_server:cast(?SERVER, {remove,Key}).lookup(Key)->gen_server:call(?SERVER, {lookup,Key}).stop() ->gen_server:cast(?SERVER, stop).%% init/1%% ====================================================================%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:init-1">gen_server:init/1</a>-spec init(Args :: term()) -> Result whenResult :: {ok, State}| {ok, State, Timeout}| {ok, State, hibernate}| {stop, Reason :: term()}| ignore,State :: term(),Timeout :: non_neg_integer() | infinity.%% ====================================================================init([]) -> {ok, #state{dic=dict:new()}}.%% handle_call/3%% ====================================================================%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:handle_call-3">gen_server:handle_call/3</a>-spec handle_call(Request :: term(), From :: {pid(), Tag :: term()}, State :: term()) -> Result whenResult :: {reply, Reply, NewState}| {reply, Reply, NewState, Timeout}| {reply, Reply, NewState, hibernate}| {noreply, NewState}| {noreply, NewState, Timeout}| {noreply, NewState, hibernate}| {stop, Reason, Reply, NewState}| {stop, Reason, NewState},Reply :: term(),NewState :: term(),Timeout :: non_neg_integer() | infinity,Reason :: term().%% ====================================================================handle_call({lookup,Key}, _From, State) ->#state{dic=Dic}=State,case dict:find(Key, Dic) of {ok,Value}->{reply, {ok,Value}, State}; _->{reply,{not_found},State}end.%% handle_cast/2%% ====================================================================%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:handle_cast-2">gen_server:handle_cast/2</a>-spec handle_cast(Request :: term(), State :: term()) -> Result whenResult :: {noreply, NewState}| {noreply, NewState, Timeout}| {noreply, NewState, hibernate}| {stop, Reason :: term(), NewState},NewState :: term(),Timeout :: non_neg_integer() | infinity.%% ====================================================================handle_cast({insert,{Key,Value}}, State) ->#state{dic=Dic}=State, {noreply, State#state{dic=dict:append(Key, Value,Dic )}};handle_cast({remove,Key}, State) ->#state{dic=Dic}=State, {noreply, State#state{dic=dict:erase(Key, Dic)}};handle_cast(stop, State) ->{stop,{normal},State}.%% handle_info/2%% ====================================================================%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:handle_info-2">gen_server:handle_info/2</a>-spec handle_info(Info :: timeout | term(), State :: term()) -> Result whenResult :: {noreply, NewState}| {noreply, NewState, Timeout}| {noreply, NewState, hibernate}| {stop, Reason :: term(), NewState},NewState :: term(),Timeout :: non_neg_integer() | infinity.%% ====================================================================handle_info(_Info, State) -> {noreply, State}.%% terminate/2%% ====================================================================%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:terminate-2">gen_server:terminate/2</a>-spec terminate(Reason, State :: term()) -> Any :: term() whenReason :: normal| shutdown| {shutdown, term()}| term().%% ====================================================================terminate(_Reason, _State) -> ok.%% code_change/3%% ====================================================================%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:code_change-3">gen_server:code_change/3</a>-spec code_change(OldVsn, State :: term(), Extra :: term()) -> Result whenResult :: {ok, NewState :: term()} | {error, Reason :: term()},OldVsn :: Vsn | {down, Vsn},Vsn :: term().%% ====================================================================code_change(_OldVsn, State, _Extra) -> {ok, State}.%% ====================================================================%% Internal functions%% ====================================================================
?其实只要写一点点代码就够了 erlang的代码简洁明了
?
调用如下:
(cc@dell-PC)8> c("naming").{ok,naming}(cc@dell-PC)9> naming:stop().ok(cc@dell-PC)10> naming:lookup(cc).** exception exit: {noproc,{gen_server,call,[naming,{lookup,cc}]}} in function gen_server:call/2 (gen_server.erl, line 180)(cc@dell-PC)11> c("naming").{ok,naming}(cc@dell-PC)12> naming:start().{ok,<0.68.0>}(cc@dell-PC)13> naming:insert(cc,"hello").ok(cc@dell-PC)14> naming:lookup(cc).{ok,["hello"]}(cc@dell-PC)15> naming:remove(cc).ok(cc@dell-PC)16> naming:lookup(cc).{not_found}(cc@dell-PC)17> naming:stop().** exception exit: {normal}(cc@dell-PC)18>=ERROR REPORT==== 12-Aug-2013::02:27:17 ===** Generic server naming terminating** Last message in was {'$gen_cast',stop}** When Server state == {state,{dict,0,16,16,8,80,48, {[],[],[],[],[],[],[],[],[],[],[],[],[], [],[],[]}, {{[],[],[],[],[],[],[],[],[],[],[],[],[], [],[],[]}}}}** Reason for termination ==** {normal}(cc@dell-PC)18> naming:lookup(cc).** exception exit: {noproc,{gen_server,call,[naming,{lookup,cc}]}} in function gen_server:call/2 (gen_server.erl, line 180)
?远程也可以调用 用rpc就可:
(cc02@dell-PC)1> net_adm:ping('cc@dell-PC').pong(cc02@dell-PC)2> rpc:call('cc@dell-PC',naming,lookup,cc).{badrpc,{'EXIT',{badarg,[{erlang,apply, [naming,lookup,cc], []}, {rpc,'-handle_call_call/6-fun-0-',5, [{file,"rpc.erl"},{line,205}]}]}}}(cc02@dell-PC)3> rpc:call('cc@dell-PC',naming,lookup,[cc]).{badrpc,{'EXIT',{noproc,{gen_server,call, [naming,{lookup,cc}]}}}}(cc02@dell-PC)4> rpc:call('cc@dell-PC',naming,lookup,[cc]).{ok,["hello","hello2"]}(cc02@dell-PC)5> rpc:call('cc@dell-PC',naming,lookup,[cc]).{ok,["hello","hello2"]}(cc02@dell-PC)6> rpc:call('cc@dell-PC',naming,lookup,[cc]).{ok,["hello","hello2"]}(cc02@dell-PC)7> rpc:call('cc@dell-PC',naming,lookup,[cc]).{not_found}(cc02@dell-PC)8> rpc:call('cc@dell-PC',naming,lookup,[cc]).{badrpc,{'EXIT',{noproc,{gen_server,call, [naming,{lookup,cc}]}}}}(cc02@dell-PC)9>
?