二、技术介绍
2、xmlsocket 对象
实现了客户端socket(套接字),允许包含flash应用的浏览器与服务端建立socket连接,之后flash应用与服务端就可以相互发送xml数据,而且在一个socket连接建立之后,在该连接上传送的数据量是没有限制的,直到socket连接关闭。
使用xmlsocket 对象时,必须要注意两点:
o 在socket连接上发送的xml数据,每条数据以一个0字节隔开,详见下面服务端的建立。
o flash 应用所连接的主机必须是与相应web服务器在同一ip地址或是同一子域。所谓同一子域是指在同一域名空间中,例如包含flash应用的网页是从mail.real-ok.com下载的,则name.mail.real-ok.com就是子域,就允许建立连接,而real-ok.com不是子域,flash的安全规则就不允许建立连接。
使用xmlsocket 对象的流程为:
1) 建立一个xmlsocket 对象
mysocket = new xmlsocket();
2) 对生成的xmlsocket 对象进行设置
mysocket.onconnect = myonconnect;
mysocket.ondata = myondata;
mysocket.onxml = myonxml;
mysocket.onclose = myonclose;
以上四条语句,分别设置了mysocket的四个事件处理函数,其中,myonconnect、myondata、myonxml分别是带有一个参数的函数,myonclose不带参数,当发生相应的事件时,就调用相应的处理函数。
3) 使用xmlsocket 对象的connect方法,建立与服务端的连接mysocket.connect(null, 6666);
其中,connect方法有两个参数,第一个参数表示要连接的主机,可以是全限定的域名和者ip地址,需要注意一点:当使用ip地址时,如 127.0.0.1 需要把它当作字符串来处理,即要用引号把ip地址括起来。如果为null,则连接web服务器(从该web服务器下载了包含当前flash应用的网页)所在的ip地址。
第二个参数表示要连接的端口,由于低于1024的端口被通用程序所占,flash的安全规则不允许在低于1024的端口建立连接。connect方法返回布尔型变量true或false,表示连接是否成功。如:
if (!mysocket.connect(null, 2000)) {
mytextfield.text = “连接失败!”;
}
以上语句中,如果连接失败,connect方法返回flase,则把mytextfield(为一非静态文字textfield对象的实例)的内容设为“连接失败!”。
xmlsocket对象与服务端进行连接将触发onconnect事件,则相应的事件处理函数(见上面流程步骤2中的设置)myonconnect,其中的参数与connect方法的返回值意义相同,详见下面的客户端实例。
4) 当连接建立成功之后,客户端与服务端就可以相互发送xml数据了。使用xmlsocket 对象的send方法向服务端发送数据:
mysocket.send(myxml);
其中,myxml是一个包含xml数据的xml对象,send方法先把myxml转化为字符串,然后将该字符串发送到服务端,并在字符串发送后,追加发送一个0字节。send方法没有返回值。
以下示例中,先生成一个空的xml对象myxml,然后在myxml中添加了一个元素节点mylogin,该节点包含两个属性username和password,send方法把myxml转化成字符串 后,发送给服务端,当然还要追加发送一个0字节,以表示一条xml数据的完成:
var myxml = new xml();
var mylogin = myxml.createelement(“login”);
mylogin.attributes.username = “morgan”;
mylogin.attributes.password = “loveme”;
myxml.appendchild(mylogin);
mysocket.send(myxml);
当有数据到达(收到一条以0字节为结尾的字符串)时,首先将触发ondata事件,相应的事件处理函数myondata带有一个参数,表示当时到达的数据字符串,但不包含0字节,如下例中,服务端传来一个字符串 “i am morgan yang !”,加上一个0字节,以下语句将把mytextfield(为一非静态文字textfield对象的实例)的内容设为“i am morgan yang !”,我们注意到这里发送的数据,可以是包括xml格式在内的任何形式:
function myondata(src) {
mytextfield.text = src ;
}
对于ondata事件,如果没有相应的事件处理函数,默认将触发onxml事件,形式如下:
xmlsocket.prototype.ondata = function (src) {
this.onxml(new xml(src));
}
即在onxml事件中,使用ondata事件中得到的数据生成一个xml对象,并把该对象作为参数传给onxml事件的处理函数,所以如果要自定义onxml事件的处理函数,服务端发送来的数据就必须是xml格式,否则就会发生意想不到的错误。如果设置了ondata事件的处理函数,当数据到达时,将不再调用onxml事件的处理函数,除非在显式地调用,所以在某种意义上,两种事件是互斥的。
在没设置ondata事件处理函数,又设置了onxml事件处理函数情况下,当有xml数据 到达时,以下语句将把两个非静态文字实例nametextfield和passwordtextfield的内容分别设为“morgan”和“loveme”:
function myonxml(doc) {
var e = doc.firstchild;
if (e != null && e.nodename == ” login “) {
nametextfield.text = e.attributes.username ;
passwordtextfield.text = e.attributes.password ;
}
}
5) 最后,在程序结束的时侯,使用xmlsocket 对象的close方法,关闭socket连接,如下:
mysocket.close();
需要注意的是,使用xmlsocket 对象的close方法,来关闭socket连接不触发xmlsocket对象的onclose事件,只有当socket连接被服务端关闭时,才在flash应用客户端触发该事件,默认情况下,xmlsocket 对象的onclose事件处理函数不执行任何动作,可以自定义该事件处理函数,以达到特定目的。如以下语句,在onclose事件发生时,把mytextfield(为一非静态文字实例)的内容设为 “socket closed by server !”
function myonclose() {
mytextfield .text = “socket closed by server !” ;
}