事件框架 POE 学习
转载本站文章请注明,转载自:扶凯[http://www.php-oa.com] 本文链接: http://www.php-oa.com/2009/09/09/perl-poe-1.html POE结构:???????????????? Kernel ????????????????????? | ???????????????? Session | _______________________________ | ? ? ? ? ? ???????? | ? ? ? ? ? ? ?| ? ? ? ? ? ?| Driver->Filter->Wheel->Components Kernel: ?POE管理会话的内核Kernel,它是POE核心,内部实现了IO读写信号回调等处理,简单应用程序与Kernel交互并不多。 Session:?? 会话抽象,会话中需要创建高层协议抽象,Session是一个处理线程,比如一个服务器程序每一个客户端连接就应该对应于一个Session,同理 Spider程序中对于每一个web服务器的连接也应该对应于一个Session,一个应用程序可以有很多Session。 Driver:???? 底层文件操作的抽象,在编程时不会直接用到,Wheel、Filter、Driver是对底层IO的封装。 Filter:???? 底层、中层协议操作的抽象,通常不会直接用到 Wheel:???? 高层协议操作的抽象,经常要用到 Components:POE提供的一些拿来就能用的组件 POE对象的数据结构:
my ($kernel, $session$heap) = @_[ KERNEL HEAP ]; $currentItem$count[ ARG0..$#_ ; 如上,这是事件调用后,比较建议给通用的信息放到第一行.第二行是其它参数接收方法,这个中?@_[ ARG0..$#_ ],很象普通的子函数调用@_一样. ? POE中几种事件调用的方法
? POE 的一些需要了解的东西?
;
? 实例分析现在我们来拿Flw大大的程序来分析POE的工作原理. 注意,在这个程序基本上可以分为三部分 1) POE::Session->create,创建一个Session。 2) POE::Kernel->run, 启动框架消息分发。 3) sub start … 定义各种状态的回调函数。 use POE; ? create POE::Session( inline_states => { _start => &;session_start&;session_stop&;session_count} ); ? print "启动 POE 内核...n"; POEKernel->run; "POE 内核运行结束。exitsub session_start { "Session 启动。Session ID = "$_[SESSIONID"; [HEAP{count} = 0[KERNELyield("count"} ? sub session_stop "Session 停止。Session ID = "".sub session_count { ( $heap ; $session_id ; ? $heap}++; printf "计数器 = %s; ? if < 5 ) { } use POE; #加载了一些诸如POE::Kernel和POE:Sesson的模块并相应地做了一些初始化,并由POE::Session会根据不同的事件输出默认常 量给事件句柄的某些参数,如:KERNEL,HEAP,ARG0等等。 ? 1.建立session 接着建立至少一个session。程序最少要有事情可以做.不然POE::Kernel会在最后一个session停止以后终止运行。 create POE( inline_states => { _start count } ; 其中的inline_states(HASHREF)表示将事件名映射到处理该事件的代码引用。还有一个 object_states(LISTREF)将事件名映射到处理它们的对象方法,值是对象引用和对象方法引用组成的列表的引用。 两个事件(最上面提到的事件句柄)是由POE::Kernel自身所提供的。它们分别表示该session的启动(_start)和销毁(_stop)。 最后一个事件(count)是用户自定义事件,它被用于程序的逻辑之中。下面我们会来亲自写这几个函数. ? 2.启动POE::Kernel 由此便建立了一个用来探测并分派事件的主循环。我们使用print来打印POE::Kernel运行的开始处和结束点。 ; POE; ; Kernel的run方法只有在所有session返回之后才会停止循环。 ? 3.由上面定义的3个事件句柄: _start句柄 在上面建立session的时候.首先从_start开始。_start的句柄将在sesson初始化完成之后开始运行,session在其自身的上下文 中使用它来实现输入引导。比如初始化heap中的值,或者分配一些必要的资源等等。 在该句柄中我们建立了一个累加器,并且发出了“count”事件以触发相应的事件句柄。 { ; } 在这,我们使用yield方法,将一个事件放入fifo分派队列的末尾处,当队列中在其之前的事件被处理完毕之后,该事件将被触发以运行相应的事件 句柄。 ? _stop句柄。 POE::Kernel将在所有session再无事件可触发之后,并且是在自身被销毁之前调用它。 }
count事件句柄。 该函数用来增加heap中的累加器计数,并打印累加结果。为了加深对yield的印象,我们现在使用yield方法来调用新的事件,这样也能够加深对 POE事件处理原理的理解。 { ; ; ? ++; ; ? } POE输出:只要累加器计数未超过10,session将再yield一个count事件。因为不断地触发了 session_count句柄,使得当前session可以继续得以生存而不会被POE::Kernel清理。 当计数器到10时,便不再调用yield命令,session也将停止。一旦POE::Kernel检测到该session再没有事件句柄可被激发,便在 调用_stop事件句柄之后将其清理销毁。 以下是运行的结果: Session 启动。Session ID 2 启动 POE 内核... 计数器 1 计数器 2 计数器 3 计数器 4 计数器 5 Session 停止。Session ID 2. POE 内核运行结束。 有没有注意到,第一个count时本来是要打印0的,但是直接打印1.为什么,主要是因为下面,yield是需要事件完后才调用. ? POE 其它注意session->get_heap()? 通过 session 来得到 heap. ? 常用POE的组件POE::API::Peek 这是一个可以查看 POE 核心事件的接口 POE::Wheel::Run 制造轮子,常用来做并发的事件 POE::Filter::Line? 行过滤器 POE::Wheel::SocketFactory 非阻塞套接字创建 ????? POE::Component::Server::TCP 一个简单的TCP服务器 POE::Wheel::ListenAccept(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |