/** {@inheritDoc} */ public void execute(ISchedulingService service) { // ensure the job is not already running if (running.compareAndSet(false, true)) { // get now long now = System.currentTimeMillis(); // get the current bytes read count on the connection long currentReadBytes = getReadBytes(); // get our last bytes read count long previousReadBytes = lastBytesRead.get(); log.debug( "Time now: {} current read count: {} last read count: {}", new Object[] {now, currentReadBytes, previousReadBytes}); if (currentReadBytes > previousReadBytes) { log.debug("Client is still alive, no ping needed"); // client has sent data since last check and thus is not dead. No need to ping if (lastBytesRead.compareAndSet(previousReadBytes, currentReadBytes)) { // update the timestamp to match our update lastBytesReadTime = now; } } else { // client didn't send response to ping command and didn't sent data for too long, // disconnect long lastPingTime = lastPingSent.get(); long lastPongTime = lastPongReceived.get(); if (lastPongTime > 0 && (lastPingTime - lastPongTime > maxInactivity) && !(now - lastBytesReadTime < maxInactivity)) { log.debug("Keep alive job name {}", keepAliveJobName); if (log.isTraceEnabled()) { log.trace("Scheduled job list"); for (String jobName : service.getScheduledJobNames()) { log.trace("Job: {}", jobName); } } service.removeScheduledJob(keepAliveJobName); keepAliveJobName = null; log.warn( "Closing {}, with id {}, due to too much inactivity ({} ms), last ping sent {} ms ago", new Object[] { RTMPConnection.this, getId(), (lastPingTime - lastPongTime), (now - lastPingTime) }); // Add the following line to (hopefully) deal with a very common support request // on the Red5 list log.warn( "This often happens if YOUR Red5 application generated an exception on start-up. Check earlier in the log for that exception first!"); onInactive(); } // send ping command to client to trigger sending of data ping(); } // reset running flag running.compareAndSet(true, false); } }
public void init() { if (schedulingService != null) { // set to run once per hour schedulingService.addScheduledJob(3600000, new ReaperJob()); } else { log.warn("Session reaper job was not scheduled"); } }
/** {@inheritDoc} */ public void execute(ISchedulingService service) { long thisRead = getReadBytes(); long previousReadBytes = lastBytesRead.get(); if (thisRead > previousReadBytes) { // Client sent data since last check and thus is not dead. No // need to ping. if (lastBytesRead.compareAndSet(previousReadBytes, thisRead)) lastBytesReadTime = System.currentTimeMillis(); return; } // Client didn't send response to ping command // and didn't sent data for too long, disconnect if (lastPongReceived.get() > 0 && (lastPingSent.get() - lastPongReceived.get() > maxInactivity) && !(System.currentTimeMillis() - lastBytesReadTime < maxInactivity)) { getWriteLock().lock(); try { log.debug("Keep alive job name {}", keepAliveJobName); if (log.isDebugEnabled()) { log.debug("Scheduled job list"); for (String jobName : service.getScheduledJobNames()) { log.debug("Job: {}", jobName); } } service.removeScheduledJob(keepAliveJobName); keepAliveJobName = null; } finally { getWriteLock().unlock(); } log.warn( "Closing {}, with id {}, due to too much inactivity ({}ms), " + "last ping sent {}ms ago", new Object[] { RTMPConnection.this, getId(), (lastPingSent.get() - lastPongReceived.get()), (System.currentTimeMillis() - lastPingSent.get()) }); onInactive(); return; } // Send ping command to client to trigger sending of data. ping(); }
/** * Start waiting for a valid handshake. * * @param service The scheduling service to use */ protected void startWaitForHandshake(ISchedulingService service) { getWriteLock().lock(); try { waitForHandshakeService = service; waitForHandshakeJob = service.addScheduledOnceJob(maxHandshakeTimeout, new WaitForHandshakeJob()); } finally { getWriteLock().unlock(); } }
private void unscheduleWaitForHandshakeJob() { getWriteLock().lock(); try { if (waitForHandshakeJob != null) { schedulingService.removeScheduledJob(waitForHandshakeJob); waitForHandshakeJob = null; log.debug("Removed waitForHandshakeJob for: {}", getId()); } } finally { getWriteLock().unlock(); } }
/** Stop this server-side stream */ public void stop() { if (state == StreamState.PLAYING || state == StreamState.PAUSED) { if (liveJobName != null) { scheduler.removeScheduledJob(liveJobName); liveJobName = null; } if (vodJobName != null) { scheduler.removeScheduledJob(vodJobName); vodJobName = null; } if (msgIn != null) { msgIn.unsubscribe(this); msgIn = null; } if (nextRTMPMessage != null) { nextRTMPMessage.getBody().release(); } stopRecording(); setState(StreamState.STOPPED); } }
/** * Pull the next message from IMessageInput and schedule it for push according to the timestamp. */ protected void scheduleNextMessage() { boolean first = (nextRTMPMessage == null); long delta = 0L; do { nextRTMPMessage = getNextRTMPMessage(); if (nextRTMPMessage != null) { IRTMPEvent rtmpEvent = nextRTMPMessage.getBody(); // filter all non-AV messages if (rtmpEvent instanceof VideoData || rtmpEvent instanceof AudioData) { rtmpEvent = nextRTMPMessage.getBody(); nextTS = rtmpEvent.getTimestamp(); if (first) { vodStartTS = nextTS; first = false; } delta = nextTS - vodStartTS - (System.currentTimeMillis() - serverStartTS); if (delta < WAIT_THRESHOLD) { if (doPushMessage()) { if (state != StreamState.PLAYING) { // Stream is not playing, don't load more messages nextRTMPMessage = null; } } else { nextRTMPMessage = null; } } } } else { onItemEnd(); } } while (nextRTMPMessage != null || delta < WAIT_THRESHOLD); // start the job all over again vodJobName = scheduler.addScheduledOnceJob( delta, new IScheduledJob() { public void execute(ISchedulingService service) { if (vodJobName != null) { vodJobName = null; if (doPushMessage()) { if (state == StreamState.PLAYING) { scheduleNextMessage(); } else { // Stream is paused, don't load more messages nextRTMPMessage = null; } } } } }); }
public void init() { // create the job and schedule it jobName = scheduler.addScheduledJobAfterDelay(checkInterval, new DeployJob(), 20000); // log.debug("Source directory: {}", deploymentDirectory); // check the deploy from directory File dir = new File(deploymentDirectory); if (!dir.exists()) { log.warn("Source directory not found"); } else { if (!dir.isDirectory()) { log.warn("Source directory is not a directory"); } } dir = null; }
/** * Play a specific IPlayItem. The strategy for now is VOD first, Live second. * * @param item Item to play */ protected void play(IPlayItem item) { // dont play unless we are stopped if (state == StreamState.STOPPED) { // assume this is not live stream boolean isLive = false; if (providerService != null) { msgIn = providerService.getVODProviderInput(getScope(), item.getName()); if (msgIn == null) { msgIn = providerService.getLiveProviderInput(getScope(), item.getName(), true); isLive = true; } if (msgIn == null) { log.warn("ABNORMAL Can't get both VOD and Live input from providerService"); return; } } setState(StreamState.PLAYING); currentItem = item; sendResetMessage(); if (msgIn != null) { msgIn.subscribe(this, null); } if (isLive) { if (item.getLength() >= 0) { liveJobName = scheduler.addScheduledOnceJob( item.getLength(), new IScheduledJob() { public void execute(ISchedulingService service) { if (liveJobName == null) { return; } liveJobName = null; onItemEnd(); } }); } } else { long start = item.getStart(); if (start < 0) { start = 0; } sendVODInitCM(msgIn, (int) start); startBroadcastVOD(); } } }
/** Starts measurement. */ public void startRoundTripMeasurement() { if (pingInterval <= 0) { // Ghost detection code disabled return; } getWriteLock().lock(); try { if (keepAliveJobName == null) { // log.debug("Scope null = {}", (scope == null)); // log.debug("getScope null = {}", (getScope() == null)); // log.debug("Context null = {}", (scope.getContext() == null)); // ISchedulingService schedulingService = (ISchedulingService) // scope.getContext().getBean(ISchedulingService.BEAN_NAME); keepAliveJobName = schedulingService.addScheduledJob(pingInterval, new KeepAliveJob()); } log.debug("Keep alive job name {} for client id {}", keepAliveJobName, getId()); } finally { getWriteLock().unlock(); } }
/** {@inheritDoc} */ @Override public void close() { getWriteLock().lock(); try { if (keepAliveJobName != null) { schedulingService.removeScheduledJob(keepAliveJobName); keepAliveJobName = null; } } finally { getWriteLock().unlock(); } Red5.setConnectionLocal(this); IStreamService streamService = (IStreamService) getScopeService(scope, IStreamService.class, StreamService.class); if (streamService != null) { for (Map.Entry<Integer, IClientStream> entry : streams.entrySet()) { IClientStream stream = entry.getValue(); if (stream != null) { log.debug("Closing stream: {}", stream.getStreamId()); streamService.deleteStream(this, stream.getStreamId()); usedStreams.decrementAndGet(); } } streams.clear(); } channels.clear(); getWriteLock().lock(); try { if (bwContext != null && getScope() != null && getScope().getContext() != null) { IBWControlService bwController = (IBWControlService) getScope().getContext().getBean(IBWControlService.KEY); bwController.unregisterBWControllable(bwContext); bwContext = null; } } finally { getWriteLock().unlock(); } super.close(); }
/** Starts measurement. */ public void startRoundTripMeasurement() { if (pingInterval > 0 && keepAliveJobName == null) { keepAliveJobName = schedulingService.addScheduledJob(pingInterval, new KeepAliveJob()); log.debug("Keep alive job name {} for client id {}", keepAliveJobName, getId()); } }
/** {@inheritDoc} */ @Override public void close() { getWriteLock().lock(); try { if (keepAliveJobName != null) { schedulingService.removeScheduledJob(keepAliveJobName); keepAliveJobName = null; } } finally { getWriteLock().unlock(); } Red5.setConnectionLocal(this); IStreamService streamService = (IStreamService) getScopeService(scope, IStreamService.class, StreamService.class); if (streamService != null) { for (Map.Entry<Integer, IClientStream> entry : streams.entrySet()) { IClientStream stream = entry.getValue(); if (stream != null) { log.debug("Closing stream: {}", stream.getStreamId()); streamService.deleteStream(this, stream.getStreamId()); usedStreams.decrementAndGet(); } } } // close the base connection - disconnect scopes and unregister client super.close(); // kill all the collections etc if (channels != null) { channels.clear(); channels = null; } else { log.trace("Channels collection was null"); } if (streams != null) { streams.clear(); streams = null; } else { log.trace("Streams collection was null"); } if (pendingCalls != null) { pendingCalls.clear(); pendingCalls = null; } else { log.trace("PendingCalls collection was null"); } if (deferredResults != null) { deferredResults.clear(); deferredResults = null; } else { log.trace("DeferredResults collection was null"); } if (pendingVideos != null) { pendingVideos.clear(); pendingVideos = null; } else { log.trace("PendingVideos collection was null"); } if (streamBuffers != null) { streamBuffers.clear(); streamBuffers = null; } else { log.trace("StreamBuffers collection was null"); } }
/** * Start waiting for a valid handshake. * * @param service The scheduling service to use */ protected void startWaitForHandshake(ISchedulingService service) { waitForHandshakeJob = service.addScheduledOnceJob(maxHandshakeTimeout, new WaitForHandshakeJob()); }
public void shutdown() { scheduler.removeScheduledJob(jobName); }