8月 16
已在游戏项目中使用。
python关键源码
self.transport.write(struct.pack(‘!I’, len(value)))
self.transport.write(value)
代码中注释的地方,主要是启用了压缩和客户端发送也加了长度。想看研发历程的请看这里http://apsay.gearhostpreview.com/?p=1128
package { import flash.display.Sprite; import flash.events.TimerEvent; import flash.utils.Timer; public class Main extends Sprite { private var _server:ClientSocket; private var myTimer:Timer = new Timer(1, 1000); public function Main() { _server = ClientSocket.getInstance("localhost", 7001); _server.addEventListener(ClientSocketEvent.CONNECTED, _socketHandler); _server.addEventListener(ClientSocketEvent.DISCONNECTED, _socketHandler); _server.addEventListener(ClientSocketEvent.XML_DATA_OK, _socketHandler); } private function _socketHandler(event:ClientSocketEvent):void { // trace(event.type); switch (event.type) { case ClientSocketEvent.CONNECTED : myTimer.addEventListener(TimerEvent.TIMER, timerHandler); myTimer.start(); break; case ClientSocketEvent.XML_DATA_OK : _resultsData(event.data); break; } } public function timerHandler(event:TimerEvent):void { _server.writeSend("start.xml\r\n", ClientSocketEvent.XML_DATA_OK); } private function _resultsData(data:Object):void { // trace(data); try { var xmlFile:XML = new XML(data); trace(xmlFile.toXMLString()); } catch (err:Error) { trace(err.toString()); } } } } package { import flash.errors.IOError; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.SecurityErrorEvent; import flash.net.Socket; import flash.utils.ByteArray; public class ClientSocket extends Socket { protected static var instance:ClientSocket; protected static var initInstance:Boolean = false; protected const SINGLETON_MSG:String = "socket单例请用getInstance获得!"; private var _host:String = ""; private var _port:int = 0; private var _dataEventCount:uint = 0; private var _realDataCount:uint = 0; private var _readDataLen:Boolean = true; private var _dataLenByte:ByteArray = new ByteArray(); private var _dataContentLen:uint = 0; private var _readDataContent:Boolean = false; private var _dataContentByte:ByteArray = new ByteArray(); private var _resultsData:String = ""; private var _flushAry:Array = []; public function ClientSocket(host:String, port:int) { if(!initInstance) { throw Error(SINGLETON_MSG); } _host = host; _port = port; configureListeners(); logger("Connecting to socket server on " + _host + ":" + _port); } public static function getInstance(host:String = "localhost", port:int = 80):ClientSocket { if(!initInstance) { initInstance = true; } if(instance == null) { instance = new ClientSocket(host, port); } return instance; } private function configureListeners():void { // this.objectEncoding = ObjectEncoding.AMF3; // Security.loadPolicyFile("xmlsocket://" + _host + ":" + _port); this.connect(_host, _port); this.addEventListener(Event.CLOSE, _socketHandler); this.addEventListener(Event.CONNECT, _socketHandler); this.addEventListener(IOErrorEvent.IO_ERROR, _socketHandler); this.addEventListener(SecurityErrorEvent.SECURITY_ERROR, _socketHandler); this.addEventListener(ProgressEvent.SOCKET_DATA, _socketHandler); } public function get host():String { return _host; } public function get port():uint { return _port; } public function writeSend(params:String, dataType:String):void { var bytes:ByteArray = new ByteArray(); try { // bytes.writeObject(params); bytes.writeUTFBytes(params); // bytes.compress(); // this.writeUnsignedInt(bytes.length); this.writeBytes(bytes); } catch (e:IOError) { switch (e.errorID) { case 2002 : // reconnect when connection timed out if(!this.connected) { this.connect(_host, _port); logger("Reconnecting..."); } break; default : logger(e.toString()); break; } } this.flush(); _flushAry.push(dataType); // logger(_flushAry[_flushAry.length - 1]); } private function _socketHandler(event:Event):void { switch (event.type) { case Event.CLOSE : this.dispatchEvent(new ClientSocketEvent(ClientSocketEvent.DISCONNECTED)); logger("连接关闭.\n"); break; case Event.CONNECT : this.dispatchEvent(new ClientSocketEvent(ClientSocketEvent.CONNECTED)); logger("已连接.\n"); break; case IOErrorEvent.IO_ERROR : break; case SecurityErrorEvent.SECURITY_ERROR : logger("连接失败.\n"); break; case ProgressEvent.SOCKET_DATA : _dataEventCount++; trace(_dataEventCount); _readData(); break; } } private function _readData():void { if(_readDataLen) { // trace("_readDataLen:"+this.bytesAvailable); while(!(_dataLenByte.length == 4)) { this.readBytes(_dataLenByte, _dataLenByte.length, 1); } if(_dataLenByte.length == 4) { _dataContentLen = _dataLenByte.readUnsignedInt(); // trace(_dataContentLen); _dataLenByte.clear(); _readDataLen = false; _readDataContent = true; if(this.bytesAvailable == 0) { return; } } } if(_readDataContent) { // trace("_readDataContent:"+this.bytesAvailable); if(this.bytesAvailable != 0) { if(this.bytesAvailable < _dataContentLen) { this.readBytes(_dataContentByte, _dataContentByte.length, this.bytesAvailable); } else { this.readBytes(_dataContentByte, _dataContentByte.length, _dataContentLen); } if(_dataContentByte.length == _dataContentLen) { _parseDataReceived(_dataContentByte); _readDataLen = true; _readDataContent = false; } if(this.bytesAvailable > 0) { _readData(); } } } } private function _parseDataReceived(bytes:ByteArray):void { try { // bytes.uncompress(); bytes.position = 0; _resultsData = bytes.readUTFBytes(bytes.length); bytes.clear(); _realDataCount++; trace("\n:" + _realDataCount); switch (_flushAry[0]) { case ClientSocketEvent.XML_DATA_OK : // trace(_resultsData + ";\n"); this.dispatchEvent(new ClientSocketEvent(ClientSocketEvent.XML_DATA_OK, _resultsData)); // logger("XML_DATA_OK.\n"); break; } _flushAry.shift(); } catch (error:Error) { logger("解码失败"); } } private function logger(msg:String):void { trace(msg + '\n'); } } } package { import flash.events.Event; public class ClientSocketEvent extends Event { public static const CONNECTED:String = "connected"; public static const DISCONNECTED:String = "disconnected"; public static const XML_DATA_OK:String = "xmlDataOk"; private var _data:Object; public function ClientSocketEvent(type:String, data:Object = null) { super(type, true); this._data = data; } public function get data():Object { return _data; } override public function toString():String { return formatToString("ClientSocketEvent", "type", "bubbles", "cancelable", "data"); } override public function clone():Event { return new ClientSocketEvent(type, data); } } }
©panhezeng for 阿潘道,
2006-2023. 原文地址:https://apsay.com/2011/08/16/original-page-cruise-as3-socket-communication-implementation-code-backend-python-twisted/
本文遵循署名-非商业性使用共享协议,转载请注明。
本文遵循署名-非商业性使用共享协议,转载请注明。