在上一篇"基础-web即时通讯系统的四种实现"中,我们讨论了如何使用flash/actionscript,来实现socket/tcp,并使用开源的haxe来编译。而本文将介绍如何使用javascript调用编译出的flash来进行通讯。
我使用swfobject.js来加载我们编译出的flash文件——socket_bridge.swf。
swfobject.js是一种易用的、符合标准的在网页中嵌入flash对象的方法,你只需要在网页中引用一个小巧的js文件。你在网上可以很容易下载到它。
我们可以调用swfobject.js里提供的方法,来编写跨浏览器的加载flash的代码。
function initialFlash(){ var so = new SWFObject("socket_bridge.swf", "socketBridge", "800", "300", "9", "#ffffff"); so.addParam("allowscriptaccess", "always"); so.addVariable("scope", "socket"); so.write("flashcontainer"); }
这段代码的意义是,将socket_bridge.swf下载到浏览器端,并在id为flashcontainer的html元素下。并将对象名为socket的对象暴露给flash。
考虑到这里使用到了flashcontainer这个html元素,我们需要在这个html元素已经存在于dom以后才可以执行这段代码,比如在window.onload事件里。
onload=function(){ initialFlash(); }
我们需要在initialFlash执行前声明一个对象名为socket的对象。
var socket = { config :{ ip:"127.0.0.1", port:4502, flashcontainer:"flashcontainer", auto:true }, connect : function() { socket.flash.log("begin connect to session server"); socket.flash.connect(socket.config.ip, socket.config.port); }, send : function(msg) { if(socket.isConnected >= 1){ socket.flash.send(msg); } }, loaded : function() { socket.flash = document.getElementById("socketBridge"); socket.isConnected = 0; if(socket.config.auto){ socket.connect(); } }, connected : function() { socket.isConnected = 1; socket.flash.log("connected to session server"); }, close : function() { socket.flash.close(); socket.isConnected = 0; socket.flash.log("close connection"); }, disconnected : function() { socket.isConnected = 0; socket.flash.log("disconnected"); }, ioError: function(msg) { socket.flash.log(msg); socket.isConnected = 0; }, securityError: function(msg) { socket.flash.log(msg); socket.isConnected = 0; }, receive: function(msg) { //callback } };
这里有几处需要注意:
socket.config.auto为true时,flash文件socket_bridge.swf加载完毕时,自动调用socket.flash.connect连接本地的4502端口。
socket.flash.log为对flash的trace函数的封装,可以调用它向flash控制台写入一些调试信息。
socket.isConnected为socket连接的状态量,实际上在真实的聊天室里,连接完以后还需要登录和验证的一系列过程,所以用此变量来表示这些自定义状态。
有了这个socket对象,我们便可以在javascript里操作flash socket了。比如说:
socket.send("hello socket")
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <script src="js/swfobject.js"></script> <script> var socket = { config :{ ip:"127.0.0.1", port:4502, flashcontainer:"flashcontainer", auto:true }, connect : function() { socket.flash.log("begin connect to session server"); socket.flash.connect(socket.config.ip, socket.config.port); }, send : function(msg) { if(socket.isConnected >= 1){ socket.flash.send(msg); } }, loaded : function() { socket.flash = document.getElementById("socketBridge"); socket.isConnected = 0; if(socket.config.auto){ socket.connect(); } }, connected : function() { socket.isConnected = 1; socket.flash.log("connected to session server"); }, close : function() { socket.flash.close(); socket.isConnected = 0; socket.flash.log("close connection"); }, disconnected : function() { socket.isConnected = 0; socket.flash.log("disconnected"); }, ioError: function(msg) { socket.flash.log(msg); socket.isConnected = 0; }, securityError: function(msg) { socket.flash.log(msg); socket.isConnected = 0; }, receive: function(msg) { //callback } }; function initialFlash(){ var so = new SWFObject("socket_bridge.swf", "socketBridge", "800", "300", "9", "#ffffff"); so.addParam("allowscriptaccess", "always"); so.addVariable("scope", "socket"); so.write(socket.config.flashcontainer); } onload=function(){ initialFlash(); } </script> </head> <body> <textarea id="cmd" style="width: 400px; height: 300px;">socket.send("")</textarea> <input type="button" value="exec" onclick="eval(document.getElementById('cmd').value);" /> <div id="flashcontainer"></div> </body> </html>