tsvikt has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have a poe component tcp server and a session. I need to send updates from the session to the server. here is a sample I used that didn't work:
#!/usr/bin/perl -w use strict; use YAML; sub POE::Kernel::ASSERT_DEFAULT () { 1 } use POE; use POE::Component::Server::TCP; use POE::Filter::Reference; POE::Component::Server::TCP->new(Alias => 'TOF', Port => 2222, ClientFilter => ['POE::Filter::Reference'], ClientInput => \&client_input, InlineStates => {Update_clients => \&update_clients, }, ); POE::Session->create(inline_states => {_start => \&_start, Send_updates => \&send_update, _stop => \&_stop, }, ); POE::Kernel->run(); exit; sub client_input { my $input = $_[ARG0]; print 'my input = ' . YAML::Dump($input); } sub update_clients { my $update = $_[ARG0]; print 'my update is ' . YAML::Dump($update); } sub _start { my $kernel = $_[KERNEL]; print "session started\n"; $kernel->yield('Send_update'); } sub send_update { my $kernel = $_[KERNEL]; my $update = {Header => 'update', Msg => 'Hello Server', }; $kernel->post('TOF', 'Update_clients', $update); $kernel->delay('Send_update', 10); } sub _stop { print "session end\n"; }
this is the output_errors I get when I run it: session started a 'Update_clients' event was sent from talk_from_session_to_server.pl at 53 to session 2 (TOF) but session 2 (TOF) has neither a handler for it nor one for _default what am I doing wrong? thanks for the help

Replies are listed 'Best First'.
Re: POE: post an event on tcp server from a session
by Solo (Deacon) on Jul 26, 2005 at 13:01 UTC
    Typo in the event name.

    inline_states => { ... Send_updates => \&send_update, ... # later $kernel->yield('Send_update');

    Correcting that leads to a newer problem, though.

    a 'Update_clients' event was sent from pmtest.pl at 57 to session 2 (T +OF) but session 2 (TOF) has neither a handler for it nor one for _default

    But the event names look correct in this case, so InlineStates must not behave the way you expect in this component. Looking at the source for POE::Component::Server::TCP it seems the InlineStates are not added to the 'listener' PoCo::Server::TCP session, but only to sessions spawned by the default Acceptor handler which is used when one is not provided by the caller. In any case, the session 'TOF' would not get the InlineStates, it's children would. There doesn't seem to be an easy way to add additional states to the listener at creation. But I only took a quick look at the source.

    --Solo

    --
    You said you wanted to be around when I made a mistake; well, this could be it, sweetheart.
Re: POE: post an event on tcp server from a session
by rcaputo (Chaplain) on Jul 26, 2005 at 16:07 UTC

    A brand new POE::Component::Server::TCP has a single session that listens for new connections. It spawns off a new session for each connection that arrives.

    The server session uses the given Alias. In your code, that means "TOF" addresses the server itself. The individual connections do not have aliases. Even if they did, it would be difficult to address a particular connection without some arbitration: Which connection does "Moe" refer to?

    The best pattern devised so far is to have each connection register itself with a data structure to keep track of them all. The chat server recipe in the POE Cookbook shows a relatively simple way to do this.

    On a stylistic note, it is a bad idea to mix event handlers from multiple sessions in one file. It becomes difficult to tell which session a particular function belongs to.

    What follows is an untested version of your original program using concepts lifted from the Chat Server recipe.