package org.red5.server.net.rtmpt;
/*
* RED5 Open Source Flash Server - http://www.osflash.org/red5
*
* Copyright (c) 2006-2009 by respective authors (see below). All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any later
* version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import javax.servlet.http.HttpServletRequest;
import org.apache.mina.common.ByteBuffer;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.net.rtmp.codec.RTMP;
import org.red5.server.net.servlet.ServletUtils;
import org.slf4j.Logger;
/**
* A RTMPT client / session.
*
* @author The Red5 Project (red5@osflash.org)
* @author Joachim Bauch (jojo@struktur.de)
*/
public class RTMPTConnection extends BaseRTMPTConnection {
private static final Logger log = Red5LoggerFactory
.getLogger(RTMPTConnection.class);
/**
* Start to increase the polling delay after this many empty results
*/
private static final long INCREASE_POLLING_DELAY_COUNT = 10;
/**
* Polling delay to start with.
*/
private static final byte INITIAL_POLLING_DELAY = 0;
/**
* Maximum polling delay.
*/
private static final byte MAX_POLLING_DELAY = 32;
/**
* Polling delay value
*/
private byte pollingDelay = INITIAL_POLLING_DELAY;
/**
* Empty result counter, after reaching INCREASE_POLLING_DELAY_COUNT polling
* delay will increase
*/
private long noPendingMessages;
/**
* Servlet that created this connection.
*/
private volatile RTMPTServlet servlet;
/** Constructs a new RTMPTConnection. */
RTMPTConnection() {
super(POLLING);
this.state = new RTMP(RTMP.MODE_SERVER);
clientId = hashCode();
}
/**
* Set the servlet that created the connection.
*
* @param servlet
*/
protected void setServlet(RTMPTServlet servlet) {
this.servlet = servlet;
}
/** {@inheritDoc} */
public void realClose() {
super.realClose();
if (servlet != null) {
servlet.notifyClosed(this);
servlet = null;
}
}
/** {@inheritDoc} */
@Override
protected void onInactive() {
log.debug("Inactive connection id: {}, closing", getId());
close();
realClose();
}
/**
* Setter for servlet request.
*
* @param request Servlet request
*/
public void setServletRequest(HttpServletRequest request) {
host = request.getLocalName();
remoteAddress = request.getRemoteAddr();
remoteAddresses = ServletUtils.getRemoteAddresses(request);
remotePort = request.getRemotePort();
}
/**
* Return the polling delay to use.
*
* @return the polling delay
*/
public byte getPollingDelay() {
getReadLock().lock();
try {
if (state.getState() == RTMP.STATE_DISCONNECTED) {
// Special value to notify client about a closed connection.
return (byte) 0;
}
return (byte) (this.pollingDelay + 1);
} finally {
getReadLock().unlock();
}
}
/**
* {@inheritDoc}
*/
public ByteBuffer getPendingMessages(int targetSize) {
getWriteLock().lock();
try {
long currentPendingMessages = getPendingMessages();
if (currentPendingMessages == 0) {
this.noPendingMessages += 1;
if (this.noPendingMessages > INCREASE_POLLING_DELAY_COUNT) {
if (this.pollingDelay == 0) {
this.pollingDelay = 1;
}
this.pollingDelay = (byte) (this.pollingDelay * 2);
if (this.pollingDelay > MAX_POLLING_DELAY) {
this.pollingDelay = MAX_POLLING_DELAY;
}
}
return null;
}
log.debug("Going to return {} messages to client.", currentPendingMessages);
this.noPendingMessages = 0;
this.pollingDelay = INITIAL_POLLING_DELAY;
} finally {
getWriteLock().unlock();
}
return foldPendingMessages(targetSize);
}
}