Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re: How do I close a POE SocketFactory Socket?

by rcaputo (Chaplain)
on Jun 24, 2002 at 23:09 UTC ( [id://176981]=note: print w/replies, xml ) Need Help??


in reply to How do I close a POE SocketFactory Socket?

Wheels are meant to manage the things they're working with. Usually those are filehandles, as in the cases of SocketFactory, ListenAccept, FollowTail, ReadWrite, and Run. Normally you needn't hold copies of the handles themselves, but it can be handy when you want a handle to persist beyond the lifetime of its wheel.

Anyway, closing handles is very easy: Just delete all copies of the wheels that wraps them. When wheels are DESTROYed, the handles embedded within them usually are too.

sub agent_error { print "Got an agent error, exiting agent session!\n"; my ($function, $error) = @_[ARG0, ARG2]; print "SERVER: call to $function() failed: $error.\n"; # I sure would like to close the socket here... delete $_[HEAP]->{readwrite}; }

-- Rocco Caputo / poe.perl.org / poe.sf.net

Replies are listed 'Best First'.
Re: Re: How do I close a POE SocketFactory Socket?
by Declarent (Sexton) on Jun 24, 2002 at 23:22 UTC

    Ah, I see. It leaves me with one question, tho.

    This server will handle many connections at the same time. Let's say that 10 of them are online currently. If one of them gets alarmed and calls destroy on the readwrite wheel, what happens to the other nine?

    Will they go on their merry way? I'm used to working with forked children, which contain their own copies of things that can be smacked at will.

    How do these work?

    Many thanks for the insight so far...

    Declarent

      First I'd like to mention that you can have multiple alarms in POE, even in Windows. See POE::Kernel's documentation on the alarm() and delay() functions.

      The server as it's written will create one ReadWrite wheel per client connection, and they're all stored in the same place: $heap->{readwrite}. In other words, each new connection will clobber the last. That's probably not what you want to do. :)

      There are a few ways around this. First, each new ReadWrite wheel can be stored in a different $heap element. This stores each new wheel under its unique ID.

      my $wheel = POE::Wheel::ReadWrite->new( ... ); $heap->{readwrite}->{$wheel->ID} = $wheel;

      Every wheel event comes with a copy of the wheel's ID so you can tell which connection caused some activity. You might write your error handler like this:

      sub agent_error { my ($heap, $function, $error, $wheel_id) = @_[HEAP, ARG0, ARG2, ARG3 +]; print "SERVER: call to $function() failed: $error.\n"; print "Disconnecting agent!\n"; # Close the socket here... delete $heap->{readwrite}->{$wheel_id}; }

      Another way is to create a new Session instance for each client connection. This way is closest to fork() without really using fork: each connection has its own $heap to store things in.

      If you're in the mood for a very high level approach, see the documentation for POE::Component::Server::TCP. You can find a very short Server::TCP example in this section of POE's cookbook.

      -- Rocco Caputo / poe.perl.org / poe.sf.net

        That works nicely. I discovered that deleting the wheel was bad for my other clients, thanks for the info on ID.

        I'm pretty much all set on my server now, but I have one last question. The way my code currently works, my input session gets handed a value from the socket and I work on that one line of input. Now, the server that I'm porting to POE actually does a little talking back and forth during this part.

        Is there any way to get the socket handle inside the input session? I understand that SocketFactory produces regular sockets, but I don't know how to grab the handle once my connection has spawned a session.

        I've thought that perhaps by grabbing the socket handle and doing more IO, I'll likely be breaking the non-blocking nature of the server, so perhaps a better way would be to store the wheel ID and associated data in the heap and work on it on the next input?

        I'm not sure if you can store your own data in the heap to begin with, but perhaps that would be a cleaner method.

        Hmm, does this long a thread count as an interview? :P

        Thanks again for all your help!

        Declarent

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://176981]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2024-04-23 21:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found