<div><font face="courier new,monospace" size="1"></font>&nbsp;</div>
<div><font face="Courier New" size="2">alarm_collecters -&gt; alarm_forwarder -&gt; alarm_monitors</font></div>
<div><font face="Courier New" size="1">ac_101_001...</font></div>
<div><font face="Courier New" size="1">ac_101_002...</font></div>
<div><font face="Courier New" size="1"></font>&nbsp;</div>
<div><font face="Courier New" size="2">描述:一个告警监控程序的告警转发部分,有一组告警采集程序采集101系统的告警</font></div>
<div><font face="Courier New" size="2"></font>&nbsp;</div>
<div><font face="Courier New" size="2">然后写到log/101的目录下,alarm_forwarder在10001端口监听,并定期扫描log目录,</font></div>
<div><font face="Courier New" size="2"></font>&nbsp;</div>
<div><font face="Courier New" size="2">将日志内容放到队列中,有客户端连接时将队列的内容发送给客户端。</font></div>
<div><font face="courier new,monospace" size="1"></font>&nbsp;</div>
<div><font face="Courier New" size="2"><strong>file1:conf/ports_mapping.conf</strong></font></div>
<div><font face="Courier New" size="1">
<p>#ALarm Ports Mapping Config</p>
<p>101 NMS-selfMonitor 10001</p></font></div>
<div><font face="Courier New" size="2"><strong>file2:alarm_forwarder.pl</strong></font></div>
<div><font face="Courier New" size="1"></font>&nbsp;</div>
<div><font face="courier new,monospace" size="1">#!C:\Perl\bin\perl.exe<br>#Forward alarms of virual NEs to NFM or self-Monitor client<br>#By </font><a href="mailto:shanleiguang@he.chinamobile.com"><font face="courier new,monospace" size="1">
shanleiguang@he.chinamobile.com</font></a><font face="courier new,monospace" size="1">, 2006/08<br>#<br># Events<br>#--------<br>#<br>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +------&lt;------+<br>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +---&lt;----+
<br># load_config-&gt;create_queues-+-&gt;alarm_scanning-&gt;update_queues&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (queues)&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |-&gt;client_send-&gt;+<br>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |-&gt;accept_success-+-&gt;client_error
<br>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +-&gt;start_listen-+ (client_wheels)<br>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (listen_wheels)|<br>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |-&gt;accept_failure<br># $_[HEAP]<br>#----------<br>
# $[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{desc, port, queue, alarm_files, listen_wheel, client_wheels}<br>#<br>package virtualOMC;</font></div>
<p><font face="courier new,monospace" size="1">use strict;<br>use warnings;</font></p>
<p><font face="courier new,monospace" size="1">use Socket;<br>use IO::File;<br>use IO::File::Multi;<br>use Queue::Base;<br>use POSIX qw/strftime/;</font></p>
<p><font face="courier new,monospace" size="1">use POE;<br>use POE::Driver::SysRW;<br>use POE::Filter::Stream;<br>use POE::Wheel::ReadWrite;<br>use POE::Wheel::SocketFactory;</font></p>
<p><font face="courier new,monospace" size="1">use constant PACKAGE_VERSION =&gt; '0.1';<br>use constant SELF_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; 'alarmForwarder';<br>use constant SELF_VERSION&nbsp;&nbsp;&nbsp; =&gt; '0.2';<br>use constant MAX_LENGTH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; 10000;
<br>use constant SCANNING_TIMER&nbsp; =&gt; 20;<br>use constant SENDING_TIMER&nbsp;&nbsp; =&gt; 30;</font></p>
<p><font face="courier new,monospace" size="1">#For debug<br>use Data::Dumper;</font></p>
<p><font face="courier new,monospace" size="1">my $logdir&nbsp;&nbsp; = 'log';<br>my $confdir&nbsp; = 'conf';<br>my $alarmdir = 'alarm';<br>my $pmconfig = 'ports_mapping.conf';<br>my $logfile&nbsp; = (strftime &quot;%Y%m%d&quot;, localtime).'.log';
<br>my $output&nbsp;&nbsp; = new IO::File::Multi;</font></p>
<p><font face="courier new,monospace" size="1">POE::Session-&gt;create(<br>&nbsp;&nbsp;&nbsp; inline_states =&gt; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _start =&gt; \&amp;main_start,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _stop&nbsp; =&gt; \&amp;main_stop,</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alarm_scanning =&gt; \&amp;alarm_scanning,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; update_queues&nbsp; =&gt; \&amp;update_queues,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; start_listen&nbsp;&nbsp; =&gt; \&amp;start_listen,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; accept_success =&gt; \&amp;accept_success,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; accept_failure =&gt; \&amp;accept_failure,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client_send&nbsp;&nbsp;&nbsp; =&gt; \&amp;client_send,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client_error&nbsp;&nbsp; =&gt; \&amp;client_error,<br>&nbsp;&nbsp;&nbsp; },<br>);</font></p>
<p><font face="courier new,monospace" size="1">POE::Kernel-&gt;run();</font></p>
<p><font face="courier new,monospace" size="1">exit;</font></p>
<p><font face="courier new,monospace" size="1">#Get timestamp<br>sub ts { return strftime &quot;%H:%M:%S&quot;, localtime; }</font></p>
<p><font face="courier new,monospace" size="1">#'_start' event<br>sub main_start {<br>&nbsp;&nbsp;&nbsp; $output-&gt;open('&gt;-');<br>&nbsp;&nbsp;&nbsp; $output-&gt;open(&quot;&gt;&gt; $logdir/$logfile&quot;);<br>&nbsp;&nbsp;&nbsp; $output-&gt;autoflush(1);</font>
</p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; $output-&gt;print(&quot;\n&quot;.('=' x 60).&quot;\n&quot;);<br>&nbsp;&nbsp;&nbsp; $output-&gt;print(SELF_NAME.SELF_VERSION.' of '.__PACKAGE__.PACKAGE_VERSION.&quot;\n&quot;);<br>&nbsp;&nbsp;&nbsp; $output-&gt;print(('=' x 60).&quot;\n\n&quot;);
</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; &amp;load_config;<br>}</font></p>
<p><font face="courier new,monospace" size="1">#'_stop' event<br>sub main_stop {<br>&nbsp;&nbsp;&nbsp; $output-&gt;close();<br>&nbsp;&nbsp;&nbsp; delete $_[HEAP]-&gt;{vnes};<br>}</font></p>
<p><font face="courier new,monospace" size="1">#Load ports-mapping config of virtual NEs<br>sub load_config {<br>&nbsp;&nbsp;&nbsp; $output-&gt;print(ts().&quot;, load ports-mapping config\n&quot;);</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; my $config_fh = new IO::File &quot;$confdir/$pmconfig&quot;, &quot;r&quot;;</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; while(&lt;$config_fh&gt;) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chomp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; next if(m/^\s{0,}$/ or /^#/);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my ($vid, $desc, $port) = split /\s+/, $_;</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{desc} = $desc;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{port} = $port;<br>&nbsp;&nbsp;&nbsp; }</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; #print Dumper($_[HEAP]-&gt;{vnes});<br>&nbsp;&nbsp;&nbsp; $config_fh-&gt;close();<br>&nbsp;&nbsp;&nbsp; &amp;create_queues;<br>}</font></p>
<p><font face="courier new,monospace" size="1">#Create alarm queues<br>sub create_queues {<br>&nbsp;&nbsp;&nbsp; $output-&gt;print(ts().&quot;, create alarm queues\n&quot;);<br>&nbsp;&nbsp;&nbsp; $_[HEAP]-&gt;{vnes}-&gt;{$_}-&gt;{queue} = new Queue::Base foreach(keys %{$_[HEAP]-&gt;{vnes}});
</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; #&amp;dump_queues;<br>&nbsp;&nbsp;&nbsp; $_[KERNEL]-&gt;yield('alarm_scanning');<br>&nbsp;&nbsp;&nbsp; $_[KERNEL]-&gt;yield('start_listen');<br>}</font></p>
<p><font face="courier new,monospace" size="1">#'alarm_scanning' event<br>sub alarm_scanning {<br>&nbsp;&nbsp;&nbsp; $output-&gt;print(ts().&quot;, scan alarm directory\n&quot;);</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; foreach my $vid (keys %{$_[HEAP]-&gt;{vnes}}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{alarm_files} = ();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opendir(ALARMDIR, &quot;$alarmdir/$vid&quot;);
</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (sort{$a cmp $b} readdir(ALARMDIR)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; next if(not m/\.log$/i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push @{$_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{alarm_files}}, $_;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; closedir(ALARMDIR);<br>&nbsp;&nbsp;&nbsp; }</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; #&amp;dump_alarmfiles;<br>&nbsp;&nbsp;&nbsp; $_[KERNEL]-&gt;yield('update_queues');<br>}</font></p>
<p><font face="courier new,monospace" size="1">#'update_queues' event<br>sub update_queues {<br>&nbsp;&nbsp;&nbsp; $output-&gt;print(ts().&quot;, update alarm queues\n&quot;);</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; foreach my $vid (keys %{$_[HEAP]-&gt;{vnes}}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach my $alarmfile (@{$_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{alarm_files}}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my @elems;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $alarmfh = new IO::File &quot;$alarmdir/$vid/$alarmfile&quot;, &quot;r&quot;;
</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chomp and push @elems, $_ while(&lt;$alarmfh&gt;);</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $alarmfh-&gt;close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{queue}-&gt;add(@elems);</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $total_length = $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{queue}-&gt;size();</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{queue}-&gt;remove($total_length - MAX_LENGTH)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if($total_length &gt; MAX_LENGTH);</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unlink(&quot;$alarmdir/$vid/$alarmfile&quot;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; #&amp;dump_queues;<br>&nbsp;&nbsp;&nbsp; $_[KERNEL]-&gt;delay('alarm_scanning' =&gt; SCANNING_TIMER);<br>}</font></p>
<p><font face="courier new,monospace" size="1">#For debug<br>sub dump_queues {<br>&nbsp;&nbsp;&nbsp; foreach my $vid (keys %{$_[HEAP]-&gt;{vnes}}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $queue = $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{queue};</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;Queue of $vid is empty\n&quot; and next if($queue-&gt;empty());</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my @elems = $queue-&gt;remove($queue-&gt;size());</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print Dumper(\@elems);<br>&nbsp;&nbsp;&nbsp; }<br>}</font></p>
<p><font face="courier new,monospace" size="1">#For debug<br>sub dump_alarmfiles {<br>&nbsp;&nbsp;&nbsp; foreach (keys %{$_[HEAP]-&gt;{vnes}}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print Dumper($_[HEAP]-&gt;{vnes}-&gt;{$_}-&gt;{alarm_files});<br>&nbsp;&nbsp;&nbsp; }<br>}</font>
</p>
<p><font face="courier new,monospace" size="1">#'start_listen' event<br>sub start_listen {<br>&nbsp;&nbsp;&nbsp; $output-&gt;print(ts().&quot;, create listening wheels\n&quot;);</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; foreach my $vid (keys %{$_[HEAP]-&gt;{vnes}}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{listen_wheel} = POE::Wheel::SocketFactory-&gt;new(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BindAddress&nbsp;&nbsp;&nbsp; =&gt; '
<a href="http://127.0.0.1">127.0.0.1</a>',<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BindPort&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{port},<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SocketDomain&nbsp;&nbsp; =&gt; AF_INET,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SocketType&nbsp;&nbsp;&nbsp;&nbsp; =&gt; SOCK_STREAM,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ListenQueue&nbsp;&nbsp;&nbsp; =&gt; SOMAXCONN,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SocketProtocol =&gt; 'tcp',<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Reuse&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; 'on',</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SuccessEvent&nbsp;&nbsp; =&gt; 'accept_success',<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FailureEvent&nbsp;&nbsp; =&gt; 'accept_failure',<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<br>&nbsp;&nbsp;&nbsp; }<br>}</font></p>
<p><font face="courier new,monospace" size="1">#'accept_success' event<br>sub accept_success {<br>&nbsp;&nbsp;&nbsp; my $accepted_handle = $_[ARG0];<br>&nbsp;&nbsp;&nbsp; my ($peer_addr, $peer_port, $listen_wid)= (inet_ntoa($_[ARG1]), $_[ARG2], $_[ARG3]);
</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; foreach my $vid (keys %{$_[HEAP]-&gt;{vnes}}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if($_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{listen_wheel}-&gt;ID() == $listen_wid) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $output-&gt;print(ts().&quot;, vID:$vid connected from '$peer_addr:$peer_port'\n&quot;);
</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $client_wheel = POE::Wheel::ReadWrite-&gt;new(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Handle&nbsp;&nbsp;&nbsp;&nbsp; =&gt; $accepted_handle,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Driver&nbsp;&nbsp;&nbsp;&nbsp; =&gt; POE::Driver::SysRW-&gt;new(),
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Filter&nbsp;&nbsp;&nbsp;&nbsp; =&gt; POE::Filter::Stream-&gt;new(),</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputEvent =&gt; 'client_send',<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ErrorEvent =&gt; 'client_error',<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $client_wid = $client_wheel-&gt;ID();</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{client_wheels}-&gt;{$client_wid} = $client_wheel;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_[KERNEL]-&gt;yield('client_send');</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; last;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>}</font></p>
<p><font face="courier new,monospace" size="1">#'accept_failure' event<br>sub accept_failure { }</font></p>
<p><font face="courier new,monospace" size="1">#'client_send' event<br>sub client_send {<br>&nbsp;&nbsp;&nbsp; $output-&gt;print(ts().&quot;, send alarm queues\n&quot;);</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; foreach my $vid (keys %{$_[HEAP]-&gt;{vnes}}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my $queue = $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{queue};</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if($queue-&gt;size()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my @elems = $queue-&gt;remove($queue-&gt;size());</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach my $client_wid (keys %{$_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{client_wheels}}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{client_wheels}-&gt;{$client_wid}-&gt;put(&quot;$_\n&quot;) foreach(@elems);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; $_[KERNEL]-&gt;delay('client_send' =&gt; SENDING_TIMER);<br>}</font></p>
<p><font face="courier new,monospace" size="1">#'client_error' event<br>sub client_error {<br>&nbsp;&nbsp;&nbsp; my $client_wid = $_[ARG3];</font></p>
<p><font face="courier new,monospace" size="1">&nbsp;&nbsp;&nbsp; foreach my $vid (keys %{$_[HEAP]-&gt;{vnes}}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(defined $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{client_wheels}-&gt;{$client_wid}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $output-&gt;print(ts().&quot;, client wheel '$client_wid' of vID:$vid closed\n&quot;);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete $_[HEAP]-&gt;{vnes}-&gt;{$vid}-&gt;{client_wheels}-&gt;{$client_wid};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>}</font></p>