Documentation/Tutorials/JRubyScriptingExplained

Jruby スクリプトの概要

概要

I am pretty new to red5 and had some trouble getting any of my jruby apps to work with it. The only other example that I could find was the scripting how-to guide and I personally think it is geared more towards seasoned red5 developers. So this will be my attempt at making jruby scripting and scripting in general with red5 a little easier for newbs such as my self. This tutorial assumes that you have the latest version of red5 from trunk installed and working correctly. I also use apache's ant to build the more complicated example.

Basic Application

The first example is going to assume that you have no java services defined and only have the main application(main.rb). This will cover the required directory structure and required files(took me a long time to figure this out).  This may seem very simple to more seasoned red5 developers but it is major hang-up for new users to the scripting features in red5. Also, I am using java version 1.6.0_02 but this first example should work with any version that supports scripting. However, I have read that there are issues with older versions and red5 scripting.

Webapp Directory Structure

As you may already be aware, all applications should be located in the red5/webapps directory. This seems really simple now that I am aware of what is required but at first I had no clue what my basic directory structure should be. Also, please note that we will use a slightly different process for applications with java services and I will explain that in more detail later on in the tutorial. In this tutorial red5 will represent the red5 root directory. I will also use the webapp name of red5Jruby throughout this tutorial.

The basic configuration files can be found in red5/doc/templates/myapp . To make things easier you can copy the contents of that directory to red5/webapps/yourApp

red5/    #red5 root directory
...webapps/    #red5 web applications directory
.....red5Jruby/    #our application
.........WEB-INF/     #contains all of our application's  files i.e. configs and application sources
..............classes/    #contains our complied java classes and scripting sources
..................applications/   #contains our scripting sources
........................main.rb     #our jruby implementation of the red5 application adapter
..............lib/    #our application's lib directory
................slf4j-api-1.4.3.jar   #core api. This jar should be located in red5/lib. You will need to copy it into this directory
..............web.xml  #our application settings. This file is located in red5/doc/templates/myapp/WEB-INF
..............red5-web.xml #our application's web handler and services definitions
..............red5-web.properties #our application's vitualHosts and context path

The configuration files should be pretty easy to understand. The only one that I am going to cover in this tutorial is the red5-web.xml. Which contains our web handler and services definitions. Below is an excerpt from the red5-web.xml that defines our application web handler. Please see the scripting how-to guide for more information.

#red5/webapps/red5Jruby/WEB-INF/red5-web.xml
<!-- Our application web handler -->
       <bean id="web.handler" class="org.springframework.scripting.jruby.JRubyScriptFactory">
		<constructor-arg index="0" value="classpath:applications/main.rb"/>
		<constructor-arg index="1">
			<list>
				<value>org.red5.server.api.IScopeHandler</value>
				<value>org.red5.server.adapter.IApplication</value>
			</list>
		</constructor-arg>
	</bean>

Ruby application adapter

I am going to use the main.rb from the olfaDemo as it is a good basic example. In later tutorials I will explain the application adapter in more detail. The focus of this tutorial is to get a basic application setup and working.

# JRuby - style
require 'java'
module RedFive
    include_package "org.red5.server.api"
	include_package "org.red5.server.api.stream"
	include_package "org.red5.server.api.stream.support"
	include_package "org.red5.server.adapter"
	include_package "org.red5.server.stream"
end

#
# application.rb - a translation into Ruby of the ofla demo application, a red5 example.
#
# @author Paul Gregoire
#
class Application < RedFive::ApplicationAdapter

    attr_reader :appScope, :serverStream
	attr_writer :appScope, :serverStream

	def initialize
	   #call super to init the superclass, in this case a Java class
	   super
	   puts "Initializing ruby application"
	end

	def appStart(app)
        puts "Jruby application started"
		@appScope = app
		return true
	end

	def appConnect(conn, params)
		puts "Ruby appConnect"
		measureBandwidth(conn)
		puts "Ruby appConnect 2"
		if conn.instance_of?(RedFive::IStreamCapableConnection)
		    puts "Got stream capable connection"
			sbc = RedFive::SimpleBandwidthConfigure.new
			sbc.setMaxBurst(8388608)
			sbc.setBurst(8388608)
			sbc.setOverallBandwidth(8388608)
			conn.setBandwidthConfigure(sbc)
		end
		return super
	end

	def appDisconnect(conn)
		puts "Ruby appDisconnect"
		if appScope == conn.getScope && @serverStream != nil
			@serverStream.close
		end
		super
	end

	def toString
		return "Ruby toString"
	end

    def setScriptContext(scriptContext)
	   puts "Ruby application setScriptContext"
    end

    def method_missing(m, *args)
      super unless @value.respond_to?(m)
      return @value.send(m, *args)
    end

end

That is all that is required for a basic jruby application in red5.&nbsp;

More complicated example

Next I will explain a more complicated example that has defined services. I will use the oflaDemo as the example and will include a build file that will compile our application. As I said before, the purpose of this tutorial is to show you how to create and setup a basic application. I will go more into detail in later tutorials.

First we will need to create a new directory under red5/webapps. I will also refer to this one as red5Jruby. Once this is completed you will need to obtain the sources for the oflaDemo. If you complied red5 from the latest trunk version, they should be located in red5-trunk/webapps/oflaDemo. Now copy the contents of the oflaDemo directory into our new red5Jruby directory.&nbsp; Once that is completed you will then need to change the references to oflaDemo to red5Jruby in the configuration files. At this time you can also remove the handler and services definitions for java and the other scripting languages from the red5-web.xml.

You should now have a directory structure that looks like this:

red5/
...webapps/
......WEB-INF/
.........src/ #our application sources; both java and jruby
...........applications/ #our scripting sources
...........org/
.............red5/
...............server/
.................webapp/
...................oflaDemo/  #you will need to rename this directory to red5Jruby
.....................Application.java
.....................DemoService.java
.....................IDemoService.java
.....................DemoServiceImpl.java
.........logback.xml
.........build.xml
.........build.properties

You will now need to change the following package definition to suit our new application in all of the java sources.

package org.red5.server.webapp.oflaDemo;

to

package org.red5.server.webapp.red5Jruby;

Also, you will need to change the logger definition in red5/webapps/red5Jruby/WEB-INF/logback.xml to match our application ie org.red5.server.webapp.red5Jruby.

Build sources

I pieced this together from red5/build.xml the comments should explain it pretty well

build.xml


<project name="Complie Red5 webapp" basedir="." default="build">

<!-- Project properties -->
	<property name="root.dir" value="../../../"/>
	<property name="root.classes.dir" value="${root.dir}/bin"/>
	<property name="root.lib.dir" value="${root.dir}/lib"/>
	<property name="src.dir" value="src"/>
	<property name="classes.dir" value="classes"/>
	<property name="lib.dir" value="lib"/>
	<property name="target.jar" value="red5Jruby.jar"/>
<!-- End Project properties -->

<!-- webapps Classpath -->
	<path id="webapps.classpath">
		  <fileset dir="${root.dir}">
				<filename name="red5.jar"/>
			</fileset>
			<fileset dir="${root.lib.dir}">
				<filename name="*.jar"/>
			</fileset>
			<pathelement location="${root.classes.dir}"/>
	</path>
<!-- End webapps Classpath -->

<!-- Clean webapp -->
	<target name="clean" description="Cleans WEBAPP dir">
		<echo message="Deleting the classes and lib directories...." />
		<delete dir="${classes.dir}"/>
		<delete dir="${lib.dir}"/>
	</target>
<!-- End Clean webapp -->

<!-- Prepare webapp -->
	<target name="prepare" depends="clean">
		<echo message="Creating the classes and lib directories...." />
		<mkdir dir="${lib.dir}"/>
		<mkdir dir="${classes.dir}"/>
		<mkdir dir="${classes.dir}/applications"/>
	</target>
<!-- End Prepare webapp -->

<!-- Build webapp -->
	<target name="build" depends="prepare">
		<echo message="Compiling application sources...." />
		<javac
			sourcepath=""
			srcdir="${src.dir}"
			destdir="${classes.dir}"
			classpathref="webapps.classpath"
		    optimize="true"
		    verbose="false"
		    fork="true"
		    nowarn="true"
		    deprecation="false"
		    debug="true"
		    compiler="modern"
		    source="1.6"
		    target="1.6"
		/>
		<echo message="Copying scripting sources..." />
		<copy todir="${classes.dir}/applications">
			<fileset dir="${src.dir}/applications"/>
		</copy>

		<copy todir="${classes.dir}" file="${src.dir}/logback.xml" overwrite="true"/>
		<copy todir="${lib.dir}">
			<fileset dir="${root.lib.dir}">
				<include name="slf4j-api-1.4.3.jar"/>
				<include name="logback-core-0.9.8.jar"/>
				<include name="logback-classic-0.9.8.jar"/>
			</fileset>
		</copy>
	</target>
<!-- End Build webapp -->


<!-- Create Jar -->
	<target name="jar" description="Make Archive" depends="build">
		<echo message="Creating Jar" />
		<jar destfile="${lib.dir}/${target.jar}">
			<fileset dir="${classes.dir}">
				<include name="**"/>
			</fileset>
		</jar>
	</target>
<!-- End Create Jar -->

</project>

You can use this same build file for future applications. However, you will need to change the target.jar property from red5Jruby.jar to yourAppName.jar

build.properties(not really used in this example)

# Base build properties
#

#javac options
# http://ant.apache.org/manual/CoreTasks/javac.html
# sun javac
build.compiler=javac
# jikes
#build.compiler=jikes

# generic compiler options
build.verbose=false
build.fork=true
build.deprecation=false
build.nowarn=true

# optimize only works with a few compilers
build.optimize=true

# Change this var to build to a different Java version
java.target_version=1.6

# jikes options
build.compiler.emacs=false
build.compiler.fulldepend=false
build.compiler.pedantic=false

We are almost done now\! All we have left is to acutally build the application and start/restart the server. You can do this by navigating to red5/webapps/red5Jruby/WEB-INF and typing the following into the command prompt

ant jar

This will compile the application sources, create the required application directory structure and create a jar containing the contents of the newly created classes directory. At this point you should be able to restart the server and you should see the following in the terminal

Initializing ruby application
Ruby appStart

Any suggestions or clarifications on any topics covered in this tutorial are more then welcome.

Enjoy, Thomas Johnson(tomfmason)