Hello POE experts,
I am just a bloody beginner with POE (though not with Perl),
and I would like to create an application which
- is steered via a GUI (Tk)
- should run lots of asynchronous/parallel stuff
- reports results/states etc via HTTP
However, when I try to start up both the Tk example and one of the
Web servers from the cookbook within one POE session
(code see attachment), the first HHTP request causes a POE crash,
with the output listed below.
Of course the standalone cookbook examples do work very well.
Any help/comment is appreciated.
I am using Perl 5.8.0 on Solaris, with PerlIO.
Best regards,
Markus
(in cleanup) whoops; no tk file io object at
/vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/lib/site_p
erl/5.8.0/POE/Loop/Tk.pm line 242.
Tk::Error: fileno not same for read 6 and write 7 at
/vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/lib/site_p
erl/5.8.0/sun4-solaris/Tk/Event/IO.pm line 115.
(in cleanup) whoops; no tk file io object at
/vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/lib/site_p
erl/5.8.0/POE/Loop/Tk.pm line 242.
Tk::After::once at
/vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/lib/site_p
erl/5.8.0/sun4-solaris/Tk/After.pm line 83
[once,[{},after#21,0,once,[\&POE::Kernel::_loop_event_callback]]]
("after" script)
!!! Leaked fileno: 6 (total refcnt=1)
!!! Read:
!!! refcnt = 0
!!! ev cnt = 0
!!! Write:
!!! refcnt = 0
!!! ev cnt = 0
Not an ARRAY reference at
/vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/lib/site_p
erl/5.8.0/POE/Kernel.pm line 934.
--
Markus Jansen Senior IS/IT Support Engineer, EED/IT
Ericsson Eurolab Deutschland GmbH Email : [EMAIL PROTECTED]
Ericsson Allee 1 Phone : +49 2407 575 5157
52134 Herzogenrath Fax : +49 2407 575 7289
Germany Mobile: +49 172 274 2003
#! /vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/bin/perl -w
# http://poe.perl.org/?POE_Cookbook/Tk_Interfaces
#
# This sample program creates a very simple Tk counter. Its interface
# consists of three widgets: A rapidly increasing counter, and a
# button to reset that counter.
use warnings;
use strict;
# Tk support is enabled if the Tk module is used before POE itself.
use Tk;
use POE;
use POE qw(Component::Server::TCP Filter::HTTPD);
use HTTP::Response;
# Spawn a web server on port 8088 of all interfaces.
POE::Component::Server::TCP->new
( Alias => "web_server",
Port => 8088,
ClientFilter => 'POE::Filter::HTTPD',
# The ClientInput function is called to deal with client input.
# Because this server uses POE::Filter::HTTPD to parse input,
# ClientInput will receive HTTP requests.
ClientInput => sub {
my ( $kernel, $heap, $request ) = @_[ KERNEL, HEAP, ARG0 ];
# Filter::HTTPD sometimes generates HTTP::Response objects.
# They indicate (and contain the response for) errors that occur
# while parsing the client's HTTP request. It's easiest to send
# the responses as they are and finish up.
if ( $request->isa("HTTP::Response") ) {
$heap->{client}->put($request);
$kernel->yield("shutdown");
return;
}
# The request is real and fully formed. Build content based on
# it. Insert your favorite template module here, or write your
# own. :)
my $request_fields = '';
$request->headers()->scan
( sub {
my ( $header, $value ) = @_;
$request_fields .= "<tr><td>$header</td><td>$value</td></tr>";
}
);
my $response = HTTP::Response->new(200);
$response->push_header( 'Content-type', 'text/html' );
$response->content
( "<html><head><title>Your Request</title></head>" .
"<body>Details about your request:" .
"<table border='1'>$request_fields</table>" .
"</body></html>"
);
# Once the content has been built, send it back to the client
# and schedule a shutdown.
$heap->{client}->put($response);
$kernel->yield("shutdown");
}
);
# Create the session that will drive the user interface.
POE::Session->create
( inline_states =>
{ _start => \&ui_start,
ev_count => \&ui_count,
ev_clear => \&ui_clear,
}
);
# Run the program until it is exited.
$poe_kernel->run();
exit 0;
# Create the user interface when the session starts. This assumes
# some familiarity with Tk. ui_start() illustrates four important
# points.
#
# 1. Tk events require a main window. POE creates one for internal
# use and exports it as $poe_main_window. ui_start() uses that as the
# basis for its user interface.
#
# 2. Widgets we need to work with later, such as the counter display,
# must be stored somewhere. The heap is a convenient place for them.
#
# 3. Tk widgets expect callbacks in the form of coderefs. The
# session's postback() method provides coderefs that post events when
# called. The Button created in ui_start() fires an "ev_clear" event
# when it is pressed.
#
# 4. POE::Kernel methods such as yield(), post(), delay(), signal(),
# and select() (among others) work the same as they would without Tk.
# This feature makes it possible to write back end sessions that
# support multiple GUIs with a single code base.
sub ui_start {
my ( $kernel, $session, $heap ) = @_[ KERNEL, SESSION, HEAP ];
$poe_main_window->Label( -text => "Counter" )->pack;
$heap->{counter_widget} =
$poe_main_window->Label( -textvariable => \$heap->{counter} )->pack;
$poe_main_window->Button
( -text => "Count",
-command => $session->postback("ev_count")
)->pack;
$poe_main_window->Button
( -text => "Clear",
-command => $session->postback("ev_clear")
)->pack;
# $kernel->yield("ev_count");
$kernel->yield("ev_clear"); # display '0'
}
# Handle the "ev_count" event by increasing a counter and displaying
# its new value.
sub ui_count {
$_[HEAP]->{counter}++;
# $_[KERNEL]->yield("ev_count");
}
# Handle the "ev_clear" event by clearing and redisplaying the
# counter.
sub ui_clear {
$_[HEAP]->{counter} = 0;
}