说明:这篇文章是我翻译的一篇外文,作者:Paul Gregoire
这篇文献描述了怎么将Red5部署到Tomcat中,就像普通的web应用需要的WAR一样。标准的Red5部署由运行在作为系统服务器的嵌入式J2EE容器(如:Jetty或者Tomcat)中的单独java应用组成,然而WAR版本的部署则是运行在J2EE容器内部。
WAR版本的部署 (red5在tomcat里面) 标准的Red5部署(tomcat在red5里面)
我们更偏向于使用Tomcat,但是我们也可以用WAR来部署到其他的J2EE容器中
Tomcat的war部署器将周期的扫描web应用的目录,起目的是为了发现war。当它发现了一个未部署的war,部署器就会将这个war文件写入到基于该war文件名称的目录中去,一个名为myapp.war的文件将被扩展到名为myapp的目录中;根据你的安装,全路径会像C:\Tomcat-6.0.18\webapps\myapp。
Red5服务器被打包在名为ROOT.war的包中,这个文件名在大多数J2EE应用服务器中有一个特殊的含义,并且通常情况下它是默认的或者根部web上下文。这个根部web上下文负责为不包含路径组件的请求服务。一个具有路径组件的url看起来像http://www.example.com/myapp一样,然而根部web应用的url将类似http://www.example.com/。一个额外的配置文件(上下文描述者)被放在了META-INF目录中,为每一个web上下文服务。应用不是不是通过HTTP访问的,不需要web/servlet上下文。这个根部war文件几乎包含了在单独服务器部署中所需的所有东西,除了嵌入服务器的classes和一些配置文件。
ROOT.war有可能被重命名为red5.war,但是这还没被测试是否需要对一些配置文件做一些更改。记住一点,这个名字和它对J2EE容器的解决方案根本上是为HTTP请求服务的,根本不会影响到RTMP会话。
上下文XML描述符是XML数据的一个片段,XML数据包含了一个有效的上下文元素,通常在tomcat服务器的主要配置文件(conf/server.xml)中可以找到。对于一个给定的主机,这些上下文描述被放在$CATALINA_HOME/conf/[enginename]/[hostname]/。注意一点,当部署器从包含在war中的context.xml文件开始创建描述符的时候,这文件的名字并没有被捆绑于web应用的名字,它们的名字将与web应用的名字相匹配。
上下文描述符能够定义所有方面和上下文的配置参数,比如命名来源和session manager 配置。要注意的是,在上下文元素中指定的docBase能够适用于.WAR或当.WAR被扩展时产生的目录,或者.WAR本身。
Red5的配置由一些web.xml中的上下文参数,一个缺省的上下文文件,一个bean关联文件和为每一个利用Red5特性的应用提供服务的Spring web上下文文件组成。在服务器端应用的上下文中,只是通过AMF与Red5会话的web应用不需要配置入口。通过spring管理的应用上下文仅仅对包含在root war中的应用有用,这跟web应用的类加载器工作方式有关。另外,Red5使用一个称为范围的上下文副本,它作为一个上下文、处理者、服务器核心实例和一少些其他对象的容器。一个范围就像FMS中的应用模型。
Red5的起始入口或者启动的servlet是WarLoaderServlet,同时在web.xml中它被配置成为一个servlet监听器,就想下面描述的一样。在标准的Red5服务器中,从功能上这个servlet代替了Bootstrap类的位置
<listener>
<listener-class>org.red5.server.war.WarLoaderServlet</listener-class>
</listener>
这个类根据收到的上下文初始化和销毁的容器事件来启动和停止Red5.这个war加载器在功能上近似于spring中的ContextLoaderListener servlet,但是它被指定与Red5.
Red5使用两种类型的上下文,“default”和“web”。这儿也许只有一种default上下文,但是会有任意多种web上下文。
缺省上下文与全局应用上下文同义,并且负责最高级别的提供对象和资源。Spring的beans在这个级别上是通过defaultContext.xml和被放在ROOT classse目录(C:\Tomcat-6.0.8\webapps\ROOT\WEB-INF\classes)下的beanRefContext.xml配置的。Bean关联文件定义了一个叫default.context的bean,就好像org.springframework.context.support.ClassPathXmlApplicationContext的实例一样。另外两个配置文件red5-common.xml和red5-core.xml被用于构造默认的上下文;这些文件来源于相同名字的单独文件,最根本的不同点是服务器植入片段已经被移除。
默认的上下文通过parentContextKey参数被关联在web.xml中:
<context-param>
<param-name>parentContextKey</param-name>
<param-value>default.context</param-value>
</context-param>
这个参数被ContextLoader(上下文加载器)用来确定允许全局资源被确定的父亲上下文的位置。这个上下文加载器被WarLoaderServlet用来初始化web上下文。
与全局上下文相似的范围就是全局范围,并且它通过globalScope参数被关联在web.xml中:
<context-param>
<param-name>globalScope</param-name>
<param-value>default</param-value>
</context-param>
Web上下文的定义被通过后缀为-web.xml的Spring配置文件指定。如果你的项目名称为oflaDemo,那么它的配置文件应命名为oflaDemo-web.xml。Spring web上下文文件不应该与J2EE上下文描述文件相混淆,因为前者只是为Red5的web上下文服务的,而后者则是应用在Tomcat中的。任何一个web上下文都必须含有一个相应的配置文件,这个配置文件被用ant的风格的参数指定在web.xml中,如下:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/classes/*-web.xml</param-value>
</context-param>
上下文配置文件指定被用于提醒系统加入或者离开客户端所需的资源,提供供客户端调用的方法。另外,这些配置文件为类指定了层级式的范围。
每一个上下文配置文件必须至少包含最基本的3个个入口(context,scope ,handler)。这个规则唯一个例外是当web根应用没有handler的时候,在这样的情况下,全局的handler将被应用。
l Context:从所有的上下文同唯一的spring应用上下文存在时开始,每一个Context必须被指定一个唯一的名字。最根部的Web上下文被名字为web.context,其他的上下文用这个名字为基础并用项目名做后缀来名字,例如oflaDemo将被名字为web.context.oflaDemo。一个上下文在web上下文文件中指定如下:
<bean id="web.context"class="org.red5.server.Context">
<property name="scopeResolver" ref="red5.scopeResolver"/>
<propertyname="clientRegistry" ref="global.clientRegistry" />
<property name="serviceInvoker"ref="global.serviceInvoker" />
<propertyname="mappingStrategy" ref="global.mappingStrategy" />
</bean>
l Scope:每一个应用都至少需要一个范围(scope),它能将处理者(handler)连接到上下文和服务器。这些范围(scope)能够构建起一个树形,在这树形中客户端能够连接每个节点并且共享范围内的对象(就像shared objects或者实时流一样)。你可以把这些scope看着房间或实例。
最底层的范围叫做web.scope,其他范围的名称应该遵循范围命名的约定。应用oflaDemo的范围名字应该取为web.scope.oflaDemo,这样它才不会与其它上下文冲突。
一个范围bean具有下面的属性:
1. Server-它关联到red5.server
2. Parent-当前范围的父亲范围,通常是global.scope
3. Context-这个范围的上下文,web.context是最底层的上下文,web.context.oflaDemo是应用oflaDemo的上下文
4. Handler-范围的处理者,就好像FMS中的main.asc
5. ContextPath-当连接到该范围时该路径起作用
6. VirtualHosts-用逗号分隔开的主机列表名或者这个scope监听的IP地址。在war部署的版本中我们不控制主机名字,这是由tomcat完成的。在这里,“*”表示“所有”的意思。
最底层的范围定义如下:
<bean id="web.scope"class="org.red5.server.WebScope" init-method="register">
<propertyname="server" ref="red5.server" />
<propertyname="parent" ref="global.scope" />
<propertyname="context" ref="web.context" />
<propertyname="handler" ref="global.handler" />
<propertyname="contextPath" value="/" />
<propertyname="virtualHosts" value="*" />
</bean>
这里的contextPath就像J2EE上下文文件中为每个web应用提供服务的docBase一样。docBase被用于确定HTTP所需的资源,而contextPath是用来确定RTMP所需的资源。你的应用也许在动态的创建其他范围的路径后又添加了额外的元素。所有动态创建的范围都使用同一个handler,但是拥有它们自己的属性、共享对象和实时流。
l Handler-每个上下文都需要一个handler来提供给链接上了的客户端调用的方法。所有的handler必须实现org.red5.server.api.IScopeHandler,但是你也许会实现其它接口来控制访问共享对象或流。Red5提供的一个简单的实现就好像你的最基本类:org.red5.server.adapter.ApplicationAdapter。请查询java文档来对这个类获取更多的描述。
一个oflaDemo应用的scope handler例子如下:
<bean id="web.handler.oflaDemo"class="org.red5.demos.oflaDemo.Application"/>
这个id属性通过oflaDemo范围的定义关联起来:
<bean id="web.scope.oflaDemo"class="org.red5.server.WebScope" init-method="register">
<propertyname="server" ref="red5.server" />
<propertyname="parent" ref="global.scope" />
<propertyname="context" ref="web.context.oflaDemo" />
<propertyname="handler" ref="web.handler.oflaDemo" />
<propertyname="contextPath" value="/oflaDemo" />
<propertyname="virtualHosts" value="*" />
</bean>
如果你不需要特别的服务器端的逻辑,你可以使用red5提供的默的应用
handler:
<bean id="web.handler"class="org.red5.server.adapter.ApplicationAdapter"
/>
一个外部应用涉及到root web 应用外的访问red5的应用。是否这些应
用存在于相同的JVM实例中,他们只能够通过RTMP或者AMF通道
servlet访问Red5.这个通道servlet为每一个应用被配置在web.xml中,这些应用需要通过AMF来与Red5产生会话,一个例子如下:
<context-param>
<param-name>tunnel.acceptor.url</param-name>
<param-value>http://localhost:8080/gateway</param-value>
</context-param>
<context-param>
<param-name>tunnel.timeout</param-name>
<param-value>30000</param-value>
</context-param>
<servlet>
<servlet-name>gateway</servlet-name>
<servlet-class>org.red5.server.net.servlet.AMFTunnelServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gateway</servlet-name>
<url-pattern>/gateway</url-pattern>
</servlet-mapping>
这个通道servlet必须在已经执行了的应用的类路径上。另外,通道类org.red5.server.net.servlet.ServletUtils需要以下的jar包:
commons-codec-1.3.jar
commons-httpclient-3.0.1.jar
mina-core-2.0.0-M6.jar
slf4j-api-1.5.6.jar
jcl-over-slf4j-1.5.6.jar
jul-to-slf4j-1.5.6.jar
log4j-over-slf4j-1.5.6.jar
logback-core-0.9.14.jar
logback-classic-0.9.14.jar
red5-remoting-0.8.0.jar(contains ServletUtils class)
这些jar需要放在你项目的WEB-INF/lib目录下,例如:
C:\Tomcat-6.0.18\webapps\myapp\WEB-INF\lib
下面这章,包括两个应用。这第一个是通过AMF或者RTMP与Red5会话的并且拥有自己的handler,被命名为“RemoteApp”的一个web应用。第二个将包含一个通过RTMP与Red5回话的SWF文件,这应用被称为“LocalApp”。任何只要支持Java的IDE都可以用来创建这些应用,推荐使用eclipse。这个例子中的SWF文件将使用Flex中的AS3来创建。
这个例子将提供给你对于一个远程的Red5应用所需的最低的配置。下面这些资源需要被创建:
l J2EE web应用
l 客户端SWF文件
l Red5 handler 类
l Spring web 上下文
步骤:
1. 用你的IDE创建名为RemoteApp的web应用
2. 获取red5 jar,你可以从http:/red5.googlecode.com/svn/repository/red5/red5-0.8.0.jar下载,或者用ant来构建这个资源。如果你想继承ApplicationAdapter来处理你应用的scope handler,那么这个库是必须的。
3. 获取远程的jar包,这个你自己可以通过“ant remote jar”来完成,或者从http://red5.googlecode.com/svn/repository/red5-remoting-0.8.0.jar这个类库提供了通道servlet。
4. 将jar包加入到工程类库路径下,并把它们加入到对应的build classpath中。
5. 编辑Java和Flex资源
6. 在tomcat的webapps路径下创建名为RemoteApp的路径,如:C:\Tomat-6.0.18\webapps\RemoteApp
7. 将web路径下类容复制到RemoteApp路径下
8. 从bin目录中复制RemoteApp.swf到webapps\RemoteApp目录下。
9. 复制lib目录下的内容到WEB-INF,包括red5.jar
10. 从bin目录复制所有的例子目录和RemoteApp-web.xml文件到ROOT的类文件目录。例如:C:\Tomcat-6.0.18\webapps\ROOT\WEB-INF\classes
11. 重启tomcat
12. 打开你的浏览器并跳转到http://localhost:8080/RemoteApp/RemoteApp.html
13. 点击RTMP或者HTTP连接按钮。如果测试成功你将看到服务器返回的“Hello World”
一个简单的应用,它完全在root web应用中。这个例子由Spring的web上下文,handler类和客户端SWF文件组成。
步骤:
1. 在IDE中创建名为LocalApp的应用
2. 获取red5.jar,你可以在http://red5.googlecode.com/svn/repository/red5/red5-0.8.0.jar下载,或者用“ant jar”构建。如果你想继承ApplicationAdapter来处理你应用的scope handler,那么这个库是必须的。
3. 将jar包加入到工程类库路径下,并把它们加入到对应的build classpath中。
4. 编辑Java和Flex资源
5. 从bin目录下复制LocalApp.html和LocalApp.swf到ROOT下,如:C:\Tomcat-6.0.18\webapps\ROOT
6. 从bin目录复制所有的例子目录和LocalApp-web.xml文件到ROOT的类文件目录。例如:C:\Tomcat-6.0.18\webapps\ROOT\WEB-INF\classes
7. 重启tomcat
8. 打开你的浏览器并跳转到http://localhost:8080/LocalApp.html
9. 点击连接按钮。如果测试成功你将看到服务器返回的“Hello World”
例子应用资源在Subversion中可见,http://red5.googlecode.com/svn/java/example/trunk
AMF通道-这个servlet用AMF于服务器会话。
<servlet>
<servlet-name>gateway</servlet-name>
<servlet-class>org.red5.server.net.servlet.AMFGatewayServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>gateway</servlet-name>
<url-pattern>/gateway</url-pattern>
</servlet-mapping>
RTMPT-这个servlet通过HTTP实现了RTMP通道,它通常用于绕过防火墙
<servlet>
<servlet-name>rtmpt</servlet-name>
<servlet-class>org.red5.server.net.rtmpt.RTMPTServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rtmpt</servlet-name>
<url-pattern>/fcs/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>rtmpt</servlet-name>
<url-pattern>/open/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>rtmpt</servlet-name>
<url-pattern>/idle/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>rtmpt</servlet-name>
<url-pattern>/send/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>rtmpt</servlet-name>
<url-pattern>/close/*</url-pattern>
</servlet-mapping>
安全-下面的条目用于阻止检索敏感的信息。
<security-constraint>
<web-resource-collection>
<web-resource-name>Forbidden</web-resource-name>
<url-pattern>/WEB-INF/*</url-pattern>
</web-resource-collection>
<auth-constraint/>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Forbidden</web-resource-name>
<url-pattern>/persistence/*</url-pattern>
</web-resource-collection>
<auth-constraint/>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Forbidden</web-resource-name>
<url-pattern>/streams/*</url-pattern>
</web-resource-collection>
<auth-constraint/>
</security-constraint>
在某些情况下你也许需要重命名war,这样它就不会覆盖你的容器的ROOT应用。仅仅需要几步就可以完成:
1. 打开red5的web.xml
tomcat/webapps/red5/WEB-INF/web.xml
2. 将webAppRootKey参数值该为/red5
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>/red5</param-value>
</context-param>
3. 打开root-web.xml文件
tomcat/webapps/red5/WEB-INF/classes/root-web.xml
4. 像下面这样在web.scope bean中更改contexPath和virtualHosts:
<property name="contextPath" value="/red5"
<property name="virtualHosts" value="*" />
如果你的部署有问题或者你的应用不能启动,优先用下面的步骤来检查故障。这些目录例子用了典型的windows路径结构。
1. 停止tomcat
2. 确定你的tomcat安装路径,C:\ProgramFiles\Apache\Tomcat
3. 删除“work”目录,C:\ProgramFiles\Apache\Tomcat\work
4. 从“conf”中删除“Catalina”,C:\ProgramFiles\Apache\Tomcat\conf\Catalina
5. 删除扩展的war目录如果存在
C:\Program Files\Apache\Tomcat\webapps\ROOT
C:\Program Files\Apache\Tomcat\webapps\echo
C:\Program Files\Apache\Tomcat\webapps\SOSample
6. 确认你的war文件在webapps目录中
C:\Program Files\Apache\Tomcat\webapps\ROOT.war
C:\Program Files\Apache\Tomcat\webapps\echo.war
C:\Program Files\Apache\Tomcat\webapps\SOSample.war
7. 重启tomcat
如果你的应用仍然有问题,在你快速的了解了其他人也经历同样的问题后收集下面的信息并向Jira邮递这个事件。
1) Java版本
2) Tomcat版本
3) 操作系统
4) Red5版本(0.6.2,Trunk,修订本2283等)