
How to script for Red5
By: Paul Gregoire
Date: 2 Feb 2007

I. Select a scripting implementation
Level: Beginner

Red5 includes interpreters for the following scripting languages:
	- Javascript - version 1.6 (Mozilla Rhino version 1.6.2)
	- JRuby - version 0.9.2 (Ruby version 1.8.5)
	- Jython - version 2.1 (Python version 2.1)
	- Groovy - version 1.0
	- Beanshell - version 2.0b4

Future versions may include:
	- JudoScript
	- Scala
	- PHP
	- Actionscript (Not SSAS)



II. Configuring Spring
Level: Intermediate

Step one is to locate your web applications red5-web.xml file. Within the xml config file the web.scope bean definition must supply a web.handler, this handler is your Red5 application (An application must extend the org.red5.server.adapter.ApplicationAdapter class).
The application provides access to the Red5 server and any service instances that are created. The service instances and the application itself may be scripted.
Bean definitions in Spring config files may not have the same id, here are some web handler definition examples:

Java class implementation - 
<bean id="web.handler" class="org.red5.server.webapp.oflaDemo.Application" />

Javascript implementation -
<bean id="web.handler" class="org.red5.server.script.rhino.RhinoScriptFactory">
	<constructor-arg index="0" value="classpath:applications/main.js"/>
	<constructor-arg index="1">
		<list>
			<value>org.red5.server.api.IScopeHandler</value>
     		<value>org.red5.server.adapter.IApplication</value>
		</list>
	</constructor-arg>
	<constructor-arg index="2">
		<value>org.red5.server.adapter.ApplicationAdapter</value>
	</constructor-arg>
</bean>

Ruby implementation - 
<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>

Groovy implementation - 
<bean id="web.handler" class="org.red5.server.script.groovy.GroovyScriptFactory">
	<constructor-arg index="0" value="classpath:applications/main.groovy"/>
	<constructor-arg index="1">
		<list>
			<value>org.red5.server.api.IScopeHandler</value>
			<value>org.red5.server.adapter.IApplication</value>
		</list>
	</constructor-arg>
</bean>

Python implementation - 
<bean id="web.handler" class="org.red5.server.script.jython.JythonScriptFactory">
	<constructor-arg index="0" value="classpath:applications/main.py"/>
	<constructor-arg index="1">
		<list>
    		<value>org.red5.server.api.IScopeHandler</value>
    		<value>org.red5.server.adapter.IApplication</value>
		</list>
	</constructor-arg>
        <constructor-arg index="2">
		<list>
            <value>One</value>
            <value>2</value>
            <value>III</value>
        </list>
    </constructor-arg>
</bean>

In general the configuration using scripted classes is defined using the constructor arguments (see interpreter section) in the following order:
	Argument 1 - Location of the script source file
	Argument 2 - Java interfaces implemented by the script
	Argument 3 - Java classes extended by the script

The example location starts with classpath:applications which in physical disk terms for the oflaDemo application equates to webapps/oflaDemo/WEB-INF/applications 




III. Creating an application script
Level: Intermediate

JRuby application adapter implementation -

# JRuby
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.js - a translation into Ruby of the olfa 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 "Ruby appStart"
		@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




IV. Creating your own interpreter
Level: Advanced



V. Links with scripting information
Spring scripting - 
http://static.springframework.org/spring/docs/2.0.x/reference/dynamic-language.html
http://rhinoinspring.sourceforge.net/

Java scripting - 
http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting/
http://blogs.sun.com/sundararajan/
https://scripting.dev.java.net/
http://today.java.net/pub/a/today/2006/04/11/scripting-for-java-platform.html
http://www.javaworld.com/javaworld/jw-03-2005/jw-0314-scripting_p.html
http://www.oreillynet.com/onjava/blog/2004/01/java_scripting_half_the_size_h.html
http://www.robert-tolksdorf.de/vmlanguages.html

Javascript - 
http://www.mozilla.org/rhino/
http://www.mozilla.org/rhino/ScriptingJava.html

Ruby -
http://jruby.codehaus.org/

BeanShell - 
http://www.beanshell.org/

Python - 
http://www.jython.org/Project/
http://www.onjava.com/pub/a/onjava/2002/03/27/jython.html
http://jepp.sourceforge.net/
http://jpe.sourceforge.net/
http://jpype.sourceforge.net/

Groovy -
http://groovy.codehaus.org/





