Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Missing event from InlineStates in POE::Component::Server::TCP

by diotalevi (Canon)
on Jul 06, 2004 at 03:49 UTC ( #372014=perlquestion: print w/ replies, xml ) Need Help??
diotalevi has asked for the wisdom of the Perl Monks concerning the following question:

The following error occurs when I run this script. The AddPublisher state is declared in POE::Component::Server::TCP->create( InlineStates => { ... } ). What is wrong that I am getting this error and why is it not triggering a fatal assertion?

a 'AddPublisher' state was sent from poe at 13 to session 2, but sessi +on 2 has neither that state nor a _default state to handle it POE::Component::Server::TCP->new( Alias => 'TCPServer', ... InlineStates => { AddPublisher => sub {} } ; $_[KERNEL]->post( TCPServer => AddPublisher => $_[SESSION], 1 ); },

The script at ~diotalevi/poe2

sub POE::Kernel::ASSERT_DEFAULT () { 1 } use POE qw( Session Component::Server::TCP ); POE::Component::Server::TCP->new( Alias => 'TCPServer', Port => 53511, InlineStates => { AddPublisher => sub {} }, ClientInput => sub {} ); POE::Session->create( inline_states => { _start => sub { $_[KERNEL]->post( TCPServer => AddPublisher => $_[SESSION], 1 ); }, _stop => sub {} } ); POE::Kernel->run;

Comment on Missing event from InlineStates in POE::Component::Server::TCP
Select or Download Code
Re: Missing event from InlineStates in POE::Component::Server::TCP
by rcaputo (Chaplain) on Jul 06, 2004 at 16:31 UTC

    Your TCPServer alias is for the main server session. This is the session that listens on the server socket, accepts connections, and spawns off new sessions for each client/server connection.

    The InlineStates parameter defines new events and handlers for each client/server session. These sessions are different than the one with the TCPServer alias. When you later post() to TCPServer, you're sending the event to a session that doesn't handle it.

    If you want the AddPublisher event to go to every client/server connection, you'll need to register the connections in a hash. This untested code might help:

    my %clients; POE::Component::Server::TCP->new( Alias => 'TCPServer', Port => 53511, ClientConnected => sub { $clients{$_[SESSION]->ID} = 1 }, ClientDisconnected => sub { delete $clients{$_[SESSION]->ID} }, ClientInput => sub { }, InlineStates => { AddPublisher => sub { }, }, ); POE::Session->create( inline_states => { _start => sub { foreach my $client (keys %clients) { $_[KERNEL]->post( $client, AddPublisher => $_[SESSION], 1 ); } }, _stop => sub { }, } ); POE::Kernel->run(); exit;

    On the other hand, you may really want to enter each publisher into a central registry, and have the client/server connections interact with them that way. Not only is this code untested, but it also borrows a lot of its bulk from the previous untested code. Consider it doubly potentially buggy.

    my %plugins; POE::Component::Server::TCP->new( Alias => 'TCPServer', Port => 53511, ClientInput => sub { my $input = $_[ARG0]; foreach my $plugin (keys %plugins) { send_input_to_plugin($input, $plugin); } }, ); POE::Session->create( inline_states => { _start => sub { $plugins{$_[SESSION]->ID} = 1 }, _stop => sub { delete $plugins{$_[SESSION]->ID} }, } ); POE::Kernel->run(); exit;

    I like the second way better than the first. Clients can come and go, but the plugins remain the same. Still, you may have a really good reason for doing it the first way. I don't know. It's hard to say which (if either) is best without knowing more about the code's purpose.

    -- Rocco Caputo - http://poe.perl.org/

      I did not understand that POE::Component::Server::TCP->create( Alias => ... ) refers to to the listening server session and that InlineStates is declaring events for its children. I get it now. So instead of one TCPServer session I really have one parent TCPServer session and lots of children.

      How then do I register events for the hub server? I thought I should store stuff for it in its heap instead of just some global.

        Heaps are just session-scoped hash references. Consider them like $self, but they're kept aside for your event handlers to use.

        You certainly can use them for inter-session storage, but it won't be as practical as setting aside a plain hash. Consider that your accessors would need to be event-based, which makes them insanely slow compared to $hash{foo} = 1 or just incredibly slow compared to $object->set_foo(1).

        -- Rocco Caputo - http://poe.perl.org/

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://372014]
Approved by graff
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (8)
As of 2015-07-06 09:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (71 votes), past polls