说完了gen_server,今天我们来看看gen_event。
通常我们会有这么一种需求场景:采集客户端发送的事件,并做相应的处理,如下图:
[img]http://dl.iteye.com/upload/attachment/0078/6320/5a1a22d9-4ff5-34fd-83f7-039002e424f0.png[/img]
EventServer负责接收客户端发送的事件消息,当它接受到一个事件消息后,[b]它回调所有的EventHandler处理这条信息(不同的EventHandler对同一条消息会才采取不同的响应)[/b],所以EventServer实际上是充当着[b]代理[/b]的角色,实际的事件消息是由EventHandler处理(我们称EventHandler是EventServer的callback模块)
现在我们按照上图,实现一下EventServer:
[img]http://dl.iteye.com/upload/attachment/0078/6322/ce7bb5a3-0486-3680-a294-4fb2cf11a98f.png[/img]
我们可以通过add_handler方法[b]动态[/b]的往EventServer中添加EventHandler(EventServer内部维护着一个HandlerList);
notify方法供客户端向EventServer发送事件消息,当EventServer收到一条事件消息时({event, Event}),它遍历HandlerList,把这条消息交给每个EventHandler处理;
接着,我们实现两个EventHandler(EventServer的callback模块),其中terminal_logger会把接受到的事件消息打印到控制台,file_logger会把事件消息记录到文件。
[img]http://dl.iteye.com/upload/attachment/0078/6324/2e0e9c52-4406-37c8-8969-283d4b31b612.png[/img]
[img]http://dl.iteye.com/upload/attachment/0078/6326/e8fe747d-c812-38a7-b9fe-c43536ebf5e3.png[/img]
现在我们运行下程序,看下效果
[img]http://dl.iteye.com/upload/attachment/0078/6328/6ca9ee13-0b79-31b7-9ca7-bbf670a85aa6.png[/img]
[img]http://dl.iteye.com/upload/attachment/0078/6330/8474dd13-3b17-313b-a72c-6b9fa4b59ea3.png[/img]
event_server:start()启动了一个EventServer(初始状态下没有任何的EventHandler),接着我们动态的添加了两个EventHandler(3,4两行命令),最后我们使用event_server:notify方法向EventServer发送了两条事件消息,当EventServer收到这些消息后,回调所有的EventHandler进行处理,其中terminal_logger将收到的事件打印到了屏幕(如红色箭头部分),file_logger将事件保存到了event.log中
[b]至此我们就实现了一个EventServer,那么gen_event是什么呢?它实际上就是我们刚才EventServer的一种实现并且提供更多更稳健的功能(譬如,不仅支持EventHandler的动态添加,也支持动态卸载)[/b],下面我们就用gen_event重新实现以下刚才的需求:
[img]http://dl.iteye.com/upload/attachment/0078/6332/8f7c76b6-3c65-3b6a-b5e0-1cab4483ec43.png[/img]
[img]http://dl.iteye.com/upload/attachment/0078/6334/bb5757be-6a46-35e5-91dd-c32d08d8741a.png[/img]
执行下程序:
[img]http://dl.iteye.com/upload/attachment/0078/6336/4519b20c-9e53-30f1-a7b7-1b63fcfce7e8.png[/img]
[img]http://dl.iteye.com/upload/attachment/0078/6338/a29d4afa-55a8-39fc-98e5-ab44b25b1237.png[/img]
第四行,我们向event_server发送一条事件消息,这时候屏幕上,文件里都记录了hello world这条事件消息,当我们调用gen_event:delete_handler方法去掉new_terminal_logger后,再次发送事件消息,这时候只有文件中会记录,屏幕上不再显示
关于gen_event我们就说道这里,更多api细节,请看:[url]http://www.erlang.org/doc/man/gen_event.html[/url]
通常我们会有这么一种需求场景:采集客户端发送的事件,并做相应的处理,如下图:
[img]http://dl.iteye.com/upload/attachment/0078/6320/5a1a22d9-4ff5-34fd-83f7-039002e424f0.png[/img]
EventServer负责接收客户端发送的事件消息,当它接受到一个事件消息后,[b]它回调所有的EventHandler处理这条信息(不同的EventHandler对同一条消息会才采取不同的响应)[/b],所以EventServer实际上是充当着[b]代理[/b]的角色,实际的事件消息是由EventHandler处理(我们称EventHandler是EventServer的callback模块)
现在我们按照上图,实现一下EventServer:
[img]http://dl.iteye.com/upload/attachment/0078/6322/ce7bb5a3-0486-3680-a294-4fb2cf11a98f.png[/img]
我们可以通过add_handler方法[b]动态[/b]的往EventServer中添加EventHandler(EventServer内部维护着一个HandlerList);
notify方法供客户端向EventServer发送事件消息,当EventServer收到一条事件消息时({event, Event}),它遍历HandlerList,把这条消息交给每个EventHandler处理;
接着,我们实现两个EventHandler(EventServer的callback模块),其中terminal_logger会把接受到的事件消息打印到控制台,file_logger会把事件消息记录到文件。
[img]http://dl.iteye.com/upload/attachment/0078/6324/2e0e9c52-4406-37c8-8969-283d4b31b612.png[/img]
[img]http://dl.iteye.com/upload/attachment/0078/6326/e8fe747d-c812-38a7-b9fe-c43536ebf5e3.png[/img]
现在我们运行下程序,看下效果
[img]http://dl.iteye.com/upload/attachment/0078/6328/6ca9ee13-0b79-31b7-9ca7-bbf670a85aa6.png[/img]
[img]http://dl.iteye.com/upload/attachment/0078/6330/8474dd13-3b17-313b-a72c-6b9fa4b59ea3.png[/img]
event_server:start()启动了一个EventServer(初始状态下没有任何的EventHandler),接着我们动态的添加了两个EventHandler(3,4两行命令),最后我们使用event_server:notify方法向EventServer发送了两条事件消息,当EventServer收到这些消息后,回调所有的EventHandler进行处理,其中terminal_logger将收到的事件打印到了屏幕(如红色箭头部分),file_logger将事件保存到了event.log中
[b]至此我们就实现了一个EventServer,那么gen_event是什么呢?它实际上就是我们刚才EventServer的一种实现并且提供更多更稳健的功能(譬如,不仅支持EventHandler的动态添加,也支持动态卸载)[/b],下面我们就用gen_event重新实现以下刚才的需求:
[img]http://dl.iteye.com/upload/attachment/0078/6332/8f7c76b6-3c65-3b6a-b5e0-1cab4483ec43.png[/img]
[img]http://dl.iteye.com/upload/attachment/0078/6334/bb5757be-6a46-35e5-91dd-c32d08d8741a.png[/img]
执行下程序:
[img]http://dl.iteye.com/upload/attachment/0078/6336/4519b20c-9e53-30f1-a7b7-1b63fcfce7e8.png[/img]
[img]http://dl.iteye.com/upload/attachment/0078/6338/a29d4afa-55a8-39fc-98e5-ab44b25b1237.png[/img]
第四行,我们向event_server发送一条事件消息,这时候屏幕上,文件里都记录了hello world这条事件消息,当我们调用gen_event:delete_handler方法去掉new_terminal_logger后,再次发送事件消息,这时候只有文件中会记录,屏幕上不再显示
关于gen_event我们就说道这里,更多api细节,请看:[url]http://www.erlang.org/doc/man/gen_event.html[/url]