/*
* RED5 Open Source Flash Server - http://code.google.com/p/red5/
*
* Copyright 2006-2012 by respective authors (see below). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.red5.server.net.rtmpt;
import javax.servlet.http.HttpServletRequest;
import org.apache.mina.core.buffer.IoBuffer;
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);
state = new RTMP();
clientId = getNextClientId();
}
/**
* 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();
// Check if the request came in from the default port.
// We strip default ports so don't include it in the host.
if (request.getLocalPort() != 80) {
host += ":" + request.getLocalPort();
}
remoteAddress = request.getRemoteAddr();
remoteAddresses = ServletUtils.getRemoteAddresses(request);
remotePort = request.getRemotePort();
}
/**
* Return the polling delay to use.
*
* @return the polling delay
*/
public byte getPollingDelay() {
log.trace("getPollingDelay {}", pollingDelay);
if (state.getState() == RTMP.STATE_DISCONNECTED) {
// Special value to notify client about a closed connection.
return (byte) 0;
}
return (byte) (pollingDelay + 1);
}
/**
* {@inheritDoc}
*/
public IoBuffer getPendingMessages(int targetSize) {
long currentPendingMessages = getPendingMessages();
if (currentPendingMessages == 0) {
noPendingMessages += 1;
if (noPendingMessages > INCREASE_POLLING_DELAY_COUNT) {
if (pollingDelay == 0) {
pollingDelay = 1;
}
pollingDelay = (byte) (pollingDelay * 2);
if (pollingDelay > MAX_POLLING_DELAY) {
pollingDelay = MAX_POLLING_DELAY;
}
}
return null;
}
log.debug("Returning {} messages to client", currentPendingMessages);
noPendingMessages = 0;
pollingDelay = INITIAL_POLLING_DELAY;
return foldPendingMessages(targetSize);
}
}