简介
在上一篇"基础-web即时通讯系统的四种实现"中,我们讨论了如何使用flash/actionscript,来实现socket/tcp,并使用开源的haxe来编译。而本文将介绍如何使用javascript调用编译出的flash来进行通讯。
加载flash
我使用swfobject.js来加载我们编译出的flash文件——socket_bridge.swf。
swfobject.js是一种易用的、符合标准的在网页中嵌入flash对象的方法,你只需要在网页中引用一个小巧的js文件。你在网上可以很容易下载到它。
初始化flash
我们可以调用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事件里。
οnlοad=function(){ initialFlash(); }
封装flash socket
我们需要在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连接的状态量,实际上在真实的聊天室里,连接完以后还需要登录和验证的一系列过程,所以用此变量来表示这些自定义状态。
操作flash 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);
}
οnlοad=function(){
initialFlash();
}
</script>
</head>
<body>
<textarea id="cmd" style="width: 400px; height: 300px;">socket.send("")</textarea>
<input type="button" value="exec" οnclick="eval(document.getElementById('cmd').value);"
/>
<div id="flashcontainer"></div>
</body>
</html>