On Wed, Dec 31, 2003 at 03:37:45PM -0600, Jay Strauss wrote:
> Hi,
> 
> I'd like to build an object, which would connect (via
> POE::Component::Client::TCP) to my POE server.  I want the object to keep
> the connection open so that I could call the methods and perform useful
> tasks without having to connect - disconnect within each of my objects
> methods.
> 
> Sorta like (pseudo code):
> 
> package TWS;
> 
> POE::Component::Client::TCP->new(...);
> 
> sub quote {
>     # send @_ to the server
>     # process the data sent back by server
> }
> 
> sub order {
>     # send @_ to the server
> }
>
> ### then in a nearby piece of code:
> my $tws = TWS->new;
> $tws->quote('IBM');
> $tws->order(10,'IBM');

It looks like you want quote() and order() to block until they're done.
You can probably use the undocumented (and poorly tested)
run_one_timeslice() method of POE::Kernel.  Please let me know how it
work for you.

The idea is to create your single client, like this slightly modified
version of your original client code.

>     POE::Component::Client::TCP->new(
>         ...
>         Args            => [EMAIL PROTECTED],
          Alias           => "client_connection",
>         Started         => sub {..},
>         Connected       => sub {
>             ...
>            $heap->{server}->put(\$stuff);
>             }
>         },
> 
>         ServerInput     => sub {

            # If we've received an order, and we're waiting for an
            # order, then clear the semaphore.  This will let the
            # run_one_timeslice() loop in TWS fall through.

            if ($got_an_order and $heap->{transaction} eq "order") {
              ${$heap->{semaphore}} = 0;
              $heap->{transaction} = "none";
            }

>         },

          # If something's been flushed to the server, and we're waiting
          # for a quote to be sent, then we can clear the semaphore.
          # The run_one_timeslice() loop in TWS will fall through.

          ServerFlushed => sub {
            my $heap = $_[HEAP];
            if ($heap->{transaction} eq "quote") {
              ${$heap->{semaphore}} = 0;
              $heap->{transaction} = "none";
            }
          },

          # Also new, and possibly too simplistic for real use.
          Disconnected => sub { $_[KERNEL]->yield("reconnect"),

          # Handle some custom events.
          InlineStates => {
            send_quote => sub {
              my ($heap, $semaphore, $stuff) = @_[HEAP, ARG0, ARG1];
              $heap->{server}->put($stuff);
              $heap->{semaphore} = $semaphore;
              $heap->{transaction} = "quote";
            },

            do_order => sub {
              my ($heap, $semaphore, $stuff) = @_[HEAP, ARG0, ARG1];
              $heap->{server}->put($stuff);
              $heap->{semaphore} = $semaphore;
              $heap->{transaction} = "order";
            }
          }
>     );

Then your quote() and order() methods post events to "client_connection"
and wait for completion.

sub quote {
  my ($object, $stuff) = @_;

  my $semaphore = 1;
  $poe_kernel->post( client_connection => send_quote, \$semaphore, $stuff );
  while ($semaphore) {
    $poe_kernel->run_one_timeslice();
  }
}

sub order {
  my ($object, $stuff) = @_;

  my $semaphore = 1;
  $poe_kernel->post( client_connection => do_order => \$semaphore, $stuff);
  while ($semaphore) {
    $poe_kernel->run_one_timeslice();
  }
}

That's the theory anyway.  None of this code is tested.

-- 
Rocco Caputo - [EMAIL PROTECTED] - http://poe.perl.org/

Reply via email to