flash socket 从头开始构建一个web即时通讯系统 - 客户端
flash中的socket? socket的构造 实例化一个socket对象,只需要一行代码: static var socket = new flash.net.Socket(); ? 主动方法和被动方法而剩下的工作便是把这个对象包装成合适接口供javascript调用了。这时候主要有两类方法,一类是主动性方法,由客户端直接发起的便是主动方法,比如connect、send就是主动方法。 另一类是被动方法,也就是服务器端发起,然后在客户端触发事件,并被调用的回调方法,比如connected、receive就是被动方法。 主动方法和被动方法直接决定了代码的结构,决定了javascript和flash的互操作方式。 ? 事件时序我们从事件时序上来看一下flash中socket的可能的一个过程: ? flash加载完毕我们先注册一个回调,在flash加载完毕的时候,获得一个通知,以便为下面的连接做一些设置和准备。 ? flash.external.ExternalInterface.call("setTimeout",jsScope + "loaded()"); ? 建立一个socket连接接着我们便使用下面的方法来建立一个socket连接 ? static function connect(host : String,port : String) { trace("Connecting to socket server at " + host + ":" + port); socket.connect(host,Std.parseInt(port));? } ? 这里的两个形参:host为ip或者域名,port为通讯的端口。trace为输入到flash控制台的方法。 ? flash socket在端口上是有限制的,仅被允许访问4502-4534这个网段里的端口。 ? flash socket在执行socket.connect(host,Std.parseInt(port))时,无论如何,会先访问843端口,如果843端口被监听,并且在连接上后接收到一个policy-file.xml的话,才会断开与843端口的连接,并与调用方法时指定的端口连接。 ? 如果flash没有正常得到这个policy-file.xml的话,从调用方法时指定的端口连接时刚连接上便获得这个policy-file.xml也是可以的。如果这两种情况下都没有获得policy-file.xml,那么通讯是不能继续的。这是flash特有的安全机制。 ? 关于这个安全机制,以及提供这个policy-file.xml服务器程序policyserver,我会在稍后的教程里详细介绍。 ? 连接失败如果flash没有顺利连接上服务器,或者超时,我们可以注册一个回调来获得连接失败的通知,已准备重连。 ? socket.addEventListener(flash.events.SecurityErrorEvent.SECURITY_ERROR,function(e) : Void { trace("SECURITY ERROR : " + ?e.text); flash.external.ExternalInterface.call("setTimeout",jsScope + "securityError('" +e.text+ "')",0); } ); ? 连接成功如果顺利连接上了,这时候,我们可以通过下面的代码来注册一个回调,得到连接状态更新的通知。 ? socket.addEventListener(flash.events.Event.CONNECT,function(e) : Void {? trace("Connected to server"); flash.external.ExternalInterface.call("setTimeout",jsScope + "connected()",0); } ); ? 发送消息下面我们便可以从flash发送消息给服务器了 ? static function send(msg) { if (socket.connected) { trace("Writing '" + msg + "' to server"); //socket.writeMultiByte(msg,"gb2312"); socket.writeUTFBytes(msg); socket.flush(); } else { trace("Cannot write to server because there is no connection!"); } }? 我们可以看到,这段代码里,我注释掉了socket.writeMultiByte(msg,"gb2312");此句代码。从字面意思上也可以了解,这里是使用了"gb2312"的编码来发送消息。 ? flash socket提供了丰富的方法,在以后的教程里,我会详细描述flash.net.Socket的每一个方法。 ? 获取消息如果服务器发送消息给客户端,我们也可注册一个回调来获取消息的内容 ? socket.addEventListener(flash.events.ProgressEvent.SOCKET_DATA,function(e) : Void { //var msg = socket.readMultiByte(socket.bytesAvailable,"gb2312"); var msg = socket.readUTFBytes(socket.bytesAvailable); trace("Received : " + msg ); flash.external.ExternalInterface.call("setTimeout",jsScope + "receive('" + msg + "')",0); } ); ? 这里和发送消息类似,我们可以使用不同的编码标准来解码我们获得的字节流。 ? 关闭连接在完成通讯以后,如果我们需要关闭这个socket连接的话,可以使用下面的主动方法。 ? static function close() { if (socket.connected) { ?? trace("Closing current connection"); socket.close(); } else { trace("Cannot disconnect to server because there is no connection!"); } } ? 连接断开在socket连接断开以后,我们可以注册一个回调来获得通知 ? socket.addEventListener(flash.events.Event.CLOSE,function(e) : Void { trace("Disconnected from server"); flash.external.ExternalInterface.call("setTimeout",jsScope + "disconnected()",0); } ); ? IO错误在通信过程中,如果有错误发生的话,我们可以这样来获得通知 socket.addEventListener(flash.events.IOErrorEvent.IO_ERROR,function(e) : Void { trace("IOERROR : " + ?e.text); flash.external.ExternalInterface.call("setTimeout",jsScope + "ioError('" + e.text + "')",0); } ); ? 完整的代码 //SocketBridge.hx ? class SocketBridge { ? ???????? static var socket = new flash.net.Socket(); ???????? ???????? static var jsScope; ? ???????? ??? static function main() { ?????????????????? ?????????????????? if (flash.external.ExternalInterface.available) { ?????????????????? ??? ?????????????????? jsScope = flash.Lib.current.loaderInfo.parameters.scope; ?????????????????? ?????????????????? if (jsScope == null) { ??????????????????????????? jsScope = ""; ?????????????????? } else { ??????????????????????????? jsScope += "."; ?????????????????? } ? ?????????????????? /* Calls the javascript load method once the SWF has loaded */ ?????????????????? flash.external.ExternalInterface.call("setTimeout",jsScope + "loaded()");???????????????????? ?????????????????? ?????????????????? // Set event listeners for socket ?????????????????? ?????????????????? // CONNECT ?????????????????? socket.addEventListener(flash.events.Event.CONNECT,function(e) : Void { ???????????????????????????????????? trace("Connected to server"); ???????????????????????????????????? flash.external.ExternalInterface.call("setTimeout",0); ??????????????????????????? } ?????????????????? ); ? ?????????????????? // CLOSE ?????????????????? socket.addEventListener(flash.events.Event.CLOSE,function(e) : Void { ???????????????????????????????????? trace("Disconnected from server"); ???????????????????????????????????? flash.external.ExternalInterface.call("setTimeout",0);??????????????????????????????? ??????????????????????????? } ?????????????????? ); ??????????????????????????? ? ?????????????????? // IO ERROR ?????????????????? socket.addEventListener(flash.events.IOErrorEvent.IO_ERROR,function(e) : Void { ???????????????????????????????????? trace("IOERROR : " +? e.text); ???????????????????????????????????? flash.external.ExternalInterface.call("setTimeout",0); ??????????????????????????? } ?????????????????? ); ? ?????????????????? // SECURITY ERROR ?????????????????? socket.addEventListener(flash.events.SecurityErrorEvent.SECURITY_ERROR,function(e) : Void { ???????????????????????????????????? trace("SECURITY ERROR : " +? e.text); ???????????????????????????????????? flash.external.ExternalInterface.call("setTimeout",0); ??????????????????????????? } ?????????????????? ); ? ?????????????????? // SOCKET DATA ?????????????????? socket.addEventListener(flash.events.ProgressEvent.SOCKET_DATA,function(e) : Void { ?????????????????????????????????????????????? //var msg = socket.readMultiByte(socket.bytesAvailable,"gb2312"); ?????????????????????????????????????????????? var msg = socket.readUTFBytes(socket.bytesAvailable); ?????????????????????????????????????????????? trace("Received : " + msg ); ?????????????????????????????????????????????? flash.external.ExternalInterface.call("setTimeout",0); ???????????????????????????????????? } ??????????????????????????? ); ? ?????????????????? /* Set External Interface Callbacks */ ?????????????????? ?????????????????? // connect(host,port) ?????????????????? flash.external.ExternalInterface.addCallback("connect",connect);????? ??? ???????? ?????????????????? ?????????????????? // disconnect() ?????????????????? flash.external.ExternalInterface.addCallback("close",close);?????? ??? ???????????????????????????????????? ?????????????????? ?????????????????? // send() ?????????????????? flash.external.ExternalInterface.addCallback("send",send);???????? ?? ?????????????????? ?????????????????? // log() ?????????????????? flash.external.ExternalInterface.addCallback("log",log); ? ???????? ??? } else { ?????????????????? trace("Flash external interface not available"); ???????? ??? }?? ? ??? } ??? ??? /** ???? * Connect to new socket server ???? * @param host The host the socket server resides on ???? * @param port The socket servers port ???? */ ??? static function connect(host : String,port : String) { ??? ???????? trace("Connecting to socket server at " + host + ":" + port); ?????????????????? socket.connect(host,Std.parseInt(port));??? ?????? ??? } ??? ??? /** ???? * Disconnect the socket ???? */ ??? static function close() { ??? ???????? if (socket.connected) { ??? ???????? ???? trace("Closing current connection"); ??????????????????????????? socket.close(); ?????????????????? } else { ??????????????????????????? trace("Cannot disconnect to server because there is no connection!"); ?????????????????? } ??? } ? ??? /** ???? * Write string to the socket ???? */ ??? static function send(msg) { ??? ???????? if (socket.connected) { ???????? ??? ???????? trace("Writing '" + msg + "' to server"); ??????????????????????????? //socket.writeMultiByte(msg,"gb2312"); ??????????????????????????? socket.writeUTFBytes(msg); ??????????????????????????? socket.flush(); ?????????????????? } else { ??????????????????????????? trace("Cannot write to server because there is no connection!");????????????????? ?????????????????? } ??? }??? ? ??? /** ???? * Log ???? */ ??? static function log(msg) { ??? ???????? trace("log : "+msg); ??? }?? ? } ? ? 编译我使用了开源的haxe来编译,你也可以通过http://haxe.org/file/hxinst-win.exe获取它。 ? 编写完SocketBridge.hx以后,你需要在同一个目录下建一个compile.hxml文本文件,它的内容是: ? -swf socket_bridge.swf -swf-version 9 -main SocketBridge ? 在安装过haxe的情况下,只要你双击执行compile.hxml,便可以在同一目录下获得编译出的socket_bridge.swf 。 ? 文章来自 http://blog.sina.com.cn/s/blog_a787bfa90101brvs.html(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |