zoukankan      html  css  js  c++  java
  • 看张亚飞《.Net for Flash FMS》的笔记

    Flash Player有点像vs开发asp.net的内置的IIS,AIR(Adobe Integrated Runtime)则像.net的运行时Runtime。AS1、AS2、AS各种版本语法相差太多,它们之间除了名字有点联系外,几乎没有任何关系,而如.net有C#和VB一样,共用的是.net framework这个框架,他们共用AIR。

    浏览器接收和发送数据,我们可以用get/post方式提交数据,然后我们可以使用request对象对应的queryString属性或Form属性在提交到的页面获取提交的信息。注意中文字符用UTF-8去编码。

    同样的,asp.net网页与falsh的交互也可以使用get/post的方式,对于复杂的数据类型可以使用get方式构造一个xml格式的文本字符串返回给Flash。

    跳过http的请求与相应等相关知识,发现用navigateToURL函数可以使用“javascript:”伪协议调用网页中的javascript函数。但是这种方法由于种种限制或弊端,一般不会用,而选择用externalinterface的call方法。

    externalinterface详情,可以去官网查看http://livedocs.adobe.com/flash/9.0_cn/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001653.html

    关于js与as互相如何调用,我做了一个例子,经过测试是可以的。

    --关于远程方法调用的问题

    使用FluorineFx开源的AMF-RPC。注:RPC——进程间通信

    Remoting技术:

    1.Remoting Channel:这是指客户端和服务端的通讯协议,如TCP、HTTP协议。

    2.Serializer:这是指在传输时采用何种格式来传输数据,如可以采用Binary,也可以采用SOAP来传输XML格式的数据。

    客户端的数据经过序列化,通过HTTP被传递到远程服务端。在服务端,一般会有一个代理(网管)接收并将数据逆序列化,从而执行位于服务端的方法并返回给客户端。

    AMF-RPC是目前最重要的Flash Remoting技术,传输时的数据格式是Action Message Format(简称AMF),目前有连个版本AMF0和AMF3,AMF3是AMF0的增强版本。

    简单的HTTP功能,我们可以用URLLoader,但是如果涉及到复杂的问题的时候,就麻烦了。所以,AMF-RPC的优点就体现在复杂的操作上。

    比如:

    易用:AMF-RPC可以对本地远程服务程序代码(Java、C#、PHP)的数据类型进行自动转换,既可以转换成Actionscript代码数据类型,也可以转回本地远程服务程序代码数据类型。

    高性能:AMF-RPC使用Action Message Format(AMF)将Flash影片应用程序和远程服务之间的通信信息序列化。AMF是一个二进制格式,通信更加快速。

    可扩展性:AMF-RPC设计集成了现有应用程序设计模式和最佳的开发实践,从而可以满足高度扩展性Flash网络应用程序设计要求。

    下载安装FluorineFX

    创建一个asp.net的一个应用程序

    将web.config文件添加几行代码,他将对该应用程序的请求都映射到FluorineFx.FluorineGateway这个HttpModule来处理。

    <?xml version="1.0"?>
    <configuration>
    <system.web>
    <compilation defaultLanguage="C#" debug="true" targetFramework="4.0">
    </compilation>
    <httpModules>
    <add name="FluorineGateway" type="FluorineFx.FluorineGateway,FluorineFx"/>
    </httpModules>
    <globalization requestEncoding="utf-8" responseEncoding="utf-8"/>
    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/></system.web>
    </configuration>

    引用FluorineFx.dll

    创建一个类

    using FluorineFx;//引用FluorineFX
    
    using System;
    
    
    
    namespace org.zhangyafei {
        
        [RemotingService()] //标明这个远程服务
        public class HelloWorld {
            
            public string sayHelloWorld(String arg) {
                return "嗨!AMF-RPC for .NET" + arg;
            }
        }
    }

    上面这个类里面写了一个带参数的方法,并返回一个string。

    以下是flash源文件的代码

    // [01]======================================================
    // 创建一个NetConnection实例并连接到网关
    var nc:NetConnection = new NetConnection();
    // 注册各种事件监听函数(可选)
    nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR,
                            asyncErrorHandler);
    nc.addEventListener(IOErrorEvent.IO_ERROR,
                            ioErrorHandler);
    nc.addEventListener(NetStatusEvent.NET_STATUS,
                            netStatusHandler);
    nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
                            securityErrorHandler);
    function asyncErrorHandler(evt:AsyncErrorEvent):void
    {
    trace(evt);
    }
    function ioErrorHandler(evt:IOErrorEvent):void
    {
    trace(evt);
    }
    function netStatusHandler(evt:NetStatusEvent):void
    {
    trace(evt);
    }
    function securityErrorHandler(evt:SecurityErrorEvent):void
    {
    trace(evt);
    }
    // 设置默认编码
    NetConnection.defaultObjectEncoding = ObjectEncoding.AMF3;
    nc.connect('http://localhost/zhangyadong2/gateway.aspx');
    
    //gateway.aspx作为一个远程服务的网管,此名称必须为此。gateway.html都不行。
    
    //通过反编汇工具发现FluorineFx.dll里面有个private class FluorineGateWay。
    
    
    // [02]======================================================
    // 定义响应及回调函数,这是异步调用的通用步骤
    var responder:Responder = new Responder(onResult,onError);
    // 回调函数用于处理结果和错误
    function onResult(re:Object):void
    {
    trace(re);
    }
    function onError(err:Error)):void
    {
    trace(err);
    }
    
    
    // [03]======================================================
    // 调用远程方法,并设置回调函数
    nc.call("org.zhangyafei.HelloWorld.SayHelloWorld", responder,
              ",可以执行中文的");

    //输出结果:"嗨!AMF-RPC for .NET可以执行中文的"

    //第一个是完全限定的类名,即命名空间下的HelloWorld类SayHelloWorld方法,最后一个参数“可以执行中文的”这个是参数

    //注意了,WebApplication有命名空间,而WebSite没有命名空间,WebApplication的类文件直接会被放在应用程序目录下。而WebSite的类文件则会放置在App_Code文件夹内,虽然放在了一个文件夹里,但是仍然是”根.类名.方法“的访问。

    //WebSite必须放在App_Code文件夹里

    Flash代码运行分为3个步骤

    1.使用Netconnection对象链接到远程服务网关,这个通过connect方法实现,在此之前应该使用defaultObjectEncoding属性或objectEncoding属性设置编码格式。注意,defaultObjectEncoding属性是静态成员。

    2.使用Responder对象定义一个响应,该响应用来指定回调函数用于处理返回的结果和错误。

    3.使用call方法调用远程服务方法,并将响应与某个Responder对象建立关联,从而当响应返回时就交由该对象进行处理。注意call方法指定的远程服务及其方法参数。远程服务名是完全限定的类名,完全限定意为着包含命名空间。

    此外,有个安全沙箱的问题。

    crossdomain.xml文件要放在根目录下,用来设置flash与web交互的权限

      <?xml version="1.0"?>
      <!DOCTYPE cross-domain-policy (View Source for full doctype...)>
    -<cross-domain-policy>
      <site-control permitted-cross-domain-policies="all" />
      <allow-access-from domain="*" secure="true" />
      <allow-http-request-headers-from domain="*" headers="*" secure="true" />
      </cross-domain-policy>

    另外,还要注意,在flash发布的时候,要把设置访问为”网络“,而不是”访问本地“

    调用远程服务

    WebService类

    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.Services;
    using FluorineFx;
    
    
    /// <summary>
    ///WebService 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    //若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 
    // [System.Web.Script.Services.ScriptService]
    [RemotingService()]
    public class WebService : System.Web.Services.WebService {
    
    
        public WebService () {
    
    
            //如果使用设计的组件,请取消注释以下行 
            //InitializeComponent(); 
        }
    
    
        [WebMethod]
        public string HelloWorld(string parm) {
            return "Hello World"+parm;
        }
        
    }

    flash源代码

    import flash.net.NetConnection;
    import flash.net.Responder;
    
    
    var nc:NetConnection=new NetConnection();
    
    
    NetConnection.defaultObjectEncoding = ObjectEncoding.AMF3;
    nc.connect('http://localhost/zhangyadong2/gateway.aspx');
    
    
    var responder:Responder = new Responder(onResult,onError);
    
    
    function onResult(re:Object):void
    {
    trace(re);
    }
    
    
    function onError(err:Object):void
    {
    for (var i:String in err)
    {
    trace(err[i]);
    }
    }
    
    
    nc.call("WebService.HelloWorld",responder,"nihao");
    
    //WebService是服务名称,即类名名称,不需要加asmx。

    输出:”Hello Worldnihao“

    传递参数的数据类型

     public Array sayHelloWorld(String arg)
     {
          string[] d = new string[2] { "df", "dsf" };
           return d;
    }

    当在应用程序这边写了一个返回数组的方法的时候,ActionScript是这样调用的:

    // 回调函数用于处理结果和错误
    function onResult(re:Object):void
    {
    qq.text=("用户名:"+re[0].toString()+"密码:"+re[1].toString());
    }

    在测试falsh的时候,用上trace()进行弹出,方便排错。

    AMF-RPC的工作原理:

    在服务端,AMF-RPC是作为一ASP.NET网络应用程序的一个前端组件,他处理从ActionScript到.NET应用程序服务器的数据类型转换。准确的说,AMF-RPC是一个代理网关,客户端的Flash应用程序对服务端ASP.NET网络应用程序的请求都必须经过该代理网关进行处理。

    在网关收到服务请求之前,该请求必须先通过过滤装置处理串行数据,日志和安全检验,最后到达一个服务适配器,服务适配器被用来处理服务和启动类型。

    FluorineFX的服务适配器就是“.NET类适配器”。

    分析:

    当运行于Flash Player中的Flash影片应用程序(或Flex应用程序)发出调用请求后,Flash Player首先将调用的消息序列化为AMF格式,然后通过HTTP请求发送给服务器。位于服务器的网关(http://localhost/fluorine/gateway.aspx)对AMF格式的消息进行逆序列化,获取远程服务调用信息,并执行对远程服务中方法的调用。接着,网关将执行结果序列化为AMF格式,并将其返回给客户端的Flash Player,Flash Player逆序列化这一响应数据,并交与Flex应用程序或Falsh影片应用程序。一般用于处理响应的都是一个“回调函数”。

    AMF(Action Message Format)是一种二进制的信息编码格式。

    AMF符合Simple Object Access Protocol(SOAP)协议格式,它使用信息包格式分段传送信息。

    一个AMF信息包包含以下5个部分。

    1.信息包头,这一部分包含了AMF版本信息。

    2.上下文环境关系头计数。

    3.上下文环境关系头配置。上下文环境关系头包含了一个一个独立的AMF信息应当怎样被处理的描述信息。

    4.信息计数。

    5.信息配置。

    在客户端,服务端方法请求被使用NetConnection类的方法自动序列化为AMF格式;在服务端,AMF-RPC逆序列化AMF信息。

    一次交互的过程,经过两次个格式转换。

    VO(Value Object,值对象)

    它是一些特定对象的统称,这些对象主要是由它们的属性的值来定义,通常不包含有任何业务方法。并且它们经常是不可变的,这意味着一旦它们被创建,就不能再更新了。

    用途:主要用于将某对象/层传递到其他对象/层,目的是用来通过减少网络对话,以加速层之间的数据交换。

    注意:VO通常包含有一组私有变量和获取这些变量的方法,并且必须是可序列化的,只有通过序列化才可以传递给其他对象/层。

    实现VO映射要做的第一件事情是调用flash.net.registerClassAlias函数注册ActionScript类。

    .net方要有一个类,Actionscript方也要有一个相同的类,交互的时候就会自动映射了。

    注意:registerClassAlias的注册名一定要和.net中的映射名对应。

    从.net映射到flash,在flash那边接收的是flash定义的类,不再是返回的.net类。相反也一样。

    他们的类名可以不一样,但是要使用配置文件建立映射。

    FluorineF允许为远程服务或者方法定义别名。这要修改配置文件。

  • 相关阅读:
    在阿里写了8年代码后,我才明白这些道理
    2017双11交易系统TMF2.0技术揭秘,实现全链路管理
    加入新公司快速进入状态的心得
    Kibana+ElasticSearch实现索引数据的几种查询方式
    记一次jenkins发生的无法判断字符串前后空格
    ansible-playbook调试
    记一次ansible-playbook jenkins传空格的标量导致删除了服务的主目录
    rabbitmq集群中队列的完整性
    html5分割上传实现超大文件无插件网页上传思路
    html5分割上传实现超大文件无插件网页上传功能
  • 原文地址:https://www.cnblogs.com/hougelou/p/2854451.html
Copyright © 2011-2022 走看看