2011年03月31日

来源:互联网 发布:遥感影像处理 知乎 编辑:程序博客网 时间:2024/06/03 13:00

   我是一个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[ importflash.events.SyncEvent;
   importflash.events.NetStatusEvent;
   importflash.events.MouseEvent;
   importflash.net.SharedObject;
   importflash.net.NetConnection;
   importmx.controls.Alert;
   private vartext_so:SharedObject;
   private varnc:NetConnection;
   private varrtmpGo:String;
   private vargood:Boolean;
   publicfunction 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);
    //加入连接的监听事件,以便根据连接返回的状态做相应处理
   } privatefunction 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 :");
    }
   }
   privatefunction 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;
    }
    }
   }
   privatefunction sendMsg (e:MouseEvent):void
   {
    text_so.setProperty("msg",textInput.text);
    //将新的信息存入共享对象
    textArea.htmlText+=text_so.data.msg+ "\n";
    //更新客户端的信息列表
   }]]>
 </mx:Script>
 <mx:VBox>
  <mx:TextAreaid="textArea" width="200" height="200"/>
  <mx:TextInputid="textInput"/>
  <mx:Buttonid="button" />
 </mx:VBox>
</mx:Application>

 

大致读一下代码,你会发现以下代码

  rtmpGo ="rtmp://localhost/FirstApp";//这里设置FMS服务器的连接地址,basicSO即为,
   //FMS安装目录下Applications下自己手动新建的一个文件夹名称,也是FMS的工程名,就是这么简洁,不可意议
    nc = newNetConnection( );//产生一个连接对象
    nc.connect(rtmpGo);//连接到上面的地址

是需要连接到某种服务器上,实际就是Flash MediaServer

正好我的电脑上有一个Flash Media Server2,就把它安装上,并查了一些相关资料,只要在安装目录的applications中创建一个FirstApp文件夹,这个服务就好了。

  在Flex中新建项目,进行测试,试了N多遍都以失败告终,即使看Flash Media Server2后台管理提示有连接。

那就继续在网上找资料又是一个一个实例的测试最后才发现,

只要在
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 支持将 intuint 对象作为整型发送出去,并支持只可在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 Server2支持flash.net.ObjectEncoding.AMF0; 不支持新的AMF3 。

后面我换用Flash Media Server3.5开发,把这两句去了,一样可以运行成功。。。

 

转自:http://weirhp.javaeye.com/blog/875594