package FlashChat { import flash.events.DataEvent; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; import flash.net.XMLSocket; import flash.utils.*; import flash.xml.XMLDocument; import flash.xml.XMLNode; import mx.controls.Alert; public class socketServer extends Object { private var host: String; private var port: int; //var parent; private var clientId: int; private var connectionActive: Boolean; private var incommings: Array; private var structure: Object; private var intervalId: uint; // data handling methods private var manageIncoming: Function; private var manageOutgoing: Function; private var decodeResponse: Function; private var handleError: Function; private var handleResponse: Function; public var sendRequest: Function; // connection methods and properties public var doConnect: Function; private var onConnect: Function; private var onDisconnect: Function; private var closeConnection: Function; //socket private var socket:XMLSocket; private var manageIncomingTarget: Function; private var manageIncomingHandler: Function; public function socketServer( newHost: String, newPort: int ): void { traceMsg( "[Instantiate]" ); traceMsg( "host........: " + newHost); traceMsg( "port........: " + newPort ); // main properties this.host = newHost; this.port = (newPort > 1024)? newPort: 9090; connectionActive = false; incommings = new Array(); structure = null; intervalId = 0; // data handling methods manageIncoming = socketServ_manageIncoming; manageOutgoing = socketServ_manageOutgoing; decodeResponse = socketServ_decodeResponse; handleError = socketServ_handleError; handleResponse = socketServ_handleResponse; sendRequest = socketServ_sendRequest; // connection methods and properties doConnect = socketServ_doConnect; onConnect = socketServ_onConnect; onDisconnect = socketServ_onDisconnect; closeConnection = socketServ_closeConnection; //socket socket = new XMLSocket(host, port); //socket['chat'] = this; socket.addEventListener(Event.CONNECT, onConnect); //socket.addEventListener(Event.CLOSE, onDisconnect); socket.addEventListener(DataEvent.DATA, manageIncoming); socket.addEventListener(IOErrorEvent.IO_ERROR, function(): void { Alert.show('Can not connect to socket server'); }); socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function(): void { Alert.show('Socket server: security error'); }); //socket['clientId'] = 0; } private function socketServ_closeConnection(): void { //send to server message about close connection //sendRequest( structure, socket ); } private function socketServ_doConnect(): void { traceMsg( "doConnect:" ); traceMsg( "host.....: " + host ); traceMsg( "port.....: " + port ); if( !socket.connect( host , port ) ) { connectionActive = false; //connection failed traceMsg("Connection failed."); } else traceMsg( "Connecting for client." ); } private function socketServ_onConnect( success: Boolean ) : void { traceMsg( "onConnect:" ); if( success ) { traceMsg( "Connection successful for client #" + clientId ); connectionActive = true; clearInterval(intervalId); intervalId = setInterval(sendFirst, 500); } else { traceMsg( "Connection failed for client #" + clientId ); connectionActive = false; structure = null; //handle error //chat.parent.ui.loggedout('Socket server connection failed.'); } } public function sendFirst(): void { clearInterval(intervalId); /*if(_level0.login != undefined) { parent.login(_level0.login, _level0.password, _level0.lang, _level0.room); } else*/ if(structure != null) { sendRequest( structure ); structure = null; } else { ChatManager.loadMessages(); } } public function socketServ_sendRequest( structure: Object ): void { traceMsg( connectionActive.toString() ); if( !connectionActive ) { this.structure = structure; doConnect(); return; } traceMsg( "sendRequest" ); var command: XMLDocument = new XMLDocument(); command.ignoreWhite = true; var request: XMLNode = command.createElement("request"); var elements: Array = new Array(); var textnodes: Array = new Array(); var i: uint = 0; for( var key: String in structure ) { if( key == 't' ) { elements[i] = command.createElement( key ); textnodes[i] = command.createTextNode( structure[key] ); request.appendChild( elements[i] ); elements[i].appendChild( textnodes[i] ); i++; } else { request.attributes[key] = structure[key]; } } command.appendChild( request ); traceMsg( command.toString() ); socket.send( command ); } private function socketServ_onDisconnect(): void{ traceMsg("Disconnect client #" + clientId.toString()); connectionActive = false; } private function setManageIncomingHandler( target: *, handler: Function): void { manageIncomingTarget = target; manageIncomingHandler = handler; } private function socketServ_manageIncoming( contents : Object ): void { traceMsg( "manageIncoming: " ); traceMsg( "type..........: " + contents.toString()); //create queque //chat.incommings.push( contents ); var evnt: Object = new Object(); evnt.target = {data: contents['data']}; ChatManager.load(evnt); //if(chat.incommings.length == 1) { //chat.manageIncomingTarget[chat.manageIncomingHandler]( true, contents ); } } private function socketServ_manageOutgoing(): Boolean { return true; } private function socketServ_decodeResponse( xmlobj: XMLDocument ) : Object { traceMsg( "decodeResponse" ); var currentNode: XMLNode = xmlobj.firstChild; var decoded: Object = new Object; while( currentNode ) { decoded[currentNode.nodeName] = currentNode.firstChild.nodeValue; currentNode = currentNode.nextSibling; } return decoded; } private function socketServ_handleResponse( response: Object): void { response = decodeResponse( response.firstChild ); traceMsg( "Handling response... Type: " + response.type ); switch( response.type ) { case "message": traceMsg("from: " + response.fromClientId + " to: " + response.toClientId + " done "); break; default: traceMsg( "Type: unrecognized response type ->> " + response.type ); break; } } private function socketServ_handleError(error: Event): Boolean { return true; } private function traceMsg( inText: String ): void { trace(' >> SocketServer >> ' + inText); } } }