Archive for the ‘ Red5 Media Server ’ Category

Socket bind exception on Red5 restart

This one is a gem. We’re using Red5 as flash server for several of our projects and one annoying problem that we encountered were thrown exceptions on Red5 restart. Specifically, Address already in use exception which signals that a socket is still being used. The culprit is socket bound to 1935 port which is used for rtmp traffic between flash clients and Red5. That socket remained in TIME_WAIT state even after Red5 was shutdown.

Now, it is important to note that tcp connections should be closed properly in order to avoid this sort of problems, but this is not always possible (unexpected server shutdown, bug which makes server unresponsive, etc.). Brief discussion about proper tcp handling is here. I know from experience that other servers (for example Tomcat) don’t have this problem with socket binding (at least not in the last ~5 years) and I was curious why Red5 developers haven’t solved this. The thing to do to avoid this is to set SO_REUSEADDR flag on the socket. This means that other processes can bind to this socket if it is in TIME_WAIT state. Fortunately, Red5 is open source, so I browsed a bit and found this in RTMPMinaTransport class :

acceptor = new NioSocketAcceptor(ioThreads);
acceptor.setHandler(ioHandler);
acceptor.setBacklog(100);

log.info(“TCP No Delay: {}”, tcpNoDelay);
log.info(“Receive Buffer Size: {}”, receiveBufferSize);
log.info(“Send Buffer Size: {}”, sendBufferSize);

SocketSessionConfig sessionConf = (SocketSessionConfig) acceptor.getSessionConfig();
sessionConf.setReuseAddress(true);
sessionConf.setTcpNoDelay(tcpNoDelay);
sessionConf.setReceiveBufferSize(receiveBufferSize);
sessionConf.setSendBufferSize(sendBufferSize);

Interesting enough, they do set this flag as I’ve shown with the bolded line. So I’ve tried debugging the code and after some time I’ve found out, that SocketSessionConfig is never read, never used. I will repeat this : SocketSessionConfig is never accessed. That part of the code could as well be removed. The solution is simple, flag must be set directly on NioSocketAcceptor and then the socket can be bound on restart without a problem:

acceptor = new NioSocketAcceptor(ioThreads);
acceptor.setHandler(ioHandler);
acceptor.setBacklog(100);
acceptor.setReuseAddress(true);

I’ve added the bolded line and compiled the source. With new red5.jar, restarting works like a charm.

Advertisements

How to create new Red5 0.8 Application on CentOS

In this tutorial we will know how to create a simple Red5 Application. Which you can modify the codes ang also easly change the application.

In addition, you can also learn how red5 works and also how to use shared objects.

Step 1: Go to root directory where you install Red5.

# cd /usr/local/red5

This is the root folder of Red5. Go to your dist folder if you installed the svn version of red5,
if not you can go directly go to your webapps folder.

# cd /usr/local/red5/dist/webapp

Step 2: Creating your new application.

# mkdir -p myapp/WEB-INF

myapp is the name of our new application. The folder WEB-INF is created because this is where you put youre classes and libraries, and this also the folder which the red5 is looking on every applications.

Step 3: Creating files inside WEB-INF.

Go to your new applications WEB-INF

# cd /usr/local/red5/dist/webapps/myapp/WEB-INF

You will need 5 files inside WEB-INF.
Create this files using touch command. (example: # touch web.xml)
Files: web.xml, red5-web.xml, red5-web.properties, log4j.properties, build.xml

a) web.xml: This is the first file that your Jetty/Tomcat Servlet engine will read. The parameter webAppRootKey defines the application context of your application.

<START>
<?xml version=”1.0″ encoding=”ISO-8859-1″?>
<web-app
xmlns=”http://java.sun.com/xml/ns/j2ee&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&#8221;
version=”2.4″>
<display-name>Red 5 JAVA Concepts</display-name>
<context-param>
<param-name>globalScope</param-name>
<param-value>default</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/red5-*.xml</param-value>
</context-param>
<context-param>
<param-name>locatorFactorySelector</param-name>
<param-value>red5.xml</param-value>
</context-param>
<context-param>
<param-name>parentContextKey</param-name>
<param-value>default.context</param-value>
</context-param>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>/myapp</param-value>
</context-param>
<listener>
<listener-class>org.red5.logging.ContextLoggingListener</listener-class>
</listener>
<filter>
<filter-name>LoggerContextFilter</filter-name>
<filter-class>org.red5.logging.LoggerContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoggerContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>Forbidden</web-resource-name>
<url-pattern>/streams/*</url-pattern>
</web-resource-collection>
<auth-constraint/>
</security-constraint>
</web-app>
<END>

b) red5-web.xml: This config file is used to configure and load your scope/context handler, your virtual-host configuration and your very own application.

<START>
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://www.springframework.org/dtd/spring-beans.dtd”&gt;
<beans>
<bean id=”placeholderConfig”>
<property name=”location” value=”/WEB-INF/red5-web.properties” />
</bean>
<bean id=”web.context”
autowire=”byType” />
<bean id=”web.scope”
init-method=”register”>
<property name=”server” ref=”red5.server” />
<property name=”parent” ref=”global.scope” />
<property name=”context” ref=”web.context” />
<property name=”handler” ref=”web.handler” />
<property name=”contextPath” value=”${webapp.contextPath}” />
<property name=”virtualHosts” value=”${webapp.virtualHosts}” />
</bean>
<bean id=”web.handler”
singleton=”true” />
</beans>
<END>

c) red5-web.properties: This file is imported into the red5-web.xml file. Use this file for items that often change within your configuration eg the contextPath (ie name of your application scope) or virtualHosts directives (which might change from one hosted service to another).

<START>
webapp.contextPath=/myapp
webapp.virtualHosts=localhost, 127.0.0.1
<END>

d) log4j.properties: This is used to configure the logging properties of your application by using the log4j libraries.

In your class you will retreive the log by using:
protected static Log log = \
LogFactory.getLog(Application.class.getName());

You can obtain a template of these files from within the red5 server folder by going to doc/templates/myapp/WEB-INF

e) build.xml: This is the file that we will use to compile our application before restarting red5.

<START>
<project name=”myapp” default=”compile” basedir=”.”>
<target name=”clean” description=”Clean output directories”>
</target>
<target name=”compile” depends=”clean”>
<javac srcdir=”./src” destdir=”./classes” source=”1.6″ classpath=”/usr/local/red5/red5.jar” >
</javac>
</target>
<target name = “jar” depends =”compile”>
<echo message =”Creating jar…”/>
<jar destfile=”./lib/myapp.jar” basedir=”./classes”/>
<echo message =”Done.”/>
</target>
</project>
<END>

Step 4: Creating folders inside WEB-INF
You will need 3 folders. /classes for your classes folder, /lib for your libraries and /src for the source.

# mkdir /classes /lib /src

Step 5: Creating the Application.java

Application.java is the source file for your Application.class

Create file named Application.java inside /src

Copy this codes to your Application.java

<START>
package org.red5.server.webapp.myapp;
import org.red5.server.api.*;
import org.red5.server.api.so.ISharedObject;
import java.util.*;
import org.red5.server.adapter.ApplicationAdapter;
public class Application extends ApplicationAdapter {
public boolean appStart(IScope room) {
System.out.println(“Hello World”);
return true;
}
}
<END>

Step 5: Creating MANIFEST.MF
This use for the jar file needed for your new application. Class path is targeted to red5.jar on your red5 root.
See also. About JAR

Create file named MANIFEST.MF inside /src

Copy this codes to your MANIFEST.MF

<START>
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7
Created-By: 1.5.0_06-b05 (Sun Microsystems Inc.)
Class-Path: ../../../../red5.jar
<END>

Step 6: Compiling and Making JAR for you’re new Application.

Go to your WEB-INF folder where build.xml is located.
Compile your Application.java
# ant compile

Make a JAR for your new Application
# ant jar

And Now restart your Red5 Server.
You can see Hello World in the bottom, where your application was launched by Red5.

Congratulations, You have made your new Application.

For more questions and info, feel free to ask.

See also.  how-to-install-red5-version-0-8-on-centos

How To Install RED5 version 0.8 on CENTOS

Step 1: Download and Install Java
RED5 depends on Java, so lets install it using yum.
# yum -y install java-1.6.0-openjdk java-1.6.0-openjdk-devel

Step 2: Download and Install Ant(Apache Project)
Ant will be needed to compile RED5 server code.
# cd /usr/src

Note: Link may be broken or may cause problems because they are always updating the apache ant and changing the filename.
For updated link if link is broken: http://opensource.become.com/apache/ant/
# wget http://opensource.become.com/apache/ant/binaries/apache-ant-1.8.1-bin.tar.gz
# tar zxvf apache-ant-1.8.1-bin.tar.gz
# mv apache-ant-1.8.1/ /usr/local/ant

Step 3: Export Variables for Ant and Java
# export ANT_HOME=/usr/local/ant
# export JAVA_HOME=/usr/lib/jvm/java
# export PATH=$PATH:/usr/local/ant/bin
# export CLASSPATH=.:$JAVA_HOME/lib/classes.zip

Also export these variables in /etc/bashrc to become available for every user login or for any terminal opens.

# echo ‘export ANT_HOME=/usr/local/ant’ >> /etc/bashrc
# echo ‘export JAVA_HOME=/usr/lib/jvm/java’ >> /etc/bashrc
# echo ‘export PATH=$PATH:/usr/local/ant/bin’ >> /etc/bashrc
# echo ‘export CLASSPATH=.:$JAVA_HOME/lib/classes.zip’ >> /etc/bashrc

Step 4: Download and Install RED5 Server
# cd /usr/src
# svn co http://red5.googlecode.com/svn/java/server/tags/0_8_0/ red5
# mv red5 /usr/local/
# cd /usr/local/red5
# ant prepare
# ant dist

you will see lots and lots of lines, but you should get at last

BUILD SUCCESSFUL

that’s mean its install and now copy the conf directory from dist/ and test the red5 installation.

# cp -r dist/conf .
# ./red5.sh

If it shows Installer service created in the last then everything is fine here, press ctrl+c

Step 5: Starting RED5 Server

Now go to the red5 folder:

# cd /usr/local/red5/dist
command to stop red5:
# sh red5-shutdown.sh
or
# killall -9 java

Command to start red5:
# sh red5.sh &

When Red5 is running you should be able to access http://your-server-domain-or-ip:5080/ .

If it works first thing go to http://your-server:5080/installer/and install admin. Then to http://your-server:5080/admin/register.html and register an username and password. Then you can check application statistics anytime from http://your-server:5080/admin/ with server ip and the registered username, password.

RED 5 RESTART

You need to restart every time you add or update files in the /usr/local/red5/dist/webapps folder – where all applications should be installed.

ISSUE:

[INFO] [main] org.red5.server.tomcat.TomcatLoader – RTMPT server bean was not found
[INFO] [main] org.red5.server.tomcat.TomcatLoader – RTMPS server bean was not found

Then RTMPT doesn’t work, It was disabled by default. To enable it, uncomment RTMPT and RTMPS on your conf/red5-core.xml