跳转到内容

用于 SLA 研究的富互联网应用程序/FlashComm 数据库交互 Flash

来自维基教科书,开放书籍,开放世界

创建 Flash 动画

[编辑 | 编辑源代码]

设置时间轴

[编辑 | 编辑源代码]

在 Flash MX 2004 中,创建一个包含以下图层、关键帧和标签的时间轴。

文件:AMFPHPChat-timeline-setup.png

注意,此动画的 ActionScript 将放置在 *CSAS* 图层中。

创建用户界面

[编辑 | 编辑源代码]

登录关键帧

[编辑 | 编辑源代码]

将用户界面元素添加到 *UI* 图层,使您的动画类似于此图像。

文件:AMFPHPChat-login-frame-UI.png

将界面元素命名如下

  • *用户名* 文本区域:*username_txt*
  • *密码* 文本区域:*password_txt*
  • *输入* 按钮:*enter_pb*
  • 底部文本区域:*output_txt*

等待关键帧

[编辑 | 编辑源代码]

添加一行文本,如本图像所示。

文件:AMFPHPChat-wait-frame-UI.png

聊天研究人员关键帧

[编辑 | 编辑源代码]

将用户界面元素添加到 *UI* 图层,使您的动画类似于此图像。

文件:AMFPHPChat-chat researcher-frame-UI.png

将界面元素命名如下

  • AudioConference 通信组件:*audioChat_mc*
  • SetBandwidth 通信组件:*bw_mc*
  • *响铃* 按钮:*bell_pb*
  • UserColor 通信组件:*userColor_mc*
  • 大型文本区域:*chat*
  • 单行文本区域:*chatIn*
  • *发送* 按钮:*chat_bt*

为以下按钮设置点击处理程序

  • *保存文本* 按钮:*writeSSText*
  • *结束会话* 按钮:*endSession*
  • *响铃* 按钮:*dingDong*
  • *发送* 按钮:*addText*

聊天主题关键帧

[编辑 | 编辑源代码]

按照聊天研究人员关键帧的说明操作,但应省略 *保存文本* 和 *结束会话* 按钮。动画应类似于此图像。

文件:AMFPHPChat-chat subject-frame-UI.png

添加 ActionScript

[编辑 | 编辑源代码]

以下 ActionScript 代码应添加到每个指示的关键帧。它应放置在 *CSAS* 图层中。

登录关键帧

[编辑 | 编辑源代码]
// AMFPHPChat - CSAS layer - login keyframe
//
//Needed classes
#include "NetServices.as"
//just for debugging purposes
#include "NetDebug.as"
#include "synchAndStatusHandler.as"
//
Microphone.prototype.onStatus = onStatusTemplate;
NetConnection.prototype.onStatus = onStatusTemplate;
NetStream.prototype.onStatus = onStatusTemplate;
SharedObject.prototype.onStatus = onStatusTemplate;
//
var appName:String = "AMFPHPChat";
//
// *************************************************************
// 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/" + 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.
AMFPHPChatConnection = NetServices.createGatewayConnection();
//
// Result handler for the AMFPHP call "AMFPHPService.validateUser"
// in validateUserAMF(), father below
loginAMFRequest = new Object(); 
loginAMFRequest.onResult = function(loginResult){
  // TODO: AMFPHP service needs to return value that
  // distinguishes between error/incorrect login as well as
  // researcher and subject logins
  trace("loginResult: " + loginResult);
  output_txt.text += loginResult + "\n";
  Key.removeListener(loginKeyListener);
  gotoAndStop("wait");
}
//Create the service used to access PHP code via AMFPHP
AMFPHPService = AMFPHPChatConnection.getService("DBServices");
// instantiate generic object to serve as key listener
loginKeyListener = new Object();
// 
loginKeyListener.onKeyDown = function() {
  if(Key.getCode() == Key.ENTER) {
    // validate user via function that
    // queries AMFPHP script
    validateUserAMF();
  };
};
//
Key.addListener(loginKeyListener);
// validate user via function that
// queries AMFPHP script
this.enter_pb.onRelease = function() {
  validateUserAMF();
};
// TO DO: Callback code (a la that in SSAS) needed
// to time out the validateUserAMF call to AMFPHP gateway
validateUserAMF = function () {
  trace("validating user");
  userIDValue = username_txt.text;
  trace("userIDValue: " + userIDValue);
  passwordValue = password_txt.text;
  trace("passwordValue: " + passwordValue);
  AMFPHPService.validateUser(loginAMFRequest, username_txt.text, password_txt.text);
};
//
stop();

等待关键帧

[编辑 | 编辑源代码]
// AMFPHPChat_03 - CSAS layer - wait keyframe
// VERSION DATE: 17APR2005
//
#include "NetDebug.as"
#include "synchAndStatusHandler.as"
load("components.asc");
// set globals and constants
RING_VOLUME = 30;
SESSION_MAX_LENGTH = 60;
// generic data object
_global.session = new Object();
// session.username from log-in input
_global.session.username = username;
_global.session.pwd = password;
trace("username: " + session.username);
trace("password: " + session.pwd);
// NetConnection code
// session.uri sets path to server-side application
_global.session.uri = "rtmp://127.0.0.1/" + appName + "/instance01";
trace("_global.session.uri: " + _global.session.uri);
//
// create connection object for components and shared objects
chat_nc = new NetConnection();
//
// connect connection object with FlashCom server
chat_nc.connect(session.uri, session.username);
// Set maximum scroll of chat textarea
chat.maxscroll = 1000;
trace("chat.maxscroll: " + chat.maxscroll);
//
// create remote (server-side) shared object: textchat
//
// textchat_so methods should be defined before connecting
// shared object with FlashCom server
AMFPHPChat_so = SharedObject.getRemote("AMFPHPChat_so", _global.session.uri, false);
AMFPHPChat_so.onSync = onSyncTemplate;
//
// AMFPHPChat_so.enterChat
// Function is to be called when set number of users
// have logged in and are waiting at the "wait" frame.
AMFPHPChat_so.enterChat = function() {
  trace("in enterChat");
  gotoAndStop("chat_researcher");
  // this code will have to be changed to decide whether to go
  // to the researcher interface or the subject interface
};
//
// connect shared object with FlashCom server
trace("wait; chat_nc: " + chat_nc);
AMFPHPChat_so.connect(chat_nc);
//
// Let FlashCom know app is waiting
chat_nc.call("waiting", null);
//
stop();

聊天研究人员关键帧

[编辑 | 编辑源代码]
// AMFPHPChat - CSAS layer - chat_researcher keyframe
//
writeSSText = function() {
  trace("writeSSText CSAS function, calling writeTextToDB on server");
  chat_nc.call("saveTextToDB", null);
};
//
endSession = function() {
  trace("endSession called");
  chat_nc.call("destroySession", null);
};
//
addText = function() {
  //trace("in addText - length: " + length(chatIn.text));
  if(length(chatIn.text) > 0) {
    // call clientChatMessage on server
    trace("calling clientChatMessage on server");
    userColor = new String(gFlashCom.userprefs.color);
    userColor = "#" + userColor.substr(2);
    trace("addText() - userColor: " + userColor);
    chat_nc.call("clientChatMessage", null, chatIn.text, userColor);
    // clear input line text
    chatIn.text = "";
    // maintain focus on input line
    Selection.setFocus("chatIn");
  };
};
//
// serverChatMessage function; called from SSAS (main.asc)
AMFPHPChat_so.serverChatMessage = function(msg) {
  trace("in serverChatMessage - msg: " + msg);
  chat.htmlText += msg;
  chat.scroll = chat.maxscroll;
};
//
// Chat updates on the server with msg upon connection.
// Chat will be blank for first user; subsequent users will get
// latest chat.maxscroll units of any chat text preceding their
// connecting. Chat text is cleared when user count reaches zero.
// Called from SSAS (main.asc)
AMFPHPChat_so.startChat = function(msg) {
  trace("in startChat - msg: " + msg);
  chat.htmlText = msg;
  // connect FCS UI components
  app_init();
};
//
// THIS NEEDS FIXING! As of 4-3-05, a user who rejoins the chat
// has her text color set to that of the other user. Perhaps persistent
// shared object needed?
//
// instantiate generic object to serve as color change listener
colorListener = new Object();
//
colorListener.onColorChange = function(){
  colorListener.color = gFlashCom.userprefs.color;
  trace("colorListener.color: " + gFlashCom.userprefs.color);
};
//
gFlashCom.userprefs.addListener(colorListener);
//
// instantiate generic object to serve as key listener
keyListener = new Object();
//
// define onKeyDown to trigger check for enter key
keyListener.onKeyDown = function() {
  if(Key.getCode() == Key.ENTER) {
    addText();
  };
};
//
Key.addListener(keyListener);
//
// create chat_doorbell sound
chat_doorbell = new Sound(this);
chat_doorbell.attachSound("doorbell.wav");
chat_doorbell.setVolume(RING_VOLUME);
chat_doorbell.stop();
trace("chat_doorbell: " + chat_doorbell);
//
// ring doorbell; calls SSAS, which then calls
// AMFPHPChat_so.clientRing on each client
dingDong = function() {
  trace("Ding Dong!");
  chat_nc.call("doorbellRing", null);
};
//
AMFPHPChat_so.clientRing = function() {
  trace("in clientRing");
  chat_doorbell.start();
};
//
app_init = function() {
  // connect UI component(s)
  //trace("bandwidth_mc.connect");
  trace("app_init; session.username: " + session.username);
  // userColor_mc.setUsername(session.username);
  userColor_mc.connect(chat_nc);
  bw_mc.setUsername(session.username);
  bw_mc.connect(chat_nc);
  audioChat_mc.setUsername(session.username);
  audioChat_mc.connect(chat_nc);
  Selection.setFocus("chatIn");
  historyScroll.setScrollTarget(chat);
  historyScroll.setScrollPosition(chat.maxscroll);
};
//
app_close = function() {
  //trace("app_close: closing...");
  chat.text = "";
};
//
// tell server-side scripts that client is ready
chat_nc.call("ready", null, sessionID);
//
stop();

聊天主题关键帧

[编辑 | 编辑源代码]

注意:*chat_subject* 关键帧可以使用与 *chat_researcher* 关键帧相同的代码,因为在没有 *chat_researcher* 关键帧中的 UI 按钮的情况下,无法访问文本写入和会话结束代码。

同步和状态处理程序代码

[编辑 | 编辑源代码]

注意:以下代码应放在名为 *synchAndStatusHandler.as* 的文件中。此代码在 Flash MX 2004 作者环境中用于调试。它报告所有同步消息(例如成功和错误)以及状态消息。可以添加代码以响应特定事件,例如连接错误或意外断开连接。

// AMFPHPChat
// *TEMPLATE* synchAndStatusHandler - CSAS/SSAS - "#include" file
//
onSyncTemplate = function (info) {
  trace("Data Synchronizing");
  // 
  // This structure may be used as a prototype for onSync handlers.
  //
  // First, loop through the array of objects with the IN operator
  // 
  for (name in info) {
    trace("[sync] Array Object #"+name+"  code("+info[name].code+","+info[name].name+")");
    // 
    // ::: switch to handle code values returned by the object
    // Place Custom Code Here
    // 
    switch (info[name].code) {
      case "change" :
        trace("::change of data by another client");
        // Place Custom Code Here
        //
        break;
      case "success" :
        trace("::successful change of data from this server");
        // Place Code Here
        //
        break;
      case "reject" :
        trace("::rejected SharedObject write operation");
        // Place Code Here
        //
        break;
      case "clear" :
        trace("::initialization of the SharedObject");
        // Place Code Here
        //
        break;
      case "delete" :
        trace("::deleted Attributes");
        // Place Code Here
    }
    // ::: End the switch, continue looping through the information object
  }
  // ::: End of onSync handler
};
//
function onStatusTemplate(info) {
  infoMessage_array = info.code.split(".");
  trace(" ** status message received for: "+infoMessage_array[0]+" **");
  trace(" ** "+new Date());
  trace("    |::: Level--> "+info.level);
  trace("    |::: Code --> "+info.code);
  //
  // Trace information properties 
  if (info.description != undefined) {
    trace("    |::: Description--> "+info.description);
  }
  if (info.details != undefined) {
    trace("    |::: Details--> "+info.details);
  }
  if (info.application != undefined) {
    trace("    |::: Application--> "+info.application);
  }
  switch (infoMessage_array[0]) {
    case "Application" :
      trace("    | ::::Application Messages");
      // Display script error messages
      if (infoMessage_array[1] == "script") {
        trace("    |::: Script Error Details.  Filename--> "+info.filename+"   Line--> "+info.lineno);
        trace(info.linebuf);
      }
      // Place Code Here
      break;
    case "Camera" :
      //   | :::: Handle Camera Messages
      // Place Code Here
      break;
    case "Microphone" :
      //    | :::: Handle Microphone Messages
      // Place Code Here
      break;
    case "NetConnection" :
      //    | ::: Handle NetConnection Messages
      if (infoMessage_array[2] == "Success") {
        trace("    |::* Connection accepted by server; continuing to load.");
        // Place (below) scripts to run when the connection has succeeded
      }
      if (infoMessage_array[2] == "Closed") {
        trace("    |::* Connection was closed; returning the user!");
        app_close();
      }
      // Place Code Here
      break;
    case "NetStream" :
      //    | :::: Handle NetStream Messages
      // Place Code Here
  }
  trace(" ** End Status Message for: "+infoMessage_array[0]+" **");
}

下一个FlashComm 数据库交互:FlashComm

华夏公益教科书