[Slim-Checkins] r12628 - in /trunk/server/Slim: Control/Request.pm Web/Cometd.pm Web/Cometd/Manager.pm

andy at svn.slimdevices.com andy at svn.slimdevices.com
Mon Aug 20 16:24:57 PDT 2007


Author: andy
Date: Mon Aug 20 16:24:57 2007
New Revision: 12628

URL: http://svn.slimdevices.com?rev=12628&view=rev
Log:
Comet unsubscribe support

Modified:
    trunk/server/Slim/Control/Request.pm
    trunk/server/Slim/Web/Cometd.pm
    trunk/server/Slim/Web/Cometd/Manager.pm

Modified: trunk/server/Slim/Control/Request.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Control/Request.pm?rev=12628&r1=12627&r2=12628&view=diff
==============================================================================
--- trunk/server/Slim/Control/Request.pm (original)
+++ trunk/server/Slim/Control/Request.pm Mon Aug 20 16:24:57 2007
@@ -1029,6 +1029,28 @@
 	return $self->{'_ae_callback'};
 }
 
+# remove the autoExecuteCallback for this request
+sub removeAutoExecuteCallback {
+	my $self = shift;
+	
+	$self->{'_ae_callback'} = undef;
+	
+	my $cnxid       = $self->connectionID();
+	my $name        = $self->getRequestString();
+	my $clientid    = $self->clientid() || 'global';
+	my $request2del = $subscribers{$cnxid}{$name}{$clientid};
+	
+	$log->debug("removeAutoExecuteCallback: deleting $cnxid - $name - $clientid");
+	
+	delete $subscribers{$cnxid}{$name}{$clientid};
+	
+	# there should not be any of those, but just to be sure
+	Slim::Utils::Timers::killTimers( $self, \&__autoexecute );
+	Slim::Utils::Timers::killTimers( $request2del, \&__autoexecute );
+	
+	return 1;
+}
+
 # sets/returns the source subscribe callback
 sub autoExecuteFilter {
 	my $self = shift;

Modified: trunk/server/Slim/Web/Cometd.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Web/Cometd.pm?rev=12628&r1=12627&r2=12628&view=diff
==============================================================================
--- trunk/server/Slim/Web/Cometd.pm (original)
+++ trunk/server/Slim/Web/Cometd.pm Mon Aug 20 16:24:57 2007
@@ -334,6 +334,28 @@
 				}
 			}
 		}
+		elsif ( $obj->{channel} eq '/meta/unsubscribe' ) {
+			my $subscriptions = $obj->{subscription};
+			
+			# a channel name or a channel pattern or an array of channel names and channel patterns.
+			if ( !ref $subscriptions ) {
+				$subscriptions = [ $subscriptions ];
+			}
+			
+			# We can't actually unsubscribe here because we need a request object
+			# but we can tell the manager to dump them the next time they are
+			# received
+			$manager->unsubscribe( $clid, $subscriptions );
+			
+			for my $sub ( @{$subscriptions} ) {
+				push @{$events}, {
+					channel      => '/meta/unsubscribe',
+					clientId     => $clid,
+					subscription => $sub,
+					successful   => JSON::True,
+				};
+			}
+		}			
 		elsif ( $obj->{channel} eq '/slim/request' ) {
 			
 			# A non-subscription request
@@ -514,6 +536,15 @@
 		$id      = undef;
 	}
 	
+	# Do we need to unsubscribe from this request?
+	if ( $manager->should_unsubscribe_from( $clid, $channel ) ) {
+		$log->debug( "requestCallback: unsubscribing from $clid / $channel" );
+		
+		$request->removeAutoExecuteCallback();
+			
+		return;
+	}
+	
 	# Construct event response
 	my $events = [ {
 		channel   => $channel,

Modified: trunk/server/Slim/Web/Cometd/Manager.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Web/Cometd/Manager.pm?rev=12628&r1=12627&r2=12628&view=diff
==============================================================================
--- trunk/server/Slim/Web/Cometd/Manager.pm (original)
+++ trunk/server/Slim/Web/Cometd/Manager.pm Mon Aug 20 16:24:57 2007
@@ -35,6 +35,7 @@
 	
 	$self->{clients}->{$clid} = {
 		pending_events       => {},    # stores most recent event per channel
+		to_unsubscribe       => {},    # channels to unsubscribe from
 		streaming_connection => undef, # streaming connection to use
 		streaming_response   => undef, # response object for streaming
 	};
@@ -46,6 +47,24 @@
 	my ( $self, $clid ) = @_;
 	
 	return exists $self->{clients}->{$clid};
+}
+
+sub unsubscribe {
+	my ( $self, $clid, $subs ) = @_;
+	
+	my $client = $self->{clients}->{$clid};
+	
+	for my $sub ( @{$subs} ) {
+		$client->{to_unsubscribe}->{$sub} = 1;
+	}
+	
+	return 1;
+}
+
+sub should_unsubscribe_from {
+	my ( $self, $clid, $sub ) = @_;
+	
+	return exists $self->{clients}->{$clid}->{to_unsubscribe}->{$sub};
 }
 
 sub remove_client {



More information about the checkins mailing list