`
fsword
  • 浏览: 165244 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Erlang新手进阶笔记(3) - 通用的server

阅读更多
分析一下之前的代码,可以注意到,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


分享到:
评论
9 楼 phoenixup 2010-05-26  
hittyo 写道
fsword 写道
mryufeng 写道

behaviour就是用来作这个的。


没想到把你惊动了,呵呵。

我这个系列是给刚会语法的人看的,主要目的是通过简单可以直接执行的代码学习erlang的一些特有的东西,下一篇就要说behaviour了。



给新手看

这还得等我的erlang中文手册翻译完才行,快了...


先弄出几章来瞧瞧~~
8 楼 hittyo 2010-05-18  
tsxm 写道
说实话,我真的很不喜欢Erlang


理由呢?
7 楼 fsword 2010-05-15  
tsxm 写道
说实话,我真的很不喜欢Erlang


非常感谢你的回复,说实话,最近很忙,没有时间写东西,不过我真的觉得erlang是一个很不错而且常常被误解的语言(上一次有这种感觉的是javascript),看到有人不喜欢,就会有些动力说说我的感受,欢迎继续关注
6 楼 tsxm 2010-05-15  
说实话,我真的很不喜欢Erlang
5 楼 hittyo 2010-05-10  
网上那个不是手册,也不是我翻译的,那个只是某教程的部门章节
4 楼 fsword 2010-05-09  
hittyo 写道

给新手看

这还得等我的erlang中文手册翻译完才行,快了...


我在网上找到了这个中文的pdf,是不是就是你正在翻译的部分?挺好的,呵呵

我在大学的时候就和同学讨论过,最好有一个有一定经验的人,沿着自己的学习路径讲一门知识,那么,和他思维方式类似的人就会比较容易学习,我这个系列就想做这个事。

不过也许应该修改一下文章的名字,就算是我自己的学习笔记吧
3 楼 hittyo 2010-05-08  
fsword 写道
mryufeng 写道

behaviour就是用来作这个的。


没想到把你惊动了,呵呵。

我这个系列是给刚会语法的人看的,主要目的是通过简单可以直接执行的代码学习erlang的一些特有的东西,下一篇就要说behaviour了。



给新手看

这还得等我的erlang中文手册翻译完才行,快了...

2 楼 fsword 2010-05-07  
mryufeng 写道

behaviour就是用来作这个的。


没想到把你惊动了,呵呵。

我这个系列是给刚会语法的人看的,主要目的是通过简单可以直接执行的代码学习erlang的一些特有的东西,下一篇就要说behaviour了。
1 楼 mryufeng 2010-05-07  
fsword 写道
分析一下之前的代码,可以注意到,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



behaviour就是用来作这个的。

相关推荐

Global site tag (gtag.js) - Google Analytics