我是一个Flex的初学者,除了懂一点点AS的语法外,所有的特性都是不了解的。最近由于项目需要在WEB上开发及时通信,也就研究一下web上的及时通信技术,这些技术包括ajax,cometd,html5中的websocket,以及flash中的这流媒体技术。最后我选择flash,除了html5,我都做了实验,感觉都不能让我满意,最后决定试试Flash中的这种技术。
由于懂的太少,只好上网查资料了,网上的东西是真丰富呀,各种介绍都有,有用flash实现聊天室的,有用flash实现视频会议的,真的很诱人。。。
还是从简单的入手吧,就去看了一个聊天室的小程序。
程序代码如下:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="TextSO ();">
<mx:Script>
<![CDATA[ import flash.events.SyncEvent;
import flash.events.NetStatusEvent;
import flash.events.MouseEvent;
import flash.net.SharedObject;
import flash.net.NetConnection;
import mx.controls.Alert;
private var text_so:SharedObject;
private var nc:NetConnection;
private var rtmpGo:String;
private var good:Boolean;
public function TextSO ():void {
button.label="Send";
button.addEventListener (MouseEvent.CLICK,sendMsg);
//为发送按钮添加发送事件
rtmpGo = "rtmp://localhost/connect";
//这里设置FMS服务器的连接地址,basicSO即为,
//FMS安装目录下Applications下自己手动新建的一个文件夹名称,也是FMS的工程名,就是这么简洁,不可意议
nc = new NetConnection( );
//产生一个连接对象
nc.connect (rtmpGo);
//连接到上面的地址
nc.addEventListener (NetStatusEvent.NET_STATUS,doSO);
//加入连接的监听事件,以便根据连接返回的状态做相应处理
} private function doSO (e:NetStatusEvent):void {
good=e.info.code == "NetConnection.Connect.Success";
//判断是否为连接成功状态 //连接返回的状态有好几种,大家可以参看FMS的文档,很详尽
if (good)
//如果连接成轼,执行如下操作
{
text_so=SharedObject.getRemote("test",nc.uri,false);
//得到远程共享对象,false属性是设置共享的数据为非持久化的,
//即重启服务器后,先前的数据不会保存
text_so.connect (nc);
text_so.addEventListener (SyncEvent.SYNC,checkSO);
//为共享对象添加异步事件,这也是服务器同步处理多客户端最关键的地方,
//一个客户端进行了什么操作,其它客户端也会有相应的变化,就是通过此事件来完成的
} else { Alert.show("connect failed :");
}
}
private function checkSO (e:SyncEvent):void
{
for (var chng:uint; chng<e.changeList.length; chng++)
{ switch (e.changeList[chng].code)
{
case "clear" : break;
case "success" : trace (text_so.data.msg);
break;
case "change" :
//一个客户端改变数据会更新所有客户端
textArea.htmlText+=text_so.data.msg + "\n"; break;
}
}
}
private function sendMsg (e:MouseEvent):void
{
text_so.setProperty ("msg",textInput.text);
//将新的信息存入共享对象
textArea.htmlText+=text_so.data.msg + "\n";
//更新客户端的信息列表
} ]]>
</mx:Script>
<mx:VBox>
<mx:TextArea id="textArea" width="200" height="200"/>
<mx:TextInput id="textInput"/>
<mx:Button id="button" />
</mx:VBox>
</mx:Application>
大致读一下代码,你会发现以下代码
rtmpGo = "rtmp://localhost/FirstApp";//这里设置FMS服务器的连接地址,basicSO即为,
//FMS安装目录下Applications下自己手动新建的一个文件夹名称,也是FMS的工程名,就是这么简洁,不可意议
nc = new NetConnection( );//产生一个连接对象
nc.connect (rtmpGo);//连接到上面的地址
是需要连接到某种服务器上,实际就是Flash Media Server
正好我的电脑上有一个Flash Media Server 2,就把它安装上,并查了一些相关资料,只要在安装目录的applications中创建一个FirstApp文件夹,这个服务就好了。
在Flex中新建项目,进行测试,试了N多遍都以失败告终,即使看Flash Media Server 2后台管理提示有连接。
那就继续在网上找资料又是一个一个实例的测试最后才发现,
只要在
public function TextSO ():void
之前加上
NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0;
SharedObject.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0;
这两句就可以了。。
这是为什么呢?看看文档的说明吧。
Adobe AIR 和 Flash Player 9 提供两种不同的序列化格式:AMF3 和 AMF0。AMF3 是为 ActionScript 3.0 开发的默认序列化格式,与用于 ActionScript 1.0 和 2.0 的 AMF0 相比,AMF3 具有多种优点。AMF3 通过网络发送数据比 AMF0 更高效。AMF3 支持将 int
和 uint
对象作为整型发送出去,并支持只可在 ActionScript 3.0 中使用的数据类型,例如 ByteArray、XML 和 IExternalizable。AMF3 只能在 ActionScript 3.0 和使用 AMF3 编码的服务器(例如 Flex 2)中使用。
ByteArray、FileStream、NetConnection、NetStream、SharedObject、Socket 和 URLStream 类均包含一个 objectEncoding
属性,为该属性分配的常量来自 ObjectEncoding 类。objectEncoding
属性的行为因对象而异;每个类的 objectEncoding
属性描述更加全面地说明了其行为。
看来Flash Media Server 2支持flash.net.ObjectEncoding.AMF0; 不支持新的AMF3 。
后面我换用Flash Media Server 3.5开发,把这两句去了,一样可以运行成功。。。
转自:http://weirhp.javaeye.com/blog/875594