[Red5commits] [1628] 1. ApplicationAdapter? now has scheduleGhostConnectionsCleanup method that start

mklishin luke at codegent.com
Wed Jan 24 11:09:47 EST 2007


1. ApplicationAdapter? now has scheduleGhostConnectionsCleanup method that starts scheduled job that kill ghost connections based on time to live set by developer. Period of cleanup is configurable.
2. ApplicationAdapter? refactored a bit to be more DRY.
3. Scope#getConnections renamed to getConnectionsIter.
4. PlaylistSubscriberStream? now has getCurrentItem method that returns reference to currently played item or, in case of live stream subscription interception, live stream object that client subscribes to.
5. Documentation, documentation, documentation where missing.


Timestamp: 01/17/07 19:26:06 EST (1 week ago) 
Change: 1628 
Author: mklishin

Files (see diff or trac for details): 
java/server/trunk/license.txt
java/server/trunk/src/org/red5/io/mp3/impl/MP3Header.java
java/server/trunk/src/org/red5/io/mp3/impl/MP3Reader.java
java/server/trunk/src/org/red5/io/object/Deserializer.java
java/server/trunk/src/org/red5/io/utils/BufferUtils.java
java/server/trunk/src/org/red5/io/utils/DOM2Writer.java
java/server/trunk/src/org/red5/io/utils/HexDump.java
java/server/trunk/src/org/red5/io/utils/IOUtils.java
java/server/trunk/src/org/red5/server/ScopeResolver.java
java/server/trunk/src/org/red5/server/adapter/ApplicationAdapter.java
java/server/trunk/src/org/red5/server/adapter/StatefulScopeWrappingAdapter.java
java/server/trunk/src/org/red5/server/api/stream/IPlayItem.java
java/server/trunk/src/org/red5/server/api/stream/IPlaylist.java
java/server/trunk/src/org/red5/server/api/stream/support/SimplePlayItem.java
java/server/trunk/src/org/red5/server/net/rtmp/RTMPHandler.java
java/server/trunk/src/org/red5/server/net/rtmp/RTMPUtils.java
java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPProtocolEncoder.java
java/server/trunk/src/org/red5/server/net/rtmp/message/Constants.java
java/server/trunk/src/org/red5/server/net/rtmp/message/Packet.java
java/server/trunk/src/org/red5/server/stream/BroadcastScope.java
java/server/trunk/src/org/red5/server/stream/ClientBroadcastStream.java
java/server/trunk/src/org/red5/server/stream/PlaylistSubscriberStream.java
java/server/trunk/src/org/red5/server/stream/StreamService.java


Trac: http://mirror1.cvsdude.com/trac/osflash/red5/changeset/1628

Index: /java/server/trunk/src/org/red5/server/adapter/ApplicationAdapter.java
===================================================================
--- /java/server/trunk/src/org/red5/server/adapter/ApplicationAdapter.java (revision 1609)
+++ /java/server/trunk/src/org/red5/server/adapter/ApplicationAdapter.java (revision 1628)
@@ -76,4 +76,7 @@
  * </p>
  *
+ *
+ * @author Joachim Bauch
+ * @author Michael Klishin
  */
 public class ApplicationAdapter extends StatefulScopeWrappingAdapter implements
@@ -92,5 +95,62 @@
 	private Set<IApplication> listeners = new HashSet<IApplication>();
 
-	/**
+    /**
+     * SharedObject service
+     */
+    protected ISharedObjectService sharedObjectService;
+
+    /**
+     * Provides input objects
+     */
+    protected IProviderService providerService;
+
+    /**
+     * OD streams service
+     */
+    protected IOnDemandStreamService vodService;
+
+    /**
+     * Scheduling service. Uses Quartz. Adds and removes scheduled jobs.
+     */
+    protected ISchedulingService schedulingService;
+
+    /**
+     * Client time to live is max allowed ping return time, in seconds
+     */
+    private int clientTTL = 2;
+
+    /**
+     * Ghost connections (disconnected users listed as connected) cleanup period in seconds
+     */
+    private int ghostConnsCleanupPeriod = 5;
+
+    /**
+     * Ghost connections cleanup job name. Needed to cancel this job.
+     */
+    private String ghostCleanupJobName;
+
+    /**
+     * Creates new application adapter
+     */
+    public ApplicationAdapter() {
+        sharedObjectService = (ISharedObjectService) getScopeService(
+                scope, ISharedObjectService.class,
+                SharedObjectService.class, false);
+
+        providerService = (IProviderService) getScopeService(scope,
+                IProviderService.class, ProviderService.class);
+
+        vodService = (IOnDemandStreamService) getScopeService(
+                scope, IOnDemandStreamService.class,
+                StreamService.class, false);
+
+        schedulingService = (ISchedulingService) getScopeService(
+                scope, ISchedulingService.class,
+                QuartzSchedulingService.class, false);
+
+        
+    }
+
+    /**
 	 * Register listener that will get notified about application events. Please
 	 * note that return values (e.g. from {@link IApplication#appStart(IScope)})
@@ -563,15 +623,13 @@
 	 * @param persistent
 	 *            Whether SharedObject instance should be persistent or not
-	 * @return					New shared object instance
+	 * @return					<code>true</code> if SO was created, <code>false</code> otherwise
 	 */
 	public boolean createSharedObject(IScope scope, String name,
 			boolean persistent) {
-		ISharedObjectService service = (ISharedObjectService) getScopeService(
-				scope, ISharedObjectService.class,
-				SharedObjectService.class, false);
-		return service.createSharedObject(scope, name, persistent);
-	}
-
-	/**
+
+        return sharedObjectService.createSharedObject(scope, name, persistent);
+    }
+
+    /**
 	 * Returns shared object from given scope by name.
 	 * 
@@ -583,8 +641,5 @@
 	 */
 	public ISharedObject getSharedObject(IScope scope, String name) {
-		ISharedObjectService service = (ISharedObjectService) getScopeService(
-				scope, ISharedObjectService.class,
-				SharedObjectService.class, false);
-		return service.getSharedObject(scope, name);
+		return sharedObjectService.getSharedObject(scope, name);
 	}
 
@@ -602,8 +657,5 @@
 	public ISharedObject getSharedObject(IScope scope, String name,
 			boolean persistent) {
-		ISharedObjectService service = (ISharedObjectService) getScopeService(
-				scope, ISharedObjectService.class,
-				SharedObjectService.class, false);
-		return service.getSharedObject(scope, name, persistent);
+		return sharedObjectService.getSharedObject(scope, name, persistent);
 	}
 
@@ -615,8 +667,5 @@
 	 */
 	public Set<String> getSharedObjectNames(IScope scope) {
-		ISharedObjectService service = (ISharedObjectService) getScopeService(
-				scope, ISharedObjectService.class,
-				SharedObjectService.class, false);
-		return service.getSharedObjectNames(scope);
+		return sharedObjectService.getSharedObjectNames(scope);
 	}
 
@@ -630,8 +679,5 @@
 	 */
 	public boolean hasSharedObject(IScope scope, String name) {
-		ISharedObjectService service = (ISharedObjectService) getScopeService(
-				scope, ISharedObjectService.class,
-				SharedObjectService.class, false);
-		return service.hasSharedObject(scope, name);
+		return sharedObjectService.hasSharedObject(scope, name);
 	}
 
@@ -640,7 +686,6 @@
 	/** {@inheritDoc} */
     public boolean hasBroadcastStream(IScope scope, String name) {
-		IProviderService service = (IProviderService) getScopeService(scope,
-				IProviderService.class, ProviderService.class);
-		return (service.getLiveProviderInput(scope, name, false) != null);
+
+        return (providerService.getLiveProviderInput(scope, name, false) != null);
 	}
 
@@ -666,7 +711,5 @@
 	 */
 	public List<String> getBroadcastStreamNames(IScope scope) {
-		IProviderService service = (IProviderService) getScopeService(scope,
-				IProviderService.class, ProviderService.class);
-		return service.getBroadcastStreamNames(scope);
+		return providerService.getBroadcastStreamNames(scope);
 	}
 
@@ -683,7 +726,5 @@
 	 */
 	public boolean hasOnDemandStream(IScope scope, String name) {
-		IProviderService service = (IProviderService) getScopeService(scope,
-				IProviderService.class, ProviderService.class);
-		return (service.getVODProviderInput(scope, name) != null);
+		return (providerService.getVODProviderInput(scope, name) != null);
 	}
 
@@ -701,10 +742,6 @@
 	 */
 	public IOnDemandStream getOnDemandStream(IScope scope, String name) {
-		log
-				.warn("This won't work until the refactoring of the streaming code is complete.");
-		IOnDemandStreamService service = (IOnDemandStreamService) getScopeService(
-				scope, IOnDemandStreamService.class,
-				StreamService.class, false);
-		return service.getOnDemandStream(scope, name);
+		log.warn("This won't work until the refactoring of the streaming code is complete.");
+        return vodService.getOnDemandStream(scope, name);
 	}
 
@@ -721,6 +758,5 @@
 	 */
 	public ISubscriberStream getSubscriberStream(IScope scope, String name) {
-		log
-				.warn("This won't work until the refactoring of the streaming code is complete.");
+		log.warn("This won't work until the refactoring of the streaming code is complete.");
 		ISubscriberStreamService service = (ISubscriberStreamService) getScopeService(
 				scope, ISubscriberStreamService.class,
@@ -742,8 +778,5 @@
 	 */
 	public String addScheduledJob(int interval, IScheduledJob job) {
-		ISchedulingService service = (ISchedulingService) getScopeService(
-				scope, ISchedulingService.class,
-				QuartzSchedulingService.class, false);
-		return service.addScheduledJob(interval, job);
+        return schedulingService.addScheduledJob(interval, job);
 	}
 
@@ -761,8 +794,5 @@
 	 */
 	public String addScheduledOnceJob(long timeDelta, IScheduledJob job) {
-		ISchedulingService service = (ISchedulingService) getScopeService(
-				scope, ISchedulingService.class,
-				QuartzSchedulingService.class, false);
-		return service.addScheduledOnceJob(timeDelta, job);
+		return schedulingService.addScheduledOnceJob(timeDelta, job);
 	}
 
@@ -779,8 +809,5 @@
 	 */
 	public String addScheduledOnceJob(Date date, IScheduledJob job) {
-		ISchedulingService service = (ISchedulingService) getScopeService(
-				scope, ISchedulingService.class,
-				QuartzSchedulingService.class, false);
-		return service.addScheduledOnceJob(date, job);
+		return schedulingService.addScheduledOnceJob(date, job);
 	}
 
@@ -792,8 +819,5 @@
 	 */
 	public void removeScheduledJob(String name) {
-		ISchedulingService service = (ISchedulingService) getScopeService(
-				scope, ISchedulingService.class,
-				QuartzSchedulingService.class, false);
-		service.removeScheduledJob(name);
+		schedulingService.removeScheduledJob(name);
 	}
 
@@ -804,8 +828,5 @@
 	 */
 	public List<String> getScheduledJobNames() {
-		ISchedulingService service = (ISchedulingService) getScopeService(
-				scope, ISchedulingService.class,
-				QuartzSchedulingService.class, false);
-		return service.getScheduledJobNames();
+		return schedulingService.getScheduledJobNames();
 	}
 
@@ -820,7 +841,5 @@
 	 */
 	public double getStreamLength(String name) {
-		IProviderService provider = (IProviderService) getScopeService(scope,
-				IProviderService.class, ProviderService.class);
-		File file = provider.getVODProviderFile(scope, name);
+		File file = providerService.getVODProviderFile(scope, name);
 		if (file == null) {
 			return 0;
@@ -851,7 +870,81 @@
 	/** {@inheritDoc} */
     public boolean clearSharedObjects(IScope scope, String name) {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
+		return sharedObjectService.clearSharedObjects( scope, name );
+    }
+
+    /**
+     * Client time to live is max allowed connection ping return time in seconds
+     * @return              TTL value used in seconds
+     */
+    public long getClientTTL() {
+        return clientTTL;
+    }
+
+    /**
+     * Client time to live is max allowed connection ping return time in seconds
+     * @param clientTTL     New TTL value in seconds
+     */
+    public void setClientTTL(int clientTTL) {
+        this.clientTTL = clientTTL;
+    }
+
+    /**
+     * Return period of ghost connections cleanup task call
+     * @return              Ghost connections cleanup period
+     */
+    public int getGhostConnsCleanupPeriod() {
+        return ghostConnsCleanupPeriod;
+    }
+
+    /**
+     * Set new ghost connections cleanup period
+     * @param ghostConnsCleanupPeriod      New ghost connections cleanup period
+     */
+    public void setGhostConnsCleanupPeriod(int ghostConnsCleanupPeriod) {
+        this.ghostConnsCleanupPeriod = ghostConnsCleanupPeriod;
+    }
+
+    /**
+     * Schedules new ghost connections cleanup using current cleanup period
+     */
+    public void scheduleGhostConnectionsCleanup() {
+        IScheduledJob job = new IScheduledJob(){
+            public void execute(ISchedulingService service) throws CloneNotSupportedException {
+                killGhostConnections();
+            }
+        };
+
+        // Cancel previous if was scheduled
+        cancelGhostConnectionsCleanup();
+
+        // Store name so we can cancel it later
+        ghostCleanupJobName = schedulingService.addScheduledJob( ghostConnsCleanupPeriod, job );
+    }
+
+    /**
+     * Cancel ghost connections cleanup period
+     */
+    public void cancelGhostConnectionsCleanup() {
+        if( ghostCleanupJobName != null ){
+            schedulingService.removeScheduledJob( ghostCleanupJobName );
+        }
+    }
+
+    /**
+     * Cleans up ghost connections
+     */
+    protected void killGhostConnections() {
+        Iterator iter = getConnectionsIter();
+        while(iter.hasNext()) {
+            IConnection conn = (IConnection) iter.next();
+
+            // Ping client
+            conn.ping();
+
+            // Time to live exceeded, disconnect
+            if( conn.getLastPingTime() > clientTTL * 1000 ){
+                disconnect( conn, scope );    
+            }
+        }
+    }
 }
Index: /java/server/trunk/src/org/red5/server/adapter/StatefulScopeWrappingAdapter.java
===================================================================
--- /java/server/trunk/src/org/red5/server/adapter/StatefulScopeWrappingAdapter.java (revision 1609)
+++ /java/server/trunk/src/org/red5/server/adapter/StatefulScopeWrappingAdapter.java (revision 1628)
@@ -147,9 +147,10 @@
      * @return  Connections
      */
-    public Iterator<IConnection> getConnections() {
+    public Iterator<IConnection> getConnectionsIter() {
 		return scope.getConnections();
 	}
 
-	/**
+
+    /**
      * Getter for context
      *
Index: /java/server/trunk/src/org/red5/server/stream/BroadcastScope.java
===================================================================
--- /java/server/trunk/src/org/red5/server/stream/BroadcastScope.java (revision 1593)
+++ /java/server/trunk/src/org/red5/server/stream/BroadcastScope.java (revision 1628)
@@ -20,18 +20,12 @@
  */
 
-import java.util.List;
-import java.util.Map;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.red5.server.BasicScope;
 import org.red5.server.api.IScope;
-import org.red5.server.messaging.IConsumer;
-import org.red5.server.messaging.IMessage;
-import org.red5.server.messaging.IPipeConnectionListener;
-import org.red5.server.messaging.IProvider;
-import org.red5.server.messaging.InMemoryPushPushPipe;
-import org.red5.server.messaging.OOBControlMessage;
-import org.red5.server.messaging.PipeConnectionEvent;
+import org.red5.server.messaging.*;
+
+import java.util.List;
+import java.util.Map;
 
 /**
@@ -171,5 +165,5 @@
      * @return                 <code>true</code> on success, <code>false</code> otherwise
      */
-	synchronized public boolean subscribe(IProvider provider, Map paramMap) {
+    public synchronized boolean subscribe(IProvider provider, Map paramMap) {
 		synchronized (pipe) {
             return !hasRemoved && pipe.subscribe(provider, paramMap);
@@ -182,5 +176,5 @@
      * @return                 <code>true</code> on success, <code>false</code> otherwise
      */
-	synchronized public boolean unsubscribe(IProvider provider) {
+    public synchronized boolean unsubscribe(IProvider provider) {
 		return pipe.unsubscribe(provider);
 	}
Index: /java/server/trunk/src/org/red5/server/stream/PlaylistSubscriberStream.java
===================================================================
--- /java/server/trunk/src/org/red5/server/stream/PlaylistSubscriberStream.java (revision 1606)
+++ /java/server/trunk/src/org/red5/server/stream/PlaylistSubscriberStream.java (revision 1628)
@@ -343,5 +343,5 @@
 				// and wait for control from outside
 			} catch (IllegalStateException e) {
-
+               log.error( "Illegal state exception on playlist item setup", e );
 			}
 		}
@@ -403,5 +403,13 @@
 	}
 
-	/** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     */
+    public IPlayItem getCurrentItem() {
+        return getItem( getCurrentItemIndex() );
+    }
+
+
+    /** {@inheritDoc} */
     public IPlayItem getItem(int index) {
 		try {
Index: /java/server/trunk/src/org/red5/server/stream/StreamService.java
===================================================================
--- /java/server/trunk/src/org/red5/server/stream/StreamService.java (revision 1606)
+++ /java/server/trunk/src/org/red5/server/stream/StreamService.java (revision 1628)
@@ -21,17 +21,6 @@
 
 import org.red5.server.BaseConnection;
-import org.red5.server.api.IBasicScope;
-import org.red5.server.api.IConnection;
-import org.red5.server.api.IContext;
-import org.red5.server.api.IScope;
-import org.red5.server.api.Red5;
-import org.red5.server.api.stream.IBroadcastStream;
-import org.red5.server.api.stream.IClientBroadcastStream;
-import org.red5.server.api.stream.IClientStream;
-import org.red5.server.api.stream.IPlaylistSubscriberStream;
-import org.red5.server.api.stream.ISingleItemSubscriberStream;
-import org.red5.server.api.stream.IStreamCapableConnection;
-import org.red5.server.api.stream.IStreamService;
-import org.red5.server.api.stream.ISubscriberStream;
+import org.red5.server.api.*;
+import org.red5.server.api.stream.*;
 import org.red5.server.api.stream.support.SimplePlayItem;
 import org.red5.server.net.rtmp.Channel;
@@ -367,7 +356,7 @@
 
 	/**
-     * Getter for property 'currentStreamId'.
+     * Getter for current stream id.
      *
-     * @return Value for property 'currentStreamId'.
+     * @return  Current stream id
      */
     private int getCurrentStreamId() {
@@ -376,5 +365,11 @@
 	}
 
-	public IBroadcastScope getBroadcastScope(IScope scope, String name) {
+    /**
+     * Return broadcast scope object for given scope and child scope name
+     * @param scope          Scope object
+     * @param name           Child scope name
+     * @return               Broadcast scope
+     */
+    public IBroadcastScope getBroadcastScope(IScope scope, String name) {
 		synchronized (scope) {
 			IBasicScope basicScope = scope.getBasicScope(IBroadcastScope.TYPE,
Index: /java/server/trunk/src/org/red5/server/stream/ClientBroadcastStream.java
===================================================================
--- /java/server/trunk/src/org/red5/server/stream/ClientBroadcastStream.java (revision 1625)
+++ /java/server/trunk/src/org/red5/server/stream/ClientBroadcastStream.java (revision 1628)
@@ -108,5 +108,5 @@
 
 	/** Stores timestamp of first packet. */
-	private int firstTime = -1;
+	private int firstPacketTime = -1;
 
     /**
@@ -129,5 +129,5 @@
 			log.warn("No video codec factory available.", err);
 		}
-		firstTime = audioTime = videoTime = dataTime = -1;
+		firstPacketTime = audioTime = videoTime = dataTime = -1;
 		connMsgOut = consumerManager.getConsumerOutput(this);
 		recordPipe = new InMemoryPushPushPipe();
@@ -307,12 +307,12 @@
 			return;
 		}
-
+        // Get stream codec
 		IStreamCodecInfo codecInfo = getCodecInfo();
-		StreamCodecInfo streamCodec = null;
+		StreamCodecInfo info = null;
 		if (codecInfo instanceof StreamCodecInfo) {
-			streamCodec = (StreamCodecInfo) codecInfo;
-		}
-
-        IRTMPEvent rtmpEvent = null;
+			info = (StreamCodecInfo) codecInfo;
+		}
+
+        IRTMPEvent rtmpEvent;
         try {
             rtmpEvent = (IRTMPEvent) event;
@@ -321,11 +321,12 @@
             return;
         }
-        int thisTime = -1;
-		if (firstTime == -1) {
-			firstTime = rtmpEvent.getTimestamp();
+        int eventTime = -1;
+        // If this is first packet save it's timestamp
+        if (firstPacketTime == -1) {
+			firstPacketTime = rtmpEvent.getTimestamp();
 		}
 		if (rtmpEvent instanceof AudioData) {
-			if (streamCodec != null) {
-				streamCodec.setHasAudio(true);
+			if (info != null) {
+				info.setHasAudio(true);
 			}
 			if (rtmpEvent.getHeader().isTimerRelative()) {
@@ -334,5 +335,5 @@
 				audioTime = rtmpEvent.getTimestamp();
 			}
-			thisTime = audioTime;
+			eventTime = audioTime;
 		} else if (rtmpEvent instanceof VideoData) {
 			IVideoStreamCodec videoStreamCodec = null;
@@ -353,6 +354,6 @@
 			}
 
-			if (streamCodec != null) {
-				streamCodec.setHasVideo(true);
+			if (info != null) {
+				info.setHasVideo(true);
 			}
 			if (rtmpEvent.getHeader().isTimerRelative()) {
@@ -361,5 +362,5 @@
 				videoTime = rtmpEvent.getTimestamp();
 			}
-			thisTime = videoTime;
+			eventTime = videoTime;
 		} else if(rtmpEvent instanceof Invoke) {
 			if (rtmpEvent.getHeader().isTimerRelative()) {
@@ -375,11 +376,14 @@
 				dataTime = rtmpEvent.getTimestamp();
 			}
-			thisTime = dataTime;
-		}
-		checkSendNotifications(event);
-
-		RTMPMessage msg = new RTMPMessage();
+			eventTime = dataTime;
+		}
+
+        // Notify event listeners
+        checkSendNotifications(event);
+
+        // Create new RTMP message, initialize it and push through pipe
+        RTMPMessage msg = new RTMPMessage();
 		msg.setBody(rtmpEvent);
-		msg.getBody().setTimestamp(thisTime);
+		msg.getBody().setTimestamp(eventTime);
 		if (livePipe != null) {
 			livePipe.pushMessage(msg);
@@ -389,5 +393,5 @@
 
     /**
-     * Check send notification
+     * Check and send notification if necessary
      * @param event          Event
      */
@@ -451,10 +455,10 @@
      */
     private void sendPublishStartNotify() {
-		Status start = new Status(StatusCodes.NS_PUBLISH_START);
-		start.setClientid(getStreamId());
-		start.setDetails(getPublishedName());
+		Status publishStatus = new Status(StatusCodes.NS_PUBLISH_START);
+		publishStatus.setClientid(getStreamId());
+		publishStatus.setDetails(getPublishedName());
 
 		StatusMessage startMsg = new StatusMessage();
-		startMsg.setBody(start);
+		startMsg.setBody(publishStatus);
 		connMsgOut.pushMessage(startMsg);
 	}
@@ -464,10 +468,10 @@
      */
 	private void sendPublishStopNotify() {
-		Status stop = new Status(StatusCodes.NS_UNPUBLISHED_SUCCESS);
-		stop.setClientid(getStreamId());
-		stop.setDetails(getPublishedName());
+		Status stopStatus = new Status(StatusCodes.NS_UNPUBLISHED_SUCCESS);
+		stopStatus.setClientid(getStreamId());
+		stopStatus.setDetails(getPublishedName());
 
 		StatusMessage stopMsg = new StatusMessage();
-		stopMsg.setBody(stop);
+		stopMsg.setBody(stopStatus);
 		connMsgOut.pushMessage(stopMsg);
 	}
@@ -477,10 +481,10 @@
      */
 	private void sendRecordStartNotify() {
-		Status start = new Status(StatusCodes.NS_RECORD_START);
-		start.setClientid(getStreamId());
-		start.setDetails(getPublishedName());
+		Status recordStatus = new Status(StatusCodes.NS_RECORD_START);
+		recordStatus.setClientid(getStreamId());
+		recordStatus.setDetails(getPublishedName());
 
 		StatusMessage startMsg = new StatusMessage();
-		startMsg.setBody(start);
+		startMsg.setBody(recordStatus);
 		connMsgOut.pushMessage(startMsg);
 	}
@@ -490,10 +494,10 @@
      */
 	private void sendRecordStopNotify() {
-		Status start = new Status(StatusCodes.NS_RECORD_STOP);
-		start.setClientid(getStreamId());
-		start.setDetails(getPublishedName());
+		Status stopStatus = new Status(StatusCodes.NS_RECORD_STOP);
+		stopStatus.setClientid(getStreamId());
+		stopStatus.setDetails(getPublishedName());
 
 		StatusMessage startMsg = new StatusMessage();
-		startMsg.setBody(start);
+		startMsg.setBody(stopStatus);
 		connMsgOut.pushMessage(startMsg);
 	}
Index: /java/server/trunk/src/org/red5/server/net/rtmp/RTMPHandler.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/rtmp/RTMPHandler.java (revision 1625)
+++ /java/server/trunk/src/org/red5/server/net/rtmp/RTMPHandler.java (revision 1628)
@@ -170,6 +170,10 @@
 		log.debug("Invoke");
 
-		final IServiceCall call = invoke.getCall();
-		if (call.getServiceMethodName().equals("_result")
+        // Get call
+        final IServiceCall call = invoke.getCall();
+
+        // If it's a callback for server remote call then pass it over to callbacks handler
+        // and return
+        if (call.getServiceMethodName().equals("_result")
 				|| call.getServiceMethodName().equals("_error")) {
 			handlePendingCallResult(conn, invoke);
@@ -185,24 +189,35 @@
 
 		boolean disconnectOnReturn = false;
-		if (call.getServiceName() == null) {
+
+        // If this is not a service call then handle connection...
+        if (call.getServiceName() == null) {
 			log.info("call: " + call);
 			final String action = call.getServiceMethodName();
 			log.info("--" + action);
 			if (!conn.isConnected()) {
-
+                // Handle connection
 				if (action.equals(ACTION_CONNECT)) {
 					log.debug("connect");
-					final Map params = invoke.getConnectionParams();
-					String host = getHostname((String) params.get("tcUrl"));
-					if (host.endsWith(":1935")) {
+
+                    // Get parameters passed from client to NetConnection#connection
+                    final Map params = invoke.getConnectionParams();
+
+                    // Get hostname
+                    String host = getHostname((String) params.get("tcUrl"));
+
+                    // Check up port
+                    if (host.endsWith(":1935")) {
 						// Remove default port from connection string
 						host = host.substring(0, host.length() - 5);
 					}
-					final String path = (String) params.get("app");
+
+                    // App name as path
+                    final String path = (String) params.get("app");
 					final String sessionId = null;
 					conn.setup(host, path, sessionId, params);
 					try {
-						final IGlobalScope global = server.lookupGlobal(host,
-								path);
+                        // Lookup server scope when connected
+                        // Use host and application name
+                        final IGlobalScope global = server.lookupGlobal(host, path);
 						if (global == null) {
 							call.setStatus(Call.STATUS_SERVICE_NOT_FOUND);
@@ -212,6 +227,6 @@
 								((IPendingServiceCall) call).setResult(status);
 							}
-							log.info("No global scope found for " 

Note:
Diffs are chopped if more than 25k.
This is to get past the limit on the mailing list.



More information about the Red5commits mailing list