-module(server1). -export([start/2, rpc/2]). start(Name, Mod) -> register(Name, spawn(fun() -> loop(Name, Mod, Mod:init()) end)). rpc(Name, Request) -> Name ! {self(), Request}, receive {Name, Response} -> Response end. loop(Name, Mod, State) -> receive {From, Request} -> {Response, State1} = Mod:handle(Request, State), From ! {Name, Response}, loop(Name, Mod, State1) end.
这段代码是erlang的标准服务器程序,下面写一个回调函数来运行测试。
name_server.erl
-module(name_server). -export([init/0, add/2, whereis/1, handle/2]). -import(server1, [rpc/2]). %% client routines add(Name, Place) -> rpc(name_server, {add, Name, Place}). whereis(Name) -> rpc(name_server, {whereis, Name}). %% callback routines init() -> dict:new(). handle({add, Name, Place}, Dict) -> {ok, dict:store(Name, Place, Dict)}; handle({whereis, Name}, Dict) -> {dict:find(Name, Dict), Dict}.
首先看后面的代码1.他负责回调服务器程序,处理其他进程发货来的请求2.相当于定义接口。
如下运行程序:
erlc *.erl
Eshell V5.6.5 (abort with ^G) 1> server1:start(name_server, name_server). true 2> nameserver:add("lengzijian","go to school"). ** exception error: undefined function nameserver:add/2 3> name_server:add("lengzijian","go to school"). ok 4> name_server:whereis("lengzijian"). {ok,"go to school"} 5>
如果读者细心可以发现,这段代码里面并没有spawn这样的创建进程的命令,不错,这个服务器程序完全是顺序性代码,也许有人质疑这样做的意义,不要急这才刚刚开始
2.server2:支持事务的服务器程序
接下来要向大家展示的是,当服务器宕机,客户端回或得到异常,然后做相应的处理。
server2.erl
-module(server2). -export([start/2, rpc/2]). start(Name, Mod) -> register(Name, spawn(fun() -> loop(Name,Mod,Mod:init()) end)). rpc(Name, Request) -> Name ! {self(), Request}, receive {Name, crash} -> exit(rpc); {Name, ok, Response} -> Response end. loop(Name, Mod, OldState) -> receive {From, Request} -> try Mod:handle(Request, OldState) of {Response, NewState} -> From ! {Name, ok, Response}, loop(Name, Mod, NewState) catch _:Why -> log_the_error(Name, Request, Why), %% send a message to cause the client to crash From ! {Name, crash}, %% loop with the *original* state loop(Name, Mod, OldState) end end. log_the_error(Name, Request, Why) -> io:format("Server ~p request ~p ~n" "caused exception ~p~n", [Name, Request, Why]).