使用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 when Result :: {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 when Result :: {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 when Result :: {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 when Result :: {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() when Reason :: 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 when Result :: {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>