Erlang OTP编程初体验——gen_server和行为模式
(2014-04-11 16:54:01)
标签:
erlangotpgen_server行为模式it |
分类: 编程语言 |
行为模式其实非常类似于面向对象语言中的接口,至少笔者是这么理解的。OTP行为模式将一些反复出现的模式分成了两个部分,通用部分和具体应用相关的实现部分,这一过程其实就类似于面向对象编程中的抽象出接口的过程。本文给出一个OTP中最常见的行为模式的示例:通用服务器,即gen_server。
编写gen_server回调模块大致包括3相步骤:
(1) 确定回调模块的名称;
(2) 写接口函数(由客户端调用的);
(3) 在回调模块中实现gen_server的6个回调函数(由gen_server容器来调用的)。
下面给出一个《Erlang
tr_server.erl |
%%%-------------------------------------------------------------------
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%-------------------------------------------------------------------
-module(tr_server).
-behaviour(gen_server).
%%
-export([
%%
-export([init/1,
-define(SERVER,
-define(DEFAULT_PORT,
-record(state,
%%%===================================================================
%%%
%%%===================================================================
%%--------------------------------------------------------------------
%%
%%
%%
%%
%%
%%
%%--------------------------------------------------------------------
start_link(Port)
%%
%%
start_link()
%%--------------------------------------------------------------------
%%
%%
%%
%%
%%
%%--------------------------------------------------------------------
get_count()
%%--------------------------------------------------------------------
%%
%%
%%
%%--------------------------------------------------------------------
stop()
%%%===================================================================
%%%
%%%===================================================================
init([Port])
handle_call(get_count,
handle_cast(stop,
handle_info({tcp,
handle_info(timeout,
terminate(_Reason,
code_change(_OldVsn,
%%%===================================================================
%%%
%%%===================================================================
do_rpc(Socket,
split_out_mfa(RawData)
args_to_terms(RawArgs)
笔者在Linux环境下运行这个程序:
1>
{ok,tr_server}
2>
{ok,<0.39.0>}
3>
这里需要再启动一个Shell,输入:
root@controller:~#
Trying
Connected
Escape
然后再回到Erlang控制台,输入:
3>
{ok,0}
4>
ok
为什么要先用telnet连接一下1055端口呢?分析一下init([Port])这个函数的行为。init([Port])函数首先用标准库中的gen_tcp模块在指定的端口上建立一个TCP监听套接字:
{ok,
然后init([Port])函数返回一个三元组,包含原子ok,初始进程状态,以及数字0:
这个0表示超时值。将超时设置为零就是让gen_server容器在init/1结束后,立即触发一个超时,从而迫使进程在完成初始化之后第一时间处理超时消息(由handle_info/2完成)。在这里使用0的用意是唤醒服务器并执行一些指定的操作:等待创建的监听套接字上的连接。在没有接收到连接时,gen_server会一直阻塞在这里,因此如果此时发送tr_server:get_count()请求,将会得到一个timeout反馈:
**
tr_server所实现的RPC服务,理论上可以调用服务器端任意模块中导出的任意函数。比如,可以在telnet中输入:
init:stop().
返回:
ok
Connection
这是因为init:stop()关闭了运行着RPC服务器的整个Erlang节点。
最后,我们看看gen_server中的几个常用的回调函数是怎么定义的。打开gen_server源码(笔者的Windows系统上,这个文件位于C:\Program
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
%%%
参考资料:《Erlang