Flash 与服务器端通信简介

Flash 与服务器端通信简介

Flying
2013-06-16 / 0 评论 / 158 阅读 / 正在检测是否收录...

无论是传统的 Web 应用程序还是 RIA 很多时候需要和服务器连接。当我们用 Flash 进行典型的三层开发时,Flash 播放器取代了传统层客户端浏览器。所谓 Flash 与服务器端的通信,就是指 Flash 如何跟逻辑层的服务器端编程语言交换数据。

概述

我们可以把整个服务器端的程序当成一个黑盒子,不用去了解它怎样连接数据库,又如何存取数据表的内容。但是我们必须知道它如何处理结果显示在 Flash 客户端。

dc_3_tiers.gif

不论你采用那种技术来开发服务器端程序,都应该遵守以下原则:

  • 接受资料的客户端是 Flash,不是浏览器,因此动态网页中不要有 HTML 标签。
  • 所有传给服务器端的数据,必须使用“名称-值”配对的格式或 XML 格式(下次再讲)
  • Flash MX 及更高版本输入/输出的数据的编码格式是 UTF-8(Unicode),所以输入 Flash 的数据必须经过 UTF-8 编码才能正确显示中文。一般将代码存成 UTF-8 格式就可以了, 也可以在 Flash 中指定 System 对象的 useCodepage 属性为 true 来编码。

什么是“名称-值”配对?大家应该记得 Flash 读取的外部文件变量的格式吧。格式是:变量 1=变量值&变量 2=变量值。如 name = "jim"&age = "28",其中 name 和 age 都是变量,jim 与 28 分别为它们对应的值。多个变量用 &连接起来,类似于 URL 中查询字符串的格式。

注意:不管是“名称-值”的格式还是 XML 格式,值都是以字符串形式传递到 Flash 中。

只要遵循上述格式,就可以用任何一种后台语言输出适合 Flash 读取的动态数据。常见的有:

  • ASP 与 ASP.net 输出数据的格式:<%Response.Write("变量 1=变量值&变量 2=变量值")%>
  • PHP 输出数据的格式:<?php echo("变量 1=变量值&变量 2=变量值") ?>
  • JSP 输出数据的格式:<% out.print("变量 1=变量值&变量 2=变量值"); %>
  • ColdFusion 输出数据的格式:变量 1=变量值&变量 2=变量值

Flash 与后台连接方法很多,比如说使用 loadVariables 函数、LoadVars 对象、XML 对象、XML Socket 对象、Flash Remoting 和 Webservice。

其中 loadVariables 函数 Flash Player 4 就开始支持了,它只能接收字符串变量,没有属性方法,加之也没有事件处理函数,因此逐渐被遗弃了。 我们这里也就不再过多讨论它了,直接从 LoadVars 对象开始。

使用 LoadVars 实现 Flash 与服务器通信

从 Flash Player 6 开始,可以使用 LoadVars 对象来实现 Flash 与后台通信。同 loadVariables 函数一样,它只能接收 MIME 格式的字符串变量。而且遇 到特殊字符时,必须进行 URL 编码。

LoadVars 对象通过其 sendAndLoad 方法将对象中的属性变量发送(send)到指定的 URL,同时载入(load)服务端器的输出变量并将其放入 目标对象中。当然,发送和载入这两个过程可以分开进行。这就是 LoadVars 对象比 loadVariables 函数强大之处,另外一个强大之处在于:载入变量时,还可以通过 LoadVars 对象的 onLoad 事件来判断载入的结果是成功还是失败。请看下面的例子。

请在舞台上添加名为 name_ti 的 TextInput 实例,名为 msg_taresult_ta的 TextArea 实例和名为 send_btn 的 Button 实例。将下面的 ActionScript 添加到时间轴的第 1 帧:

1. 客户端

var submitListener:Object = new Object(); 
submitListener.click = function(evt:Object) { 
  var result_lv:LoadVars = new LoadVars(); 
  var send_lv:LoadVars = new LoadVars(); 
  send_lv.userName = name_ti.text; 
  send_lv.msg = msg_ta.text; 
  send_lv.sendAndLoad("http://localhost/service/echo.asp", result_lv, "POST"); 
  result_lv.onLoad = function(success:Boolean) { 
    if (success) { 
      result_ta.text = result_lv.resultVar; 
    } else { 
      result_ta.text = "连接到服务器失败"; 
    } 
  } 
} 
send_btn.addEventListener("click", submitListener);

说明:当用户单击下面示例中 Login 按钮实例时,将创建两个 LoadVars 对象:send_lvresult_lvsend_lv 对象从 name_timsg_ta 实例复制名称并将数据发送到 echo.asp。此脚本的结果将载入 result_lv 对象,服务器响应则显示在 TextArea 实例 (result_ta) 中。

2. 服务器端

前面说过,任何服务器端编程语言,只要按[变量/值]配对的格式输出纯文本文件就能和 Flash 连接。接下来我们就来看这个实例的服务器端代码。

  • ASP 版:
<%@LANGUAGE="VBscript" CODEPAGE="65001"%> 
<%Dim userName,msguser 
Name=Request.Form("userName") 
msg=Request.Form("msg") 
Response.Write "resultVar="&userName&"说:"&msg 
%>
  • ASP.NET 版:
<%@ Page Language="C#"%> 
<% 
string userName,msg; 
userName = Request.Form["userName"].ToString(); 
msg = Request.Form["msg"].ToString(); 
Response.Write("resultVar="+userName+"说:"+msg); 
%>
  • PHP 版:
<?php 
$userName=$_POST["userName"]; 
$msg=$_POST["msg"]; 
echo "resultVar=".$userName."说:".$msg
?>
  • CFM 版:
<cfparam name="userName" default="" type="any"> 
<cfparam name="msg" default="" type="any"> 
<cfoutput>resultVar=#userName#说:#msg#</cfoutput>
  • JSP 版:
<%@ page language="java" pageEncoding="UTF-8"%> 
<%String userName = request.getParameter("userName"); 
String msg = request.getParameter("msg"); 
out.print("resultVar="+userName+"说:"+msg); 
%>

你可能也注意到了,几乎没有改动 Flash 的代码,只是改动后台语言而已。可以看出用 Flash 作表示层的程序是具有很强的移植性的,这也是 RIA 的一大特点。下次我们将谈一谈怎样使用 XML 对象来实现 Flash 与服务器端的通信,敬请关注!

点击此处下载源代码。

使用 XML 实现 Flash 与服务器通信

从 Flash Player 5 开始,就可以使用 XML 对象来实现 Flash 与后台通信。Flash 浏览器与 XML 数据之间的直接进行数据交换,并且同 LoadVars 函数一样,都是以字符串形式传递的。后台语言作为 XML 数据和数据库的中介,负责将数据库的数据动态生成 XML,将 XML 变动的数据更新回数据库。如下图所示:

通信

XML 对象可比 LoadVars 对象高级多了,它处理的是 XML 元素,XML 元素本身有意义而且格式良好,利用我们和电脑识别, 它早已成为数据交换格式的标准。而 LoadVars 用来处理变量,LoadVars 中的变量很少有什么实际意义,如果用来读取数据库中的数据,变量会 很多。而 XML 对象就简单多了,与 XML 相关的技术很多,比如 DOM、SOM、SMLT、SAX2 等。即使你对这些技术不了解,你也可以用后台语言输出数据的方式来实现。

使用 XML 对象来实现 Flash 与后台通信,主要是通过 XML 对象的 sendAndLoad 方法。该方法和 LoadVars 的 sendAndLoad 方法 类似,它把指定的 XML 对象编码为 XML 文档,使用 POST 方法将其发送到指定的 URL,下载服务器的响应,并将其加载到参数中指定的 resultXMLobject 中。服务器响应加载的方式与 XML.load 方法使用的方式相同。

下面是一个简单的 ASP+ XML + Flash 查询实例。XML.sendAndLoad 方法传输一个包含学生姓名的 XML 包,并使用 onLoad 方法来处理来自服务器的响应。

1. 客户端

import mx.controls.Alert;
// 新建用来响应的 XML 对象
var response_xml = new XML();
// 响应时忽略 XML 空白
response_xml.ignoreWhite = true;
 
function showResult() {
  // 清除所有项目
  student_dg.removeAll();
  response_xml.onLoad = function() {
    var nodes = this.firstChild.childNodes;
    var len = nodes.length;
    if (len < 1) {
        Alert.show('没有搜索到相应的记录!', '提示信息');
    } else {
      // 将 XML 对象解析成项目对象
      for (var i = 0; i < len; i++) {
        student_dg.addItem({
          学号 : nodes[i].attributes.id,
          姓名 : nodes[i].attributes.name,
          班级 : nodes[i].attributes.cname
        });
      }
    }
  }
}
// 新建用来发送请求的 XML 对象
var request_xml = new XML();
// 创建一个新的 元素 search
element = request_xml.createElement('student');
 
function click() {
  // 将输入的学生姓名赋值给 search 元素 name 属性
  element.attributes.name = name_ti.text;
  // 将 search 元素追加到 对象中
  request_xml.appendChild(element);
  // 传输一个包含学生姓名的 XML 包
  request_xml.sendAndLoad('http://localhost/student/search.asp', response_xml);
  showResult();
}
search_btn.addEventListener('click', this);

2. 服务器端

后台以 ASP 为例,ASP 要能读取 SWF 文件请求的 XML 元素,得用 XML DOMDocument,这就要求服务器必须安装有 MSXML2.DOMDocument 组件。至于 ASP 怎样输出动态 XML 文件,可以用 ASP 的 Response.Write 方法,当然同样也可以用 XML DOMDocument 对象来实现。不过,理论上前者的速度会快些。

  • ASP 版:
<%@LANGUAGE="JAVASCRIPT" CODEPAGE="65001"%>
<% 
// 建立 XML DOM 对象 
var doc = new ActiveXObject("MSXML2.DOMDocument"); 
doc.async =false; 
var requestXml=Request.Form(); 
// 判断是否接收到 SWF 文件传过来的 XML 包 
if(requestXml.Count >0){ 
  // 加载 XML 包 
  doc.loadXML(requestXml); 
  // 取得根元素 
  var rootNode = doc.documentElement; 
  // 取得根元素的 name 属性值 
  var name = rootNode.attributes[0].nodeValue; 
  // 设定为 XML 文件 
  Response.ContentType="text/xml"; 
  // 输出 XML 文件声明 
  Response.Write('<?xml version="1.0" encoding="UTF-8"?>'); 
  var conn = new ActiveXObject("ADODB.CONNECTION"); 
  strconn = "DBQ="+Server.MapPath("Exam.mdb")+";Driver={Microsoft Access Driver (*.mdb)};"; 
  conn.Open(strconn); 
  var rs = new ActiveXObject("ADODB.RECORDSET"); 
  var sql = "Select StudentID,Name,ClassName FROM Student Where Name LIKE &'"+name+"%&'"; 
  rs.Open(sql,conn,1,1); 
  var i=0; 
  // 输出根标记 
  Response.Write("<item>"); 
  while(!rs.EOF){ 
    // 输出子元素及其属性 
    Response.Write("<student id=\""+rs("StudentID")+"\" name=\""+ 
    rs("Name")+"\" cname=\""+rs("ClassName")+"\"/>"); 
    i++; 
    rs.MoveNext();    
  } 
  Response.Write("</item>"); 
  rs.Close(); 
  conn.Close(); 
}
%>

点击此处下载附件,该附件中还包含此实例的各版本后台脚本。

ASP.NET 版:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Data.OleDb" %> 
<script runat="server">
private void Page_Load(object sender, System.EventArgs e) {
  Stream inStream = Request.InputStream;
  if (inStream.Length > 0) {
    XmlReader reader = XmlReader.Create(Request.InputStream);
    reader.ReadToFollowing("student");
    string name = reader.GetAttribute("name");
    reader.Close();
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = true;
    XmlWriter writer = XmlWriter.Create(Response.Output, settings);
    writer.WriteStartElement("item");
    string sqlStr = "Select StudentID,Name,ClassName FROM Student" +
      " Where Name LIKE '" + name + "%'";
 
    using(OleDbConnection connection = new OleDbConnection(sqlStr, con)) 
    {
      OleDbCommand cmd = new OleDbCommand(sqlStr, con);
      connection.Open();
      OleDbDataReader dr = command.ExecuteReader();
      while (dr.Read()) {
        writer.WriteStartElement("student");
        writer.WriteAttributeString("id", dr[0].ToString());
        writer.WriteAttributeString("name", dr[1].ToString());
        writer.WriteAttributeString("cname", dr[2].ToString());
        writer.WriteEndElement();
      }
      writer.WriteEndElement();
      writer.Close();
      dr.Close();
    }
  }
} 
</script> 

因为我们只是对 XML 数据进行查询, 所以好使用 XMLReader 和 XmlWriter 类, 它们可以提供对 XML 文件快速、 非缓存、 只进读写, 所以速度比用 XmlDocument 类快得多。 而且它不需要服务器安装有 MSXML2.DOMDocument 组件, 其扩展性更强。

我租用的服务器就没有安装这个组件, 怪不得我用 ASP 作为后台在服务器运行会出错。 实际上, 大家看到的 Demo 的后台用的是 C#。

总结

注意:

  1. 测试 PHP 版时,由于使用了 $GLOBALS["HTTP_RAW_POST_DATA"] 全局变量,请打开 php.ini,将 always_populate_raw_post_data = On 前的 ; 去掉;这是一种不得以的方法,如果有哪位找到好方法,请告诉我一下。
  2. 对于 CF 版,因为在交换数据的过程中,CF 解析 XML 时不接受汉字。因此,我们需要在 Flash 中将要传送传送的参数进行 URL 编码,请将 name_ti.text 修改为escape(name_ti.text)

其实,我个人并不主张用 XML 来实现 Flash 与服务器端的通信,我宁愿用 LoadVars 和 Flash Remoting。

10

评论 (0)

取消