我是一个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/FirstApp";//这里设置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开发,把这两句去了,一样可以运行成功。。。