}
}
]]>
3.部署运行程序
进入 red5 的安装目录下的 webapps 下 ,复 制 test 文件夹,把复制的文件夹改名为chapter2,
singleton="true"
class="org.red5.samples.services.EchoService"
删除 chapter2\WEB-INF 目录下的文件夹。
把服务器项目下的 classes 目录下的文件夹 first 拷贝到 chapter2\WEB-INF 下。
把 red5-web.properties 中的/test 替换为/chapter2。
把 red5-web.xml 中 的
删除。
把 org.red5.server.webapp.test.Application 替换为 first.Application。
把 web.xml 中的
/test 替换 为
/chapter2
把 /tlds/c/WEB-INF/tlds/c.tld
删除
注 意 :webapps 下的文件夹名 chapter2,red5-web.properties 中的 chapter2,web.xml中的 chapter2
要保持相同,如果一个改了,其他的也改成相同的,所有以后的工程都这样。
重新启动 red5
在 flexbuilder3 中选择运行菜单中的运行项运行 chapter2。在文本框里输入字符串,点击连
接按钮,然后点击调用方法按钮。上面如果显示出输入框里的字符串的大写表示运行正常。
服务器端类有俩个方法,appConnect 类从 ApplicationAdapter 继承来,当 flash 连接时触发,
可以返回 true 或 false。True表示接受客户端的请求,false 表示拒绝客户端的请求。如果拒绝那么以后
flash 和服务器端的交互服务器都不会理会,所以当想拒绝某些ip 的请求时只需有在用户连接时检查它的ip
是否在拒绝 ip 之内,如果在就返回 false,那样就可以拒之门外了。change 是自己定义的,客户可以直
接调用的一个远程方法。作用是把客户传入的参数变成大些后返回,此处目的在于运行一个 red5 和 flex
交互的过程,并没有检查传入的参数是否有大写或都已经是大写。
客户端的代码稍多些,位于 之外的是图形界面的
代码,包括俩个按钮,一个输入框,一个显示文本,这就不详细讲解了,注意给按钮添加事件监听器。过
程是这样的,用户点击连接,按钮的监听器 clickConnect响应,conn.connect(rtmpURL)连接到服务
器,在服务器和客户端建立一条信息交流的通道。当这条通道打通时 netStatus 执行,把是否是打通的开
关 isConnectSuccess 设置为通的。当用户再点击调用按钮时,通过这条通道调用服务器端的方法
conn.call("c hange",responder,str.text) 。传给服务器字符串 str.text,当服务器端方法执行完后把返
回值给 responder 定义时的方法 resultFun,这样一个客户端与服务器交互的过程完成。
三.远程调用
通过 red5 服务器端和客户端可以直接通过方法调用来交互,这是非常方便的(想想你在一
作者:周英科 email:li_li_li87222@163.com.qq:543246541 5
个类里面方法调用发方便性吧),服务器调可以用客户端的方法,客户端也可以调用服务器
端的方法。其实上面的例子就是通过方法调用实现的。
1.客户端调用服务器端方法
通过 red5 可以从客户端直接调用服务器上 java 编写的方法。调用时指明被调用的方法
名称,如果有返回值则需要指明返回值处理的 responder,如果被调用的方法有参数则需要
"change"
"change"
传入参数。 可以引用第一章的例子,conn.call("change"
"change",responder,str.text);
public
public
表示客户端调用服务器端的名称为change的方法,查看 java 中 change的定义public
public String
change(String str){//函数体 }发现参数是 java 中 String 类型的;调用时传入的 str.text 是
actionscript 中 String 类型;假如 change 有多个入口参数,则可以把参数列在 str.text 后 面 ,
并用''," 隔开。返回值由 responder 处理,change 返回值是 String 类型的,要求 responder 定义
时的函数 resultFun 的入口参数是 String 类型。
调用过程中需要注意的是参数类型的对应。具体可以看下列表
Java
null
int/float
double
boolean
String
List
Map
Bean
actionscript
null
Number
Double
Boolean
String
Array
Object
Object
表说明假如 java 传给 flash 的参数是自定义 Bean类型时,客户端接收到的是 Object 类型
当被调用的方法没有返回值时把 responder 设置为 null 。具体怎么实现就不再雷述,请
看第二章的例子。
2.服务器调用客户端方法
不带返回的调用
新建 eclipse 工程 chapter3,并建 立 包 first ,在 包 里 新 建 一 个 类 Application 并继 承
ApplicationAdapter。Application 到代码如下:
package first;
import org.red5.server.adapter.Applic ationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.service.IServiceCapableConnection;
public class Application extends ApplicationAdapter {
@Override
public boolean appConnect(IConnection arg0, Object[] arg1) {
// TODO Auto-generated method stub
callClient(arg0);
return true;
}
private void callClient(IConnection conn){
if (conn instanceof IServiceCapableConnection) {
IServiceCapableConnection sc = (IServiceCapableConnection) conn;
sc.invoke("clientMethod", new Object[]{"One", 1});
作者:周英科 email:li_li_li87222@163.com.qq:543246541 6
}
}
}
复制 webapps 下的 chapter2 文件夹,并改名为 chapter3,把工程下 class 目录下的 first 拷贝覆盖以前
的 first , 把 red5-web.properties 中的 /chapter2,替换为 /chapter3。把 web.xml 中的
/chapter2替换为/chapter3
重启 red5。
新建 chapter3 客户端项目,chapter.mxml 代码如下:
点击调试程序运行客户端,然后点击连接按钮可以发现输出“接收 One2”表示服务器调用
客户端到方法成功。
服务器端还是只有俩个方法,当客户端连接时服务器调用 appConnect,在 appConnect里
调用 callClient 。在callClient 中服务器调用客户端的方法 clientMethod,并传给客户端俩个参数,一个
字符类型,一个数字类型。只有IServiceCapableConnection 类型的连接才可以调用客户端方法,所以
要先对连接类型进行强制转换。
再看客户端,有三个方法,因为不需要处理连接状态的变化事件所以用个空方法以便简单突出重点。用
户点击按钮连接,调用 clickConnect 方法连接服务器。还有一个方法给服务器调用的,这个方法附着在
conn.client 上。因为 ActionScript3 中 NetConnection 是封闭的,无法直接把方法附着在其上,但他
的一个属性 client 是 Object 类型的,是动态的。
服务器不但可以调用客户端的方法,还可以把客户端方法处理的值返回给服务器。
作者:周英科 email:li_li_li87222@163.com.qq:543246541 7
理服务器调用客户端方法有返回值就就必须实现 IPendingServiceCallback 接口,并调用方式
改 为 sc.invoke("clientMethod", new Object[]{"One", 1},this);this 是 任 意 一 个 实 现
IPendingServiceCallback 接口的类,在接口的 resultReceived 方法中处理返回值。现在把上面
的类改成下面样子
package first;
import org.red5.server.adapter.Applic ationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.service.IPendingServiceCall;
import org.red5.server.api.service.IPendingServiceCallback;
import org.red5.server.api.service.IServiceCapableConnection;
public class Application extends ApplicationAdapter implements IPendingServiceCallback{
@Override
public boolean appConnect(IConnection arg0, Object[] arg1) {
callClient(arg0);
return true;
}
private void callClient(IConnection conn){
if (conn instanceof IServiceCapableConnection) {
IServiceCapableConnection sc = (IServiceCapableConnection) conn;
sc.invoke("clientMethod", new Object[]{"One", 1},this);
}
}
public void resultReceived(IPendingServiceCall arg0) {
System.out.println(" 来自客户端到返回:"+arg0.getResult());
}
}
把客户端的
private function clientMethod(str:String,num:Number):void{
Alert.show("接收"+str+(num+1));
}
改成
private function clientMethod(str:String,num:Number):String{
Alert.show("接收"+str+(num+1));
Return "客户端返回来的字符串";
}
测试可以从 red5 的框里看到输出“客户端返回来的字符串"
3.遍历所有连接到服务器端的用户
遍历所有链接到服务器的客户端是常常的事,如好友上线,则要及时把这个消息通知给
在线的人员。
Red5 通过 IConnection.getscope()得到所在 scope,通过 scope 可以得到连接到这个 scope
的所有客户的连接。在得到连接后就可以通过连接调用客户端方法。如调用每个客户端的
clientMethod 方法一遍可以把服务器改成下面的样子
package chapter2;
import java.util.Iterator;
作者:周英科 email:li_li_li87222@163.com.qq:543246541 8