Hi Tom,
POE uses the concept of sessions, which are similar to threads.
POE::Component::Client::TCP (hereafter Poco::TCP) spawns a new session,
which is distinct from the main session of the rest of your app. Each
session has its own distinct heap.
So, first off, wrt your application, saying...
$_[HEAP]->{server}=POE::Component::Client::TCP->new
... doesn't do what you think it does. As far as I know PoCo::TCP
returns a reference to a session, not a "wheel" (i.e., not something you
can call a "put" method on, as you do later).
Just take out that initial "$_[HEAP]->{server}=". (It's not doing any
harm, but it's misleading you.)
Further, the heap you refer to in that line is actually different than
the heap that PoCo::TCP uses.
The PoCo::TCP states that you set up and call, like handle_connect,
handle_connect_error, all get passed PoCo::TCP's heap.
cv_send, however, gets passed the main session's heap, which doesn't
have a {server} attribute in it.
If you want &handle_send to be able to access PoCo::TCP's heap, just do
$web_heap = $kernel->alias_resolve('web')->get_heap();
$web_heap->put("$input_record\n");
(Note, though, that you misspelled "Alias" in your call to PoCo::TCP's
constructor. Note, too, that you're passing a "send" paramater to
PoCo::TCP -- with the line "send => \&handle_send," -- which doesn't do
anything, because PoCo::TCP doesn't take "send" as an argument.)
Starting out with POE involves a lot of thrashing around like this --
don't worry, you'll get used to it. I've found that things get very
confusing when you're dealing with more than one session within a single
file. I usually create package files with subroutines for each session
to simplify things.
Dan
On Wed, 2003-12-03 at 14:55, Phillips Thomas E Contr AFMC/ITON wrote:
> New to POE, so please be gentle.
>
> Using Tk and POE to write a client. Have read that there are some issues
> with Tk, POE and ActiveStates Perl on Win32; however, I think my problems
> are more basic. I am using the TkClient example from the Cookbook as the
> basis of my Tk interface.
>
> I have been able to successfully connect to a server, display status
> messages in the Tk windows and receive input from the server. I cannot send
> info to the server. Would like to tie the 'Request Update' button to the
> 'send' event. How do I do this?
>
>
> vitals:
> POE = v0.27
> OS=Windows 2000
> ActiveStates Perl = v 5.8.0 Build 806
>
> --- client.pl -----
> #!/perl/bin/perl
> use warnings;
> use strict;
> use Tk;
> use POE;
> use POE::Filter::Stream;
> use POE::Component::Client::TCP;
>
> local $| = 1;
> my $svr = "localhost"; # Server's ip address
> my $port = "32080"; # Server's port which app is running on.
> my $status = "Starting point...";
>
> # Create the session that will drive the user interface.
>
> POE::Session->create
> ( inline_states =>
> { _start => \&ui_start,
> ct_start => sub {
> $_[HEAP]->{server}=POE::Component::Client::TCP->new
> ( Alais => 'web',
> RemoteAddress => $svr,
> RemotePort => $port,
> Connected => \&handle_connect,
> ConnectError => \&handle_connect_error,
> Disconnected => \&handle_disconnect,
> ServerInput => \&handle_server_input,
> ServerError => \&handle_server_error,
> ServerFlushed => \&handle_server_flush,
> send => \&handle_send,
> ); $status = "Connected"; },
> cv_send => \&handle_send, # This doesnt work, but
> when I push the "request update" button I come here.
>
> }
> );
>
> # Run the program until it is exited.
>
> $poe_kernel->run();
>
> 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 => \$status )->pack;
>
> $poe_main_window->Button
> ( -text => "Connect",
> -command => $session->postback("ct_start")
> )->pack;
> $poe_main_window->Button
> ( -text => "Request Update",
> -command => $session->postback("cv_send") #
> subst 'send' for 'cv_send' doesnt work
> )->pack;
> $poe_main_window->Button
> ( -text => "Disconnect",
> -command => $session->postback("Disconnect")
> )->pack;
> $status="Press Connect Button";
> }
>
>
> sub handle_start {
> my @args = @_[ARG0..$#_];
> }
>
> sub handle_connect {
> $status = "2Connected";
> }
>
> sub handle_send {
> my ($kernel, $heap,$input_record) = @_[KERNEL, HEAP, ARG0];
> chomp $input_record;
> print "Server send $input_record\n";
> $_[HEAP]->{server}->put("$input_record\n") ; # <<<<<< This doesnt work
>
> }
>
> sub handle_connect_error {
> my ( $kernel, $heap, $syscall_name, $error_number, $error_string) =
> @_[KERNEL, HEAP,ARG0, ARG1, ARG2];
> $status = "I had problems.\n$syscall_name\n
> $error_number\n$error_string";
> }
>
> sub handle_disconnect {
> my ($kernel, $heap ) = @_[ KERNEL, HEAP ];
> #$kernel->yield("shutdown");
> $status = "Disconnect me.";
> }
>
> sub handle_server_input {
> my ($kernel, $heap,$input_record) = @_[KERNEL, HEAP, ARG0];
> chomp $input_record;
> $status = "Server input:$input_record";
> #print "Server input >$input_record<\n";
> #$_[HEAP]->{server}->put("1") if ($input_record ne "Update requested");
> }
>
> sub handle_server_error {
> my ($syscall_name, $error_number, $error_string) = @_[ARG0, ARG1, ARG2];
> $status = "I had an error:\n$syscall_name\n
> $error_number\n$error_string";
> }
>
> sub handle_server_flush {
> # no special parameters
> $status= "Time to flush\n";
> }
>
>
> Thank you,
> Tom