All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.red5.client.net.rtmp.RTMPMinaIoHandler Maven / Gradle / Ivy

There is a newer version: 2.0.12
Show newest version
/*
 * RED5 Open Source Flash Server - https://github.com/Red5/ Copyright 2006-2015 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.lang.ref.WeakReference;

import org.apache.commons.codec.binary.Hex;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.red5.client.net.rtmpe.RTMPEClient;
import org.red5.client.net.rtmpe.RTMPEIoFilter;
import org.red5.server.BaseConnection;
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.RTMPHandshake;
import org.red5.server.net.rtmp.RTMPMinaConnection;
import org.red5.server.net.rtmp.message.Packet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

/**
 * Handles all RTMP protocol events fired by the MINA framework.
 */
public class RTMPMinaIoHandler extends IoHandlerAdapter {

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

    private boolean enableSwfVerification;

    /**
     * RTMP events handler
     */
    protected BaseRTMPClientHandler handler;

    /** {@inheritDoc} */
    @Override
    public void sessionCreated(IoSession session) throws Exception {
        log.debug("Session created");
        // add rtmpe filter, rtmp protocol filter is added upon successful handshake
        session.getFilterChain().addFirst("rtmpeFilter", new RTMPEIoFilter());
        // create a connection
        RTMPMinaConnection conn = createRTMPMinaConnection();
        // set the session on the connection
        conn.setIoSession(session);
        // add the connection
        session.setAttribute(RTMPConnection.RTMP_SESSION_ID, conn.getSessionId());
        // create an outbound handshake, defaults to non-encrypted mode
        OutboundHandshake outgoingHandshake = new OutboundHandshake();
        // add the handshake
        session.setAttribute(RTMPConnection.RTMP_HANDSHAKE, outgoingHandshake);
        // setup swf verification
        if (enableSwfVerification) {
            String swfUrl = (String) handler.getConnectionParams().get("swfUrl");
            log.debug("SwfUrl: {}", swfUrl);
            if (!StringUtils.hasText(swfUrl)) {
                outgoingHandshake.initSwfVerification(swfUrl);
            }
        }
        // if handler is rtmpe client set encryption on the protocol state
        if (handler instanceof RTMPEClient) {
            // set encrypted flag on the state
            conn.getState().setEncrypted(true);
            // set the handshake type to encrypted as well
            outgoingHandshake.setHandshakeType(RTMPConnection.RTMP_ENCRYPTED);
        }
        // set a reference to the handler on the sesssion
        session.setAttribute(RTMPConnection.RTMP_HANDLER, handler);
        // set a reference to the connection on the client
        handler.setConnection((RTMPConnection) conn);
        // set a connection manager for any required handling and to prevent memory leaking
        session.setAttribute(RTMPConnection.RTMP_CONN_MANAGER, new WeakReference>(RTMPClientConnManager.getInstance()));
    }

    /** {@inheritDoc} */
    @Override
    public void sessionOpened(IoSession session) throws Exception {
        log.debug("Session opened");
        super.sessionOpened(session);
        // get the handshake from the session
        RTMPHandshake handshake = (RTMPHandshake) session.getAttribute(RTMPConnection.RTMP_HANDSHAKE);
        // create and send C0+C1
        IoBuffer clientRequest1 = ((OutboundHandshake) handshake).generateClientRequest1();
        session.write(clientRequest1);
    }

    /** {@inheritDoc} */
    @Override
    public void sessionClosed(IoSession session) throws Exception {
        log.debug("Session closed");
        String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
        if (sessionId != null) {
            log.trace("Session id: {}", sessionId);
            RTMPMinaConnection conn = (RTMPMinaConnection) getConnectionManager(session).getConnectionBySessionId(sessionId);
            if (conn != null) {
                conn.sendPendingServiceCallsCloseError();
                // fire-off closed event
                handler.connectionClosed(conn);
                // clear any session attributes we may have previously set
                session.removeAttribute(RTMPConnection.RTMP_HANDLER);
                session.removeAttribute(RTMPConnection.RTMP_HANDSHAKE);
                session.removeAttribute(RTMPConnection.RTMPE_CIPHER_IN);
                session.removeAttribute(RTMPConnection.RTMPE_CIPHER_OUT);
            } else {
                log.warn("Connection was null in session");
            }
        } else {
            log.debug("Connections session id was null in session, may already be closed");
        }
    }

    /** {@inheritDoc} */
    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        log.debug("messageReceived");
        if (message instanceof Packet && message != null) {
            String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
            log.trace("Session id: {}", sessionId);
            RTMPMinaConnection conn = (RTMPMinaConnection) getConnectionManager(session).getConnectionBySessionId(sessionId);
            Red5.setConnectionLocal(conn);
            conn.handleMessageReceived((Packet) message);
            Red5.setConnectionLocal(null);
        } else {
            log.debug("Not packet type: {}", message);
        }
    }

    /** {@inheritDoc} */
    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        log.debug("messageSent");
        if (message instanceof Packet) {
            String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
            log.trace("Session id: {}", sessionId);
            RTMPMinaConnection conn = (RTMPMinaConnection) getConnectionManager(session).getConnectionBySessionId(sessionId);
            handler.messageSent(conn, (Packet) message);
        } else {
            log.trace("messageSent: {}", Hex.encodeHexString(((IoBuffer) message).array()));
        }
    }

    /** {@inheritDoc} */
    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        log.warn("Exception caught {}", cause.getMessage());
        if (log.isDebugEnabled()) {
            log.error("Exception detail", cause);
        }
    }

    /**
     * Setter for handler.
     *
     * @param handler RTMP events handler
     */
    public void setHandler(BaseRTMPClientHandler handler) {
        log.debug("Set handler: {}", handler);
        this.handler = handler;
    }

    /**
     * Setter to enable swf verification in the handshake.
     *
     * @param enableSwfVerification to enable SWF verification or not
     */
    public void setEnableSwfVerification(boolean enableSwfVerification) {
        this.enableSwfVerification = enableSwfVerification;
    }

    protected RTMPMinaConnection createRTMPMinaConnection() {
        return (RTMPMinaConnection) RTMPClientConnManager.getInstance().createConnection(RTMPMinaConnection.class);
    }

    @SuppressWarnings("unchecked")
    private IConnectionManager getConnectionManager(IoSession session) {
        return (IConnectionManager) ((WeakReference>) session.getAttribute(RTMPConnection.RTMP_CONN_MANAGER)).get();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy