原创作者: 自由天堂   阅读:1993次   评论:4条   更新时间:2011-06-01    
分析一下之前的代码,可以注意到,server的功能其实是非常类似的,我们可以把公共的部分抽取出来,把不同的部分单独实现,做到一定程度上的复用,erlang支持动态的使用变量,例如:

Mod = my_server.
Mod:start().


这样的代码会启动my_server,借助这个功能,我们可以把模块名作为参数传入,还可以使用模块名作为进程的注册名,于是,代码就便成了这样

% my_server5.erl %
-module(my_server5).
-export([start/2,stop/1]).
-export([init/2]).
-export([request/2]).

% 启动一个模块,注册服务的名称为模块名称 %
start(Mod,Env) -> spawn(my_server5,init,[Mod,Env]).

stop(Mod) -> Mod ! stop .

%请求响应式接口,具体的实现实际上依靠Mod模块的 handle_request 方法%
request(Mod, Request) ->
    Mod ! { request, self(), Request },
    ok.

% 初始化服务,注册名称,启动init方法,初始化服务时接受一个参数 %
init(Mod, Env) -> 
        register(Mod,self()),
        State = Mod:init(Env),
        loop(Mod,State).

% 实际执行体 %
loop(Mod, State) ->
    receive
        { request,From,Request } ->
            {Res,State2} = Mod:handle_request(Request,State),
            From ! {Mod, Res},
            loop(Mod,State2);
        stop ->
            io:format("process stopped.last state is ~p~n",[State])
    end.


使用这段代码,我们只要完成一个回调模块就可以了,例如:

% my_handle1.erl %
-module(my_handle1).
-export([init/1,handle_request/2]).

init(State) -> State.

handle_request(Request,State) ->
    io:format("request to callback1: ~p~n",[Request]),
    {"ok",State}.


运行一下——

Eshell V5.7.2  (abort with ^G)
1> c(my_server5),c(my_client),c(my_handle1).
{ok,my_handle1}
2> C = my_client:start(),my_server5:start(my_handle1,"init").
<0.49.0>
3> my_server5:request(my_handle1, "hello").
request to callback1: "hello"
ok
4> my_server5:stop(my_handle1).
process stopped.last state is "init"
stop


评论 共 4 条 请登录后发表评论
4 楼 fsword 2011-05-22 16:40
在本文中,self表示的是实际执行中创建的那个进程,也就是
start(Mod,Env) -> spawn(my_server5,init,[Mod,Env]). 
这一句创建的进程。

这个进程被erlang vm创建后,我们需要给它注册一个名字供使用,因此 init 方法才需要传入一个参数,当然,通常的做法就是把mod名称传过去,于是这个参数命名为Mod
3 楼 松秋明 2011-05-21 23:44
最后一句,在erlang中所有的self()我见过的都是表示进程的……
2 楼 松秋明 2011-05-21 23:38
self()实际表示如下
% 实际执行体 % 
    loop(Mod, State) -> 
        receive 
            { request,From,Request } -> 
                {Res,State2} = Mod:handle_request(Request,State), 
                From ! {Mod, Res}, 
                loop(Mod,State2); 
            stop -> 
                io:format("process stopped.last state is ~p~n",[State]) 
        end. 

1 楼 松秋明 2011-05-21 23:32
% 初始化服务,注册名称,启动init方法,初始化服务时接受一个参数 % 
init(Mod, Env) ->  
        register(Mod,self()), 
这里面的self().表示的应该是“handle1”,但是怎么觉得很怪?

发表评论

您还没有登录,请您登录后再发表评论

文章信息

Global site tag (gtag.js) - Google Analytics