org.red5.client.net.rtmp.RTMPConnManager.java Source code

Java tutorial

Introduction

Here is the source code for org.red5.client.net.rtmp.RTMPConnManager.java

Source

/*
 * RED5 Open Source Flash Server - https://github.com/Red5/
 * 
 * Copyright 2006-2013 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.client.net.rtmp;

import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;

import org.red5.client.net.rtmpt.RTMPTClientConnection;
import org.red5.server.api.Red5;
import org.red5.server.net.IConnectionManager;
import org.red5.server.net.rtmp.RTMPConnection;
import org.red5.server.net.rtmp.RTMPMinaConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * Responsible for management and creation of RTMP based connections.
 * 
 * @author The Red5 Project
 */
public class RTMPConnManager implements IConnectionManager<RTMPConnection> {

    private static final Logger log = LoggerFactory.getLogger(RTMPConnManager.class);

    private static int maxHandshakeTimeout = 7000;

    private static int maxInactivity = 60000;

    private static int pingInterval = 0;

    private static int executorQueueCapacity = 32;

    protected static IConnectionManager<RTMPConnection> instance = new RTMPConnManager();

    protected ConcurrentMap<String, RTMPConnection> connMap = new ConcurrentHashMap<String, RTMPConnection>();

    protected AtomicInteger conns = new AtomicInteger();

    public static IConnectionManager<RTMPConnection> getInstance() {
        return instance;
    }

    /** {@inheritDoc} */
    @Override
    public RTMPConnection createConnection(Class<?> connCls) {
        RTMPConnection conn = null;
        if (RTMPConnection.class.isAssignableFrom(connCls)) {
            try {
                // create connection
                conn = createConnectionInstance(connCls);
                // add to local map
                connMap.put(conn.getSessionId(), conn);
                log.trace("Connections: {}", conns.incrementAndGet());
                log.trace("Connection created: {}", conn);
            } catch (Exception ex) {
                log.warn("Exception creating connection", ex);
            }
        }
        return conn;
    }

    /** {@inheritDoc} */
    @Override
    public RTMPConnection createConnection(Class<?> connCls, String sessionId) {
        RTMPConnection conn = null;
        if (RTMPConnection.class.isAssignableFrom(connCls)) {
            try {
                // create connection
                conn = createConnectionInstance(connCls);
                // set the session id
                if (conn instanceof RTMPTClientConnection) {
                    ((RTMPTClientConnection) conn).setSessionId(sessionId);
                }
                // add to local map
                connMap.put(conn.getSessionId(), conn);
                log.trace("Connections: {}", conns.incrementAndGet());
                log.trace("Connection created: {}", conn);
            } catch (Exception ex) {
                log.warn("Exception creating connection", ex);
            }
        }
        return conn;
    }

    /**
     * Adds a connection.
     * 
     * @param conn
     */
    @Override
    public void setConnection(RTMPConnection conn) {
        log.trace("Adding connection: {}", conn);
        int id = conn.getId();
        if (id == -1) {
            log.debug("Connection has unsupported id, using session id hash");
            id = conn.getSessionId().hashCode();
        }
        log.debug("Connection id: {} session id hash: {}", conn.getId(), conn.getSessionId().hashCode());
    }

    /**
     * Returns a connection for a given client id.
     * 
     * @param clientId
     * @return connection if found and null otherwise
     */
    @Override
    public RTMPConnection getConnection(int clientId) {
        log.trace("Getting connection by client id: {}", clientId);
        for (RTMPConnection conn : connMap.values()) {
            if (conn.getId() == clientId) {
                return connMap.get(conn.getSessionId());
            }
        }
        return null;
    }

    /**
     * Returns a connection for a given session id.
     * 
     * @param sessionId
     * @return connection if found and null otherwise
     */
    @Override
    public RTMPConnection getConnectionBySessionId(String sessionId) {
        log.debug("Getting connection by session id: {}", sessionId);
        if (connMap.containsKey(sessionId)) {
            return connMap.get(sessionId);
        } else {
            log.warn("Connection not found for {}", sessionId);
            if (log.isTraceEnabled()) {
                log.trace("Connections ({}) {}", connMap.size(), connMap.values());
            }
        }
        return null;
    }

    /** {@inheritDoc} */
    @Override
    public RTMPConnection removeConnection(int clientId) {
        log.trace("Removing connection with id: {}", clientId);
        // remove from map
        for (RTMPConnection conn : connMap.values()) {
            if (conn.getId() == clientId) {
                // remove the conn
                return removeConnection(conn.getSessionId());
            }
        }
        log.warn("Connection was not removed by id: {}", clientId);
        return null;
    }

    /** {@inheritDoc} */
    @Override
    public RTMPConnection removeConnection(String sessionId) {
        log.debug("Removing connection with session id: {}", sessionId);
        if (log.isTraceEnabled()) {
            log.trace("Connections ({}) at pre-remove: {}", connMap.size(), connMap.values());
        }
        // remove from map
        RTMPConnection conn = connMap.remove(sessionId);
        if (conn != null) {
            log.trace("Connections: {}", conns.decrementAndGet());
            Red5.setConnectionLocal(null);
        }
        return conn;
    }

    /** {@inheritDoc} */
    @Override
    public Collection<RTMPConnection> getAllConnections() {
        ArrayList<RTMPConnection> list = new ArrayList<RTMPConnection>(connMap.size());
        list.addAll(connMap.values());
        return list;
    }

    /** {@inheritDoc} */
    @Override
    public Collection<RTMPConnection> removeConnections() {
        ArrayList<RTMPConnection> list = new ArrayList<RTMPConnection>(connMap.size());
        list.addAll(connMap.values());
        connMap.clear();
        conns.set(0);
        return list;
    }

    /**
     * Creates a connection instance based on the supplied type.
     * 
     * @param cls
     * @return connection
     * @throws Exception
     */
    public RTMPConnection createConnectionInstance(Class<?> cls) throws Exception {
        RTMPConnection conn = null;
        if (cls == RTMPMinaConnection.class) {
            conn = (RTMPMinaConnection) cls.newInstance();
        } else if (cls == RTMPTClientConnection.class) {
            conn = (RTMPTClientConnection) cls.newInstance();
        } else {
            conn = (RTMPConnection) cls.newInstance();
        }
        conn.setMaxHandshakeTimeout(maxHandshakeTimeout);
        conn.setMaxInactivity(maxInactivity);
        conn.setPingInterval(pingInterval);
        // setup executor
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setDaemon(true);
        executor.setMaxPoolSize(1);
        executor.setQueueCapacity(executorQueueCapacity);
        executor.initialize();
        conn.setExecutor(executor);
        return conn;
    }

    public static void setMaxHandshakeTimeout(int maxHandshakeTimeout) {
        RTMPConnManager.maxHandshakeTimeout = maxHandshakeTimeout;
    }

    public static void setMaxInactivity(int maxInactivity) {
        RTMPConnManager.maxInactivity = maxInactivity;
    }

    public static void setPingInterval(int pingInterval) {
        RTMPConnManager.pingInterval = pingInterval;
    }

    public static void setExecutorQueueCapacity(int executorQueueCapacity) {
        RTMPConnManager.executorQueueCapacity = executorQueueCapacity;
    }

}