`

[代码分析]gen_server例子分析

 
阅读更多

这个例子是erlang/OTP并发实践里的 

例子内容很简单 但是对行为不是很理解的人(比如我)读起来还是有那么一点点困难的

 

源代码:

https://raw.github.com/erlware/Erlang-and-OTP-in-Action-Source/master/chapter_03/tr_server.erl

 

 

这边简化一下

do_rpc()那个函数其实就是运用下erlang:apply/3啦 前一篇的例子里有(\s和\\s在正则中一样??)

 

先讲个大概:

调用gen_server行为用 就可以了:

-behaviour(gen_server).

 接下去你使用gen_server中的函数一些函数时 他会自动调用模块内的一些函数

init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3

 针对代码里的

   gen_server:start/4 ----->init/1

   gen_server:call/2   ----->handle_call/3

   gen_server:cast/2  ----->handle_cast

 其他的通信(代码内主要是tcp链接)则会触发handle_info/2

 

主要流程如下:

 

 执行tr_server:start_link/1或者tr_server:start_link/0后(还可以通过tr_server:start_test/0)

 调用:

gen_server:start_link({local, ?SERVER}, ?MODULE, [Port], []).

 这段代码的意图是 绑定serverName,传入模块名和参数(这边是端口)

 

此后以上代码就会调用该模块内的init/1(这边的参数就是 gen_server:start_link({local, ?SERVER}, ?MODULE, [Port], []).中的Port(在init/1中使用了模式匹配得到了列表中的Port:init([Port])).对应关系如下:

gen_server: 写道
start(ServerName, Module, Args, Options) -> Result
Module:init(Args) -> Result

 

 

 

 

 

init/1:

init([Port]) ->
    {ok, LSock} = gen_tcp:listen(Port, [{active, true}]),
    {ok, #state{port = Port, lsock = LSock}, 0}.

 代码中新建一个tcp的服务 {active,true}代表有数据过来时自动把信息给对应的进程(这边会调用handle_info/2这个函数)

返回信息的格式如下:

写道
Result = {ok,State} | {ok,State,Timeout} | {ok,State,hibernate}
| {stop,Reason} | ignore
State = term()
Timeout = int()>=0 | infinity
Reason = term()

 那个State变量可以随意指定 这个State会传给handle_info/2,handle_call/3,handle_cast/2等(这些函数的返回值中返回的新的State可以用来更新)

返回中还有一个0代表着Timeout Timeout为0会立即触发以下函数:

handle_info(timeout, #state{lsock = LSock} = State) ->
    {ok, _Sock} = gen_tcp:accept(LSock),
    {noreply, State}.

等待TCP的一个连接(堵塞的,但开发者无需担心 这是在其他的进程中运行的)

 

从这里看出 这个应用其实只可以接受一个有效的telnet等连接。

连接建立好之后 所有的收发telnet信息等信息的工作交给了:

handle_info({tcp, Socket, RawData}, State) -> 
do_rpc(Socket, RawData), 
RequestCount = State#state.request_count, 
{noreply, State#state{request_count = RequestCount + 1}};

 负责处理数据并且更新下State

handle_info/2的第一个参数不是timeout就是发过来的信息,因为是处理telnet等的信息 所以用模式匹配就可以得到数据和对应的套接字(这个用来返回信息用)

 

 

其他的具体内容可以参考doc 以上内容也许分析有误 欢迎指正.

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics