Rich Internet Applications for SLA Research/FlashComm Database Interaction FlashComm
The Flash Communication Server code must be placed in a subfolder of the applications directory. The subfolder should be named AMFPHPChat, and the following code should be placed within a file named main.asc:
// AMFPHPChat - Server-side code (main.asc) load ("components.asc"); load ("NetServices.asc"); // application.onAppStart = function (info) { // program name constant application.appName = "AMFPHPChat"; // trace("In onAppStart"); // application.confId = 0; // trace("Begin sharing text"); // // get the server shared object textchat_so // this shared object is non-persistent and // it handles method invocations between clients // and the application's server-side methods application.AMFPHPChat_so = SharedObject.get("AMFPHPChat_so", false); // // initialize the history of the text share application.chat = ""; // chat text that the user sees application.chatTS = ""; // chat text that is sent to the database; "TS" = timestamp // // ************************************************************* // Netservices set-up: This creates a Flash Remoting connection // to the AMFPHP-enabled web server (e.g., Apache) and allows // the .swf to call a function in a PHP script, thereby working // around the crossdomain restrictions imposed on loadVars objects. // // http://www.amfphp.org for more information on the technology. // ************************************************************* NetServices.setDefaultGatewayUrl("http://DOMAINNAME/cgi-bin/" + application.appName + "/gateway.php"); // // Then, create the connection object without passing a response object parameter // to the method. The response object will be specified when the component's function // is called via the service object, myService, defined below. SS_AMFPHPChatConnection = NetServices.createGatewayConnection(); trace("SS_AMFPHPChatConnection: " + SS_AMFPHPChatConnection); }; // application.onConnect = function(clientObject, username) { // ** ACCEPT THE CONNECTION trace("the Server is connecting... (application.onConnect)"); trace("onConnect - clientObject: " + clientObject); // // Set the global user name for the UI Components gFrameworkFC.getClientGlobals(clientObject).username = username; // application.acceptConnection(clientObject, username); }; // // ************************************************************************** application.onConnectAccept = function(clientObject, username) { // requestSID() connects to the database and creates a new entry // in the chatText_SID table. SS_AMFPHPService = SS_AMFPHPChatConnection.getService("DBServices", new AMFPHPResult( clientObject ) ); trace("SS_AMFPHPService: " + SS_AMFPHPService); // startSession = function(aUsername, anotherUsername, aDateTime) { trace("startSession called; aUsername: " + aUsername + "; anotherUsername: " + anotherUsername + "; aDateTime: " + aDateTime); // // Call the service; callback is defined after all // application.{whatever} code has been defined, at // the end of this script. SS_AMFPHPService.nextSession(aUsername, anotherUsername, aDateTime); _global.startSessionInterval = setInterval(startSessionTO, 1000); }; // saveTextToDB = function () { trace("saveTextToDB called"); // // Call the service // trace("application.SID: " + application.SID + "; application.chatTS: " + application.chatTS); SS_AMFPHPService.saveChatText(application.SID, application.chatTS); _global.saveTextToDBInterval = setInterval(saveChatTextTO, 1000); }; // // this client method allows the researcher interface to call the AMFPHP service // for saving chat text: SS_AMFPHPService.saveChatText(application.SID, application.chatTS) clientObject.saveTextToDB = function () { trace("clientObject.saveTextToDB called"); // saveTextToDB(); }; // // this client method (for researcher use only) destroys the session ID information clientObject.destroySession = function() { destroySession(); } // // this SSAS method is called by CSAS in researcher .SWF destroySession = function() { _global.destroySIDInterval = setInterval(destroySIDTO, 1000); trace("SS_AMFPHPService.destroySid()"); SS_AMFPHPService.destroySID(); }; // trace("Client.ip: " + clientObject.ip); // application.confId++; trace("confId: " + application.confId); // if(application.confId == 1) { SSASDate = new Date(); application.startTimeDate = SSASDate; timeString = formatTime(SSASDate); firstLineMsg = "############################<BR>" + "### Chat Started (timestamp: " + timeString + ")<BR>" + "############################<BR>"; application.chat = firstLineMsg; // add text to queue for chat text storage in database application.chatTS = firstLineMsg; application.user01 = username; trace("application.user01: " + application.user01); }; // // make each client's name the user's name clientObject.name = username; // // The following method is invoked by client to signal that it is completely initialized/loaded. // This server-side script then passes any chat text added to the shared object before the // second or third (instructor) participant has connected. // clientObject.ready = function() { application.AMFPHPChat_so.send("startChat", application.chat); }; // clientObject.waiting = function() { trace("in clientObject.waiting; confId: " + application.confId); // // ** TODO: need to add another condition here // ** to signal application was never loaded before; // ** property of AMFPHPChat_so? (is it persistent presently?) if(application.confId == 2) { application.user02 = username; trace("application.user01: " + application.user01); trace("application.user02: " + application.user02); startSession(application.user01, application.user02, application.startTimeDate); }; }; // activateClients = function() { trace("application.AMFPHPChat_so: " + application.AMFPHPChat_so); application.AMFPHPChat_so.send("enterChat"); }; // // SSAS function to ring all clients' doorbells in response // to one client clicking her "doorbell" button. clientObject.doorbellRing = function () { trace("doorbellRing called"); application.AMFPHPChat_so.send("clientRing"); }; // // the client will call this function to get the server to accept // the message, add the user's name to it, and send it back // to all connected clients. clientObject.clientChatMessage = function(plainMSG, color) { trace("clientChatMessage has been called from client (AMFPHPChat_01)"); SSASDate = new Date(); timeString = formatTime(SSASDate); // msg = "<FONT COLOR=\"" + color + "\"><B>" + username + ":</B> " + plainMSG + "</FONT><BR>"; trace("msg: " + msg); // msgTS = "(" + timeString + ") " + "<FONT COLOR=\"" + color + "\"><B>" + username + ":</B> " + plainMSG + "</FONT><BR>"; trace("msgTS: " + msgTS); // application.chat += msg; application.chatTS += msgTS; trace("application.chat: " + application.chat); trace("application.chatTS: " + application.chatTS); application.AMFPHPChat_so.send("serverChatMessage", msg); saveTextToDB(); }; // application.onDisconnect = function(clientObject) { trace("disconnect: " + clientObject.name); // application.confId--; trace(".confId: "+application.confId); if(application.confId < 1) { application.chat = ""; application.chatTS = ""; }; }; // application.onAppStop = function (info) { trace("In onAppStop"); // /* TODO(?): Later versions of the application may include code to write the text from the chat to the database via a Remoting gateway (AMFPHP, at present) when application.onAppStop(info) is called. */ }; // // formatTime(aDate): called within clientObject.clientChatMessage(plainMSG, color), // which is within application.onConnectAccept function formatTime(aDate) { //theHours = "0" + aDate.getHours(); //theHours = theHours.substr(theHours.length - 2, theHours.length); //trace("theHours:" + theHours); // theMinutes = "0" + aDate.getMinutes(); theMinutes = theMinutes.substr(theMinutes.length - 2, theMinutes.length); // trace("theMinutes: " + theMinutes); // theSeconds = "0" + aDate.getSeconds(); theSeconds = theSeconds.substr(theSeconds.length - 2, theSeconds.length); // trace("theSeconds: " + theSeconds); // //timeString = theHours + ":" + theMinutes + ":" + theSeconds; timeString = theMinutes + ":" + theSeconds; trace("timeString: " + timeString); return timeString; }; // TIMEOUT = 2; // TIMEOUT is a constant to set the number of seconds before an AMFPHP call is sent again /** * generic AMFPHPResult object * used by all remoting calls * * NOTE: Response objects for individual remoting calls * are within the "application.{FUNCTION}" code where * AMFPHP services are called **/ AMFPHPResult = function ( client ) { // set the client object this.client = client; }; // /** * startSession wait function: startSessionTOInterval * * called in application.onConnect * within clientObject.PHPSID() */ startSessionTOCounter = 0; // startSessionTO = function( client ) { startSessionTOCounter++; // trace("startSessionTOCounter: " + startSessionTOCounter); // if (startSessionTOCounter > TIMEOUT) { clearInterval (_global.startSessionInterval); startSessionTOCounter = 0; trace("TRYING AGAIN - startSessionTOCounter: " + startSessionTOCounter); startSession(application.user01, application.user02, application.startTimeDate); }; }; // AMFPHPResult.prototype.nextSession_Result = function ( data ) { clearInterval (_global.startSessionInterval); application.SID = data; trace("application.SID: " + application.SID); trace("calling activateClients()"); activateClients(); }; // /** * saveChatText wait function * * called in application.onDisconnect * within clearSessionID() */ saveChatTextTOCounter = 0; // saveChatTextTO = function() { saveChatTextTOCounter++; trace("saveChatTextTOCounter: " + saveChatTextTOCounter); // if (saveChatTextTOCounter > TIMEOUT) { clearInterval (_global.saveTextToDBInterval); saveTextToDB(); }; }; // AMFPHPResult.prototype.saveChatText_Result = function ( data ) { clearInterval (_global.saveTextToDBInterval); trace("data: " + data); }; // /** * destroySID wait function * * called in application.onDisconnect * within clearSessionID() */ destroySIDTOCounter = 0; // destroySIDTO = function() { destroySIDTOCounter++; trace("destroySIDTOCounter: " + destroySIDTOCounter); // if (destroySIDTOCounter > TIMEOUT) { clearInterval (_global.destroySIDInterval); destroySession(); }; }; // AMFPHPResult.prototype.destroySID_Result = function ( data ) { clearInterval (_global.destroySIDInterval); trace("data: " + data); };