《Red5 用户参考手册》之十二:Red5 核心技术第五章 脚本实现
来源:互联网 发布:php开发工具安装 编辑:程序博客网 时间:2024/05/22 02:08
官方最新《Red5 用户参考手册》全套下载地址
I. 选择一个脚本实现
级别:初级
RED5 含有以下脚本语言的解释器:
* Javascript - version 1.6 (Mozilla Rhino version 1.6 R7)
* JRuby - version 1.0.1 (Ruby version 1.8.5)
* Jython - version 2.2 (Python version 2.1)
* Groovy - version 1.0
* Beanshell - version 2.0b4
RED5 的以后版本可能会含有以下脚本语言的解释器:
* JudoScript
* Scala
* PHP(这个不一般,我们可能会只是提供一个桥梁)
* Actionscript (可能会是 SSAS)
文件的位置:/META-INF/services/javax.script.ScriptEngineFactory
读取自定义在 jdk 或 jre 的类会比在其他地方定义的类优先考虑。
II. 配置 Spring
级别:中级
第一步是定位你的 web 应用 red5-web.xml 文件。在这个 xml 配置文件中 web.scope bean 的定义必须提供一个 web.handler,这个处理程序就是你的 Red5 应用(一个必须扩展 org.red5.server.adapter.ApplicationAdapter 类的应用)。
这个应用提供对 Red5 服务器的访问,并提供已创建的所有服务实例。服务实例和应用本身可以使用脚本。定义在 Spring 配置文件中的 bean 不能具有相同的 id,这里是一些 web 处理程序的定义示例:
一般来说,使用脚本类的配置文件是使用构造函数的参数(见解释部分),其顺序如下:
* 参数 1 - 脚本源文件的位置
* 参数 2 - 脚本实现的 Java 接口。扩展了应用程序的接口基本样板请参考上面的例子。你不需要在你所有脚本定义里都使用这些接口。
* 参数 3 - 脚本扩展的 Java 类。扩展的类并不总是必要,这取决于脚本引擎的实现。
示例 classpath 位置:物理磁盘里的 "oflaDemo" 依赖的应用等同于 webapps/oflaDemo/WEB-INF/applications。
III. 创建一个应用脚本
1.应用适配器
一些语言中,使用脚本编写应用程序适配器比在其他语言中要难得多,藉此我介绍 Ruby 的例子,它的效果很好并易于编写和整合。这个应用服务在其他支持的语言中也很容易编写,但它们至少需要 Java 接口。
2.应用服务
这里是一个 Java 接口的示例(是的,假设方法是空的),这个接口用于为搜集一系列的文件并将它们以 Map(名-值 对)返回给调用者的应用提供一个模板。
IV. 创建你自己的解释器
级别:高级
在打开这个话题之前先提一下上周末 02/2007 试图建立一个PHP解释器,那阵势一个痛苦的过程哈,四个小时之后我不得不放弃。这件事我汲取的教训就是你首先得断定你的脚本语言可以作为应用程序运行,而不是作为 HTTP 请求处理器。这里可以先测试一下:X 语言是否可以编译成一个可执行程序,或者它可以使用命令行运行?如果可以的话,那它就可以进行轻易整合。
V. 脚本信息的相关链接
* Spring 脚本
http://static.springframework.org/spring/docs/2.0.x/reference/dynamic-language.html
http://rhinoinspring.sourceforge.net/
* Java 脚本
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/
原文链接:http://trac.red5.org/wiki/Documentation/UsersReferenceManual/Red5CoreTechnologies/05-Scripting-Implementations。
I. 选择一个脚本实现
级别:初级
RED5 含有以下脚本语言的解释器:
* Javascript - version 1.6 (Mozilla Rhino version 1.6 R7)
* JRuby - version 1.0.1 (Ruby version 1.8.5)
* Jython - version 2.2 (Python version 2.1)
* Groovy - version 1.0
* Beanshell - version 2.0b4
RED5 的以后版本可能会含有以下脚本语言的解释器:
* JudoScript
* Scala
* PHP(这个不一般,我们可能会只是提供一个桥梁)
* Actionscript (可能会是 SSAS)
脚本实现类根据你的 Java 版本预先指定在以下位置:
- Java5 - js-engine.jar, jython-engine.jar, groovy-engine.jar
- Java6 - resources.jar
文件的位置:/META-INF/services/javax.script.ScriptEngineFactory
读取自定义在 jdk 或 jre 的类会比在其他地方定义的类优先考虑。
II. 配置 Spring
级别:中级
第一步是定位你的 web 应用 red5-web.xml 文件。在这个 xml 配置文件中 web.scope bean 的定义必须提供一个 web.handler,这个处理程序就是你的 Red5 应用(一个必须扩展 org.red5.server.adapter.ApplicationAdapter 类的应用)。
这个应用提供对 Red5 服务器的访问,并提供已创建的所有服务实例。服务实例和应用本身可以使用脚本。定义在 Spring 配置文件中的 bean 不能具有相同的 id,这里是一些 web 处理程序的定义示例:
* Java 实现类
- <bean id="web.handler" class="org.red5.server.webapp.oflaDemo.MultiThreadedApplicationAdapter" />
* Javascript 实现
- <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 实现
- <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 实现
- <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 实现
- Red5 Open Source
- Flash Server (0.7.1) 51
- <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>
- Scripting Implementations
- </list>
- </constructor-arg>
- <constructor-arg index="2">
- <list>
- <value>One</value>
- <value>2</value>
- <value>III</value>
- </list>
- </constructor-arg>
- </bean>
一般来说,使用脚本类的配置文件是使用构造函数的参数(见解释部分),其顺序如下:
* 参数 1 - 脚本源文件的位置
* 参数 2 - 脚本实现的 Java 接口。扩展了应用程序的接口基本样板请参考上面的例子。你不需要在你所有脚本定义里都使用这些接口。
* 参数 3 - 脚本扩展的 Java 类。扩展的类并不总是必要,这取决于脚本引擎的实现。
示例 classpath 位置:物理磁盘里的 "oflaDemo" 依赖的应用等同于 webapps/oflaDemo/WEB-INF/applications。
III. 创建一个应用脚本
1.应用适配器
一些语言中,使用脚本编写应用程序适配器比在其他语言中要难得多,藉此我介绍 Ruby 的例子,它的效果很好并易于编写和整合。这个应用服务在其他支持的语言中也很容易编写,但它们至少需要 Java 接口。
i. JRuby 应用适配器实现
- # 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.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 "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
2.应用服务
这里是一个 Java 接口的示例(是的,假设方法是空的),这个接口用于为搜集一系列的文件并将它们以 Map(名-值 对)返回给调用者的应用提供一个模板。
i. 由脚本执行简单的 Java 接口
- package org.red5.server.webapp.oflaDemo;
- import java.util.Map;
- public interface IDemoService {
- /**
- * Getter for property 'listOfAvailableFLVs'.
- *
- * @return Value for property 'listOfAvailableFLVs'.
- */
- public Map getListOfAvailableFLVs();
- public Map getListOfAvailableFLVs(String string);
- }
ii. Spring bean 关于脚本实现的接口的定义
- <bean id="demoService.service" class="org.springframework.scripting.jruby.JRubyScriptFactory">
- <constructor-arg index="0" value="classpath:applications/demoservice.rb"/>
- <constructor-arg index="1">
- <list>
- <value>org.red5.server.webapp.oflaDemo.IDemoService</value>
- </list>
- </constructor-arg>
- </bean>
iii. JRuby 脚本实现接口
- # JRuby - style
- require 'java'
- module RedFive
- include_package "org.springframework.core.io"
- include_package "org.red5.server.webapp.oflaDemo"
- end
- include_class "org.red5.server.api.Red5"
- include_class "java.util.HashMap"
- #
- # demoservice.rb - a translation into Ruby of the ofla demo application, a red5 example.
- #
- # @author Paul Gregoire
- #
- class DemoService < RedFive::DemoServiceImpl
- attr_reader :filesMap
- attr_writer :filesMap
- def initialize
- puts "Initializing ruby demoservice"
- super
- @filesMap = HashMap.new
- end
- def getListOfAvailableFLVs
- puts "Getting the FLV files"
- begin
- dirname = File.expand_path('webapps/oflaDemo/streams').to_s
- Dir.open(dirname).entries.grep(/\.flv$/) do |dir|
- dir.each do |flvName|
- fileInfo = HashMap.new
- stats = File.stat(dirname+'/'+flvName)
- fileInfo["name"] = flvName
- fileInfo["lastModified"] = stats.mtime
- fileInfo["size"] = stats.size || 0
- @filesMap[flvName] = fileInfo
- print 'FLV Name:', flvName
- print 'Last modified date:', stats.mtime
- print 'Size:', stats.size || 0
- print '-------'
- end
- end
- rescue Exception => ex
- puts "Error in getListOfAvailableFLVs #{errorType} \n"
- puts "Exception: #{ex} \n"
- puts caller.join("\n");
- end
- return filesMap
- end
- def formatDate(date)
- return date.strftime("%d/%m/%Y %I:%M:%S")
- end
- def method_missing(m, *args)
- super unless @value.respond_to?(m)
- return @value.send(m, *args)
- end
- end
iv. Java 应用实现接口,基于 Ruby 代码(在不需要使用脚本时的代码)
- package org.red5.server.webapp.oflaDemo;
- import java.io.File;
- import java.io.IOException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Locale;
- import java.util.Map;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.red5.server.api.IScope;
- import org.red5.server.api.Red5;
- import org.springframework.core.io.Resource;
- public class DemoService {
- protected static Log log = LogFactory.getLog(DemoService.class.getName());
- /**
- * Getter for property 'listOfAvailableFLVs'.
- Scripting Implementations
- *
- * @return Value for property 'listOfAvailableFLVs'.
- */
- public Map getListOfAvailableFLVs() {
- IScope scope = Red5.getConnectionLocal().getScope();
- Map<String, Map> filesMap = new HashMap<String, Map>();
- Map<String, Object> fileInfo;
- try {
- log.debug("getting the FLV files");
- Resource[] flvs = scope.getResources("streams/*.flv");
- if (flvs != null) {
- for (Resource flv : flvs) {
- File file = flv.getFile();
- Date lastModifiedDate = new Date(file.lastModified());
- String lastModified = formatDate(lastModifiedDate);
- String flvName = flv.getFile().getName();
- String flvBytes = Long.toString(file.length());
- if (log.isDebugEnabled()) {
- log.debug("flvName: " + flvName);
- log.debug("lastModified date: " + lastModified);
- log.debug("flvBytes: " + flvBytes);
- log.debug("-------");
- }
- fileInfo = new HashMap<String, Object>();
- fileInfo.put("name", flvName);
- fileInfo.put("lastModified", lastModified);
- fileInfo.put("size", flvBytes);
- filesMap.put(flvName, fileInfo);
- }
- }
- Resource[] mp3s = scope.getResources("streams/*.mp3");
- if (mp3s != null) {
- for (Resource mp3 : mp3s) {
- File file = mp3.getFile();
- Date lastModifiedDate = new Date(file.lastModified());
- String lastModified = formatDate(lastModifiedDate);
- String flvName = mp3.getFile().getName();
- String flvBytes = Long.toString(file.length());
- if (log.isDebugEnabled()) {
- log.debug("flvName: " + flvName);
- log.debug("lastModified date: " + lastModified);
- log.debug("flvBytes: " + flvBytes);
- log.debug("-------");
- }
- fileInfo = new HashMap<String, Object>();
- fileInfo.put("name", flvName);
- fileInfo.put("lastModified", lastModified);
- fileInfo.put("size", flvBytes);
- filesMap.put(flvName, fileInfo);
- }
- }
- } catch (IOException e) {
- log.error(e);
- }
- return filesMap;
- }
- private String formatDate(Date date) {
- SimpleDateFormat formatter;
- String pattern = "dd/MM/yy H:mm:ss";
- Locale locale = new Locale("en", "US");
- formatter = new SimpleDateFormat(pattern, locale);
- return formatter.format(date);
- }
- }
a.Flex AS3 方法调用服务
- [Bindable]
- public var videoList:ArrayCollection;
- public function catchVideos():void{
- // call server-side method
- // create a responder and set it to getMediaList
- var nc_responder:Responder = new Responder(getMediaList, null);
- // call the server side method to get list of FLV's
- nc.call("demoService.getListOfAvailableFLVs", nc_responder);
- }
- public function getMediaList(list:Object):void{
- // this is the result of the server side getListOfAvailableFLVs
- var mediaList:Array = new Array();
- for(var items:String in list){
- mediaList.push({label:items, size:list[items].size, dateModified:list[items].lastModifi
- }
- // videoList is bindable and the datagrid is set to use this for it's dataprovider
- // wrap it in an ArrayCollection first
- videoList = new ArrayCollection(mediaList);
- }
IV. 创建你自己的解释器
级别:高级
在打开这个话题之前先提一下上周末 02/2007 试图建立一个PHP解释器,那阵势一个痛苦的过程哈,四个小时之后我不得不放弃。这件事我汲取的教训就是你首先得断定你的脚本语言可以作为应用程序运行,而不是作为 HTTP 请求处理器。这里可以先测试一下:X 语言是否可以编译成一个可执行程序,或者它可以使用命令行运行?如果可以的话,那它就可以进行轻易整合。
V. 脚本信息的相关链接
* Spring 脚本
http://static.springframework.org/spring/docs/2.0.x/reference/dynamic-language.html
http://rhinoinspring.sourceforge.net/
* Java 脚本
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/
原文链接:http://trac.red5.org/wiki/Documentation/UsersReferenceManual/Red5CoreTechnologies/05-Scripting-Implementations。
- 《Red5 用户参考手册》之十二:Red5 核心技术第五章 脚本实现
- 《Red5 用户参考手册》之十二:Red5 核心技术第五章 脚本实现
- 《Red5 用户参考手册》之十一:Red5 核心技术第四章 安全
- 《Red5 用户参考手册》之十三:Red5 核心技术第六章 集群
- 《Red5 用户参考手册》之十四:Red5 核心技术第七章 管理
- 《Red5 用户参考手册》之十一:Red5 核心技术第四章 安全
- 《Red5 用户参考手册》之十三:Red5 核心技术第六章 集群
- 《Red5 用户参考手册》之十四:Red5 核心技术第七章 管理
- 《Red5 用户参考手册》之六:入门第五章 构建 Red5
- 《Red5 用户参考手册》之六:入门第五章 构建 Red5
- 《Red5 用户参考手册》之九:Red5 核心技术第二章 将 Red5 部署到 Tomcat
- 《Red5 用户参考手册》之九:Red5 核心技术第二章 将 Red5 部署到 Tomcat
- 《Red5 用户参考手册》之十:Red5 核心技术第三章 自定义流路径
- 《Red5 用户参考手册》之十五:Red5 核心技术第八章 自定义的 bean 定义列表
- 《Red5 用户参考手册》之十:Red5 核心技术第三章 自定义流路径
- 《Red5 用户参考手册》之十五:Red5 核心技术第八章 自定义的 bean 定义列表
- 《Red5 用户参考手册》之十:Red5 核心技术第三章 自定义流路径
- 《Red5 用户参考手册》之八:Red5 核心技术第一章 在 Red5 里创建新应用
- 博客安家
- 12.3 实验2:交换机端口安全
- 容易出现insert into语句的语法错误的原因
- 一个页面使用两次timepicker.js引起的Maximum call stack size exceeded问题解决办法及bug修复
- Jdom使用指南
- 《Red5 用户参考手册》之十二:Red5 核心技术第五章 脚本实现
- MFC设置对话框大小
- 从员工到总监,你要明白的8个道理
- 禁用显示屏的休眠
- 《Red5 用户参考手册》之十三:Red5 核心技术第六章 集群
- 无法找到mfc90ud.dll 的解决方法
- 《Red5 用户参考手册》之十四:Red5 核心技术第七章 管理
- 《Red5 用户参考手册》之十五:Red5 核心技术第八章 自定义的 bean 定义列表
- 透过汇编看天下之--for(;;)与while(1)究竟有什么不同?