| POE-Component-Server-Bayeux documentation | Contained in the POE-Component-Server-Bayeux distribution. |
POE::Component::Server::Bayeux::Client - An object representing a single client of the server
Used internally by POE::Component::Server::Bayeux.
Arguments:
The server's heap object
A POE::Component::Server::Bayeux::Request object representing an HTTP-connected client.
The clientId. If not given, generates one using Data::UUID.
For locally connected clients, the POE session alias or ID to post back to.
Completes an active poll if there is one
Called with a POE::Component::Server::Bayeux::Message, the client is to evaluate wether the message is invalid within the context of the client - as in, perform an authorization check. If there's an error, the message will have it's is_error() field set with the error.
Returns boolean of wether the client is subscribed to the literal channel provided
Sends, or queues, the message to the client. $subscription_args is the same hashref that was passed to the server's subscribe() method when this client subscribed to the channel. Structure of the message is same as Bayeux '5.2. Deliver Event message'.
Checks last time HTTP-connected client performed connected, and removes client if it's stale (according to server arg ConnectTimeout).
Flush the queue of messages, if there is any, and only if client is currently connected. Only used for HTTP-connected clients.
Return a reference to the servers logger.
Returns the server's args
Copyright (c) 2008 Eric Waters and XMission LLC (http://www.xmission.com/). All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the LICENSE file included with this module.
Eric Waters <ewaters@uarc.com>
| POE-Component-Server-Bayeux documentation | Contained in the POE-Component-Server-Bayeux distribution. |
package POE::Component::Server::Bayeux::Client;
use strict; use warnings; use Params::Validate; use Data::UUID; use POE; use base qw(Class::Accessor); __PACKAGE__->mk_accessors(qw( request id ip is_error flags server_heap heap session )); my $uuid = Data::UUID->new();
sub new { my $class = shift; my %self = validate(@_, { server_heap => 1, request => 0, id => 0, session => 0, flags => { default => {} }, heap => { default => {} }, }); my $self = bless \%self, $class; if ($self->request) { $self->ip( $self->request->ip ); } # Don't let the client id be arbitrarily defined save by a POE session if ($self->id && ! $self->session && ! $self->server_heap->{clients}{$self->id}) { $self->is_error("Client id '".$self->id."' is invalid"); return $self; } if (! $self->id || ($self->session && ! $self->server_heap->{clients}{$self->id})) { # Create a new client id $self->id( $uuid->create_str() ) unless $self->id(); my $heap = { created => time, ip => $self->ip, flags => { last_connect => time, }, session => $self->session, }; $self->server_heap->{clients}{ $self->id } = $heap; # Let the manager server know so it can do notifications $poe_kernel->post( $self->server_heap->{manager}, 'client_connect', { client_id => $self->id, ($self->session ? ( session => $self->session, ) : ( ip => $self->ip, )), }, ); } $self->heap( $self->server_heap->{clients}{$self->id} ); $self->session( $self->heap->{session} ) if ! $self->session && $self->heap->{session}; $self->flags( $self->heap->{flags} ); # Special: if is_polling, make sure it's still a pending request if (my $req_id = $self->heap->{flags}{is_polling}) { delete $self->heap->{flags}{is_polling} if ! defined $self->server_heap->{requests}{$req_id}; } return $self; }
sub disconnect { my ($self) = @_; $self->complete_poll(); # Let the manager server know so it can do notifications and unsubscribes $poe_kernel->post( $self->server_heap->{manager}, 'client_disconnect', { client_id => $self->id }); } sub complete_poll { my ($self) = @_; if (my $req_id = $self->flags->{is_polling}) { $poe_kernel->post( $self->server_heap->{manager}, 'complete_request', $req_id ); } }
sub message_acl { my ($self, $message) = @_; # If the client has asked for comment filtered JSON, pass this along to the # request which will be encapsulating the results. if ($self->flags->{'json-comment-filtered'}) { $message->request->json_comment_filtered(1); } # All messages fail if I'm in error if ($self->is_error) { $message->is_error($self->is_error); return; } $self->server_config->{MessageACL}->($self, $message); return if $message->is_error; }
sub is_subscribed { my ($self, $channel) = @_; return exists $self->heap->{subscriptions}{$channel}; }
sub send_message { my ($self, $message, $subscription_args) = @_; if ($subscription_args->{no_callback}) { return; } if ($self->session) { my $state = $subscription_args->{state} || 'deliver'; $poe_kernel->post( $self->session, $state, $message ); return; } $self->check_timeout(); if ($self->is_error()) { $self->logger->error("Not sending message to client ".$self->id.": ".$self->is_error); return; } $self->logger->debug("Queuing message to client ".$self->id); push @{ $self->heap->{queued_responses} }, $message; # Delay flush_queue so that if other responses need to be queued, they'll go out at the same time $poe_kernel->post($self->server_heap->{manager}, 'delay_sub', 'flush_queue.' . $self->id, 0, sub { $self->flush_queue }); }
sub check_timeout { my ($self) = @_; return if $self->session; return if $self->flags->{is_polling}; my $connect_timeout = $self->server_heap->{args}{ConnectTimeout}; if (time - $self->flags->{last_connect} < $connect_timeout) { return; } $self->is_error("Connect timeout; removing client"); $self->disconnect(); }
sub flush_queue { my ($self) = @_; return if ! $self->heap->{queued_responses}; return if ! $self->flags->{is_polling}; my $request = $self->server_heap->{requests}{ $self->flags->{is_polling} }; return if ! $request; my $queue = delete $self->heap->{queued_responses}; return if ! ref $queue || ref $queue ne 'ARRAY' || int @$queue == 0; $self->logger->debug("Flushing queue to active request on ".$self->id); $request->add_response($_) foreach @$queue; $self->complete_poll(); }
sub logger { my ($self) = @_; return $self->server_heap->{logger}; }
sub server_config { my ($self) = @_; return $self->server_heap->{args}; }
1;