gen_event行为模式规定了怎么处理日志事件
该行为模式和gen_server不同 一个gen_server的实现只能绑定一个回调模块
而gen_event则可以回调多个模块 这个和在java中注册成为一个事件的监听者道理是一样的
一个日志事件(event)会分发给多个注册了的处理者(handler,gen_event行为模式的实现模块)
gen_event由start_link/0或/1进行初始化
一般使用start_link/1(可以使用start 用start_linik是为了和监督者连接起来)
Types:
EventMgrName = {local,Name} | {global,GlobalName} | {via,Module,ViaName}
Name = atom()
GlobalName = ViaName = term()
Result = {ok,Pid} | {error,{already_started,Pid}}
Pid = pid()
使用的时候用诸如:
gen_event:start_link({local, ?SERVER}).
的形式,注册一个名字叫?SERVER的本地事件管理器(以后的notify call等函数都要通过这个?SERVER来使用 (当然也可以使用返回的pid)
要增加一个handler用:
Types:
EventMgr = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Handler = Module | {Module,Id}
Module = atom()
Id = term()
Args = term()
Result = ok | {'EXIT',Reason} | term()
Reason = term()
这个就是为?SERVER(或者表示事件管理器的pid)命令的事件管理器增加一个 handler
handler就是实现了gen_event行为模式的模块的模块名
那么对应的反操作删除就是 参数一致。
Types:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Handler = Module | {Module,Id}
Module = atom()
Id = term()
Args = term()
Result = term() | {error,module_not_found} | {'EXIT',Reason}
Reason = term()
接下去是函数的调用和对应模块(实现了gen_event行为模式的模块)内的回调的对应
gen_event:notify/2 gen_event:sync_notify/2----> module:handle_event/2
gen_event:call/3,4 ---->module:handle_call/2
module:handle_info/2用来接收没有定义的event(没有一个和module:handle_event匹配的)或者系统消息
一般使用gen_event:notify/2就足够了,其他的在doc里有详细解释
以下是一个例子:
这个例子来自erlang/OTP并发编程实战 是一个完整的小程序 我这边把日志模块单独抽取了出来
完整的程序代码见:
首先是产生事件源的代码:
-module(sc_event). -export([start_link/0, add_handler/2, delete_handler/2, lookup/1, create/2, replace/2, delete/1]). -define(SERVER, ?MODULE). start_link() -> gen_event:start_link({local, ?SERVER}). add_handler(Handler, Args) -> gen_event:add_handler(?SERVER, Handler, Args). delete_handler(Handler, Args) -> gen_event:delete_handler(?SERVER, Handler, Args). lookup(Key) -> gen_event:notify(?SERVER, {lookup, Key}). create(Key, Value) -> gen_event:notify(?SERVER, {create, {Key, Value}}). replace(Key, Value) -> gen_event:notify(?SERVER, {replace, {Key, Value}}). delete(Key) -> gen_event:notify(?SERVER, {delete, Key}).
这段代码不难理解 模块名是sc_event 里面封装了gen_event的调用
gen_event初始化时注册了 和模块同名的本地事件管理器 然后接下去的notify方法调用的第一个参数就是这个管理器的名字
通过add_handler和delete_handler对处理模块进行移入和移出操作
接下去的代码是自定义的日志处理(handler) 实现了gen_event行为模式:
-module(sc_event_logger). -behaviour(gen_event). -export([add_handler/0, delete_handler/0]). -export([init/1, handle_event/2, handle_call/2, handle_info/2, code_change/3, terminate/2]). -record(state, {}). add_handler() -> sc_event:add_handler(?MODULE, []). delete_handler() -> sc_event:delete_handler(?MODULE, []). init([]) -> {ok, #state{}}. handle_event({create, {Key, Value}}, State) -> error_logger:info_msg("sc_event_logger:create(~w, ~w)~n", [Key, Value]), {ok, State}; handle_event({lookup, Key}, State) -> error_logger:info_msg("sc_event_logger:lookup(~w)~n", [Key]), {ok, State}; handle_event({delete, Key}, State) -> error_logger:info_msg("sc_event_logger:delete(~w)~n", [Key]), {ok, State}; handle_event({replace, {Key, Value}}, State) -> error_logger:info_msg("sc_event_logger:replace(~w, ~w)~n", [Key, Value]), {ok, State}. handle_call(_Request, State) -> Reply = ok, {ok, Reply, State}. handle_info(_Info, State) -> {ok, State}. terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}.
这边也比较好理解 各个handle_event用来处理事件源中发出的不同事件
单独调用如下:
1> c(sc_event). {ok,sc_event} 2> c(sc_event_logger). {ok,sc_event_logger} 3> sc_event:start_link(). {ok,<0.45.0>} 4> sc_event_logger:add_handler(). ok 5> sc_event:lookup("test"). ok 6> =INFO REPORT==== 14-Jul-2013::11:04:38 === sc_event_logger:lookup([116,101,115,116])
相关推荐
erlang-gen_tcp手册,详细完整,网络tcp开发好东东
Erlang opt_win64 20.2 windows exe 安装包 Erlang 20.2 is the upcoming version of Erlang For Windows x64 installer 截至2018.01.25 groovy最新最稳定版本
Erlang otp_src_20.3.tar.gz linux centos otp-OTP-20.0.tar.gz 可兼容rabbitmq3.7.0
esl-erlang_23.0和rabbitmq-3.8.4windows版本 直接下载安装就行,可以直接下载就可安装,非常的方便 ,欢迎大家下载 注意事项: 1. Erlang版本和RabbitMQ版本要配套 (Erlang23.0, RabbitMQ3.8.4) 2. amd芯片请乖乖...
个人学习Erlang的时候自己写的一个基于gen_tcp的聊天室,功能有注册,登陆,获得登陆时间,聊天次数,上次登陆时间等等,资源里有完整代码,注释也很详细.
通用 TCP 服务器 通用 TCP 服务器( gen_tcp_server ) 是一种 Erlang 行为,提供快速简便的方法将 TCP 服务器功能添加到您的应用程序。 它被实现为管理 TCP 连接的主管,因为它是孩子。如何使用它? 运行make来构建。...
erlang tcp_servererlang tcp_servererlang tcp_server
erlang_otp_win64_25.0
实现了Erlang B/C功能,支持大容量计算
是erlang_otp_20.3 的win64安装包,内为exe文件,一路next即可安装完成 是适用于多线程、分布式开发的语言,也是如rabbitmq等重要工具的必须品 使用前需要配置环境变量:1.变量名为ERLANG_HOME,变量值为安装Erlang...
erlang_23.0.2-1版本 centos7 64bit esl-erlang_23.0.2-1_centos_7_amd64.rpm
这个erlang23.0版本,根据rabbitMQ官网的介绍,可以和下面这几个版本的rabbitMQ配合使用: 3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 其他版本的rabbit,请移步其他资源下载
Erlang otp_win64_22.0.exe
erlang21.0_win64,
关于在 Erlang 风格的 gen_server 上进行 Ocaml/Async 尝试。
Erlang otp_win64_21.2.exe是目前Erlang otp win64位的最新版本。
Erlang otp_win64_20.1.exe是当前最新版本的,更新时间2017-10-26
Erlang23_3,windows32为64位,linux版本
这是通信专业常用的无线通信容量查表,爱尔兰b表,希望能给有需要的同学用用
erlang_otp_20.3_man开发手册,erlang_otp_20.3_man开发手册,erlang_otp_20.3_man开发手册