Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

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;

Replies are listed 'Best First'.
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 -

      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 -

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://372014]
Approved by graff
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2018-02-21 00:19 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (274 votes). Check out past polls.