Author Archive

This is a Test Post

Casa Ni Leah

Hello World Blog

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.

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

Common Linux Command

Linux / Unix command

ls command in linux (ls) – to view content
ls -l -> view all details of folders content
ls -lh -> view all details of folders content with readable filesize
ls -l /etc -> view all details of /etc’s content
ls -lt -> view all details of folders content based on time modified

Top command in linux (top) – display top CPU processes
top -c -> display top CPU processes with detailed command
top -H -> display all threads
See http://linux.about.com/od/commands/l/blcmdl1_top.htm

Moving Files (mv)
mv file.txt /folder -> move file to new location
mv file.txt ../ -> move file back one directory

Copying Files (cp)
cp file.txt /folder -> copy file.txt to a folder
cp folder1/file1.txt folder2/file2.txt -> copy file1.txt as file2.txt
cp *.txt /folder -> copy all .txt extension to a folder
cp * /folder ->copy all file to a folder
cp -a /folder /newfolder ->copy a folder and content to a new folder

Remove or Delete Files (rm & rmdir)
rm file.txt -> remove a file
rm -r /folder -> remove a folder and all its content (recursive)
rm -rf /folder -> force remove a folder and all its content (recursive and force)
rmdir /folder -> remove a folder

Making a Directory (mkdir)
mkdir folder -> create a folder

Transfer files to server (scp)
Warning: Be careful when copying between hosts files that have the same names. You may accidentaly overwrite them.
scp file1.txt user@userhost.com:location -> copy file1.txt to user@userhost.com:location
scp -r user@userhost:location /folder -> copy all content of user@userhost:location to a folder (recursive)
scp user1@userhost1:file1.txt user2@userhost2:location -> copy userhost1 file1.txt to userhost2’s location

Zip Files using zip (zip)
zip file.zip file1 file2 file3 -> zipping file1,file2 and file3 to file.zip
zip -r file.zip /folder -> zip folder to file.zip (recursive)
unzip file.zip -> unzip your zip file called file.zip

Using tar
tar cvf name_of_your_archive.tar folder/ -> tar folder/
tar xf name_of_your_archive.tar -> Extracting tar file
tar -pczf name_of_your_archive.tar.gz /path/to/directory -> compress /path/to/directory to name_of_your_archive.tar.gz
tar -xzf name_of_your_archive.tar.gz -> Extracting name_of_your_archive.tar.gz

Change owner and change group of a file (chown & chgrp)
chown owner file -> change owner of a file
chgrp group file -> change group of a file
chown owner:group file -> change owner and group of a file
chown -R owner /folder -> change owner of the folder and its sub folder (recursive)
chgrp -R group /folder -> change group of the folder and its sub folder (recursive)
chown -R owner:group /folder -> change owner and group of the folder and its sub folder (recursive)

Changes the permission of a file (chmod)
chmod 644 file -> change permission to file
chmod -R 644 /folder -> change permission to folder and its content
See http://www.suite101.com/content/linux-commands-changing-permissions-with-chmod-a82401

Searching files (locate)
locate file -> locate file globally
locate file /folder -> locate file from folder

Searching Process (ps)
ps aux | grep java -> show all process called java
ps auxwww -> show all process and its details

Size of folder(du)
du -hs /path/to/directory -> Show total size of the folder

Linking folder(ln)
ln -s /path/to/directory -> Linking to another folder w/o copying them

More about linux see http://en.wikipedia.org/wiki/Linux