看张亚飞《.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的工作原理:

看张亚飞《.Net for Flash FMS》的笔记<一>_第1张图片

在服务端,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信息。

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





你可能感兴趣的:(.net,webservice,Flash,asp.net,actionscript)