package org.red5.server.net.rtmp; /* * 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 java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.ArrayList; import java.util.Collections; import javax.management.ObjectName; import org.apache.mina.common.ByteBuffer; import org.apache.mina.common.IoSession; import org.red5.server.api.IScope; import org.red5.server.jmx.JMXAgent; import org.red5.server.jmx.JMXFactory; import org.red5.server.net.rtmp.message.Packet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class RTMPMinaConnection extends RTMPConnection implements RTMPMinaConnectionMBean { /** * Logger */ protected static Logger log = LoggerFactory.getLogger(RTMPMinaConnection.class); /** * MINA I/O session, connection between two endpoints */ private volatile IoSession ioSession; /** * MBean object name used for de/registration purposes. */ private volatile ObjectName oName; { log.info("RTMPMinaConnection created"); } /** Constructs a new RTMPMinaConnection. */ public RTMPMinaConnection() { super(PERSISTENT); } /** {@inheritDoc} */ @Override public void close() { super.close(); if (ioSession != null) { ioSession.close(); } // Deregister with JMX try { JMXAgent.unregisterMBean(oName); } catch (Exception e) { //sometimes the client isnt registered in jmx } } @Override public boolean connect(IScope newScope, Object[] params) { boolean success = super.connect(newScope, params); if (!success) { return false; } String hostStr = host; int port = 1935; if (host != null && host.indexOf(":") > -1) { String[] arr = host.split(":"); hostStr = arr[0]; port = Integer.parseInt(arr[1]); } try { //if the client is null for some reason, skip the jmx registration if (client != null) { String cName = this.getClass().getName(); if (cName.indexOf('.') != -1) { cName = cName.substring(cName.lastIndexOf('.')).replaceFirst( "[\\.]", ""); } // Create a new mbean for this instance oName = JMXFactory.createObjectName("type", cName, "connectionType", type, "host", hostStr, "port", port + "", "clientId", client.getId()); JMXAgent.registerMBean(this, this.getClass().getName(), RTMPMinaConnectionMBean.class, oName); } else { log.warn("Client was null"); } } catch (Exception e) { log.warn("Exception registering mbean", e); } return success; } /** * Return MINA I/O session. * * @return MINA O/I session, connection between two endpoints */ public IoSession getIoSession() { return ioSession; } /** {@inheritDoc} */ @Override public long getPendingMessages() { if (ioSession == null) { return 0; } return ioSession.getScheduledWriteRequests(); } /** {@inheritDoc} */ @Override public long getReadBytes() { if (ioSession == null) { return 0; } // TODO: half-measure, writing to readBytes isn't synchronised in mina synchronized (ioSession) { return ioSession.getReadBytes(); } } /** {@inheritDoc} */ @Override public long getWrittenBytes() { if (ioSession == null) { return 0; } // TODO: half-measure, writing to writtenBytes isn't synchronised in mina synchronized (ioSession) { return ioSession.getWrittenBytes(); } } public void invokeMethod(String method) { invoke(method); } /** {@inheritDoc} */ @Override public boolean isConnected() { return super.isConnected() && (ioSession != null) && ioSession.isConnected(); } /** {@inheritDoc} */ @Override protected void onInactive() { this.close(); } /** {@inheritDoc} */ @Override public void rawWrite(ByteBuffer out) { if (ioSession != null) { ioSession.write(out); } } /** * Setter for MINA I/O session (connection). * * @param protocolSession Protocol session */ public void setIoSession(IoSession protocolSession) { SocketAddress remote = protocolSession.getRemoteAddress(); if (remote instanceof InetSocketAddress) { remoteAddress = ((InetSocketAddress) remote).getAddress() .getHostAddress(); remotePort = ((InetSocketAddress) remote).getPort(); } else { remoteAddress = remote.toString(); remotePort = -1; } remoteAddresses = new ArrayList<String>(); remoteAddresses.add(remoteAddress); remoteAddresses = Collections.unmodifiableList(remoteAddresses); this.ioSession = protocolSession; } /** {@inheritDoc} */ @Override public void write(Packet out) { if (ioSession != null) { writingMessage(out); ioSession.write(out); } } }