熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

用AJAX+J2EE實現一個網上會議室系統

2013-11-23 18:46:48  來源: Java核心技術 

  一系統實現的功能

  本會議室系統主要用於EasyJF開源團隊的成員網上會議使用會議系統模擬傳統的會議形式可以同時開設多個不同主題的會議室每個會議室需要提供訪問權限控制功能會議中能夠指定會議發言模式(分為排隊發言自由發言兩種)系統能自動記錄每個會議室的發言信息可以供參會人員長期查閱

  會議系統的用戶支持游客帳號參加會議同時也提供跟其它用戶系統的接口比如EasyJF官網中的開源論壇系統

  會議系統暫時使用文字聊天的方式並提供語音及視頻的接口

  二技術體系

  服務器端使用Java語言MVC使用EasyJWeb框架

  客戶端使用AJAX技術與服務器端交互數據

  會議歷史信息儲存格式使用文本格式方便系統安裝運行也便於管理

  三會議室服務器端設計

  會議室服務器端是整個會議系統的核心部分服務器端程序設計的好壞影響到整個系統的質量

  首先根據會議室要實現的功能進行抽象分析一個會議室對象應該包括會議主題會議簡介參會人數限制公告會議室類型訪問權限設定房間密碼當前參會的人員當前發言的人員排隊等待發言的人員等參數信息我們把他封裝一個Java對象當中如下面的ChatRoom代碼所示

  

  public class ChatRoom{ private String cid;//主鍵 private String title;//聊天室主題 private String intro;//聊天室簡介 private String announce;//聊天室公告 private String owner;//聊天室創建人 private Integer maxUser;//最大在線人數 private Integer intervals;//最大刷新時間間隔 private String vrtype;//訪問權限 private String vrvalue;//訪問值 private Integer status;//聊天室狀態 private Date inputTime; }

  需要一個管理會議室的類與會議有關的操作(如啟動會議關閉會議)等都直接找他該類還應該即有自動定時檢測用戶在線情況(防止用戶意外退出)把內存中的會議歷史發言信息保存到文本文件中等功能這裡可以考慮使用一個ChatService類提供這些功能

  

  public class ChatService implements Runnable { private static final Map service=new HashMap();//會議室服務系統中的當前會議室存放到
該表集合中 private static final int maxServices=;//可以同時開的最大會議室數 private static final SimpleDateFormat df=new SimpleDateFormat(yyyyMMdd); private final List msgs;//聊天信息Chat private final List users;//在線用戶ChatUser private final List talkers;//排隊發言人數Talker private final List manager;//會議室管理員 private Talker currentTalker;//當前發言人 public ChatService() { thismsgs=new ArrayList(); thisusers=new ArrayList(); thistalkers=new ArrayList(); thismanager=new ArrayList(); thismaxUser=;//最大人同時 thisinterval=**;//分鐘以前的信息 } }

  會議發言信息也需要封裝成一個類表示發言人接收人內容發言時間類型等大致如下面的Chat類

  

  public class Chat { private String cid; private String sender; private String reciver; private String content; private Date vdate; private Integer types; private Integer status; }

  還有表示參加會議的人的信息包括參會人名稱IP地址狀態等如下面的ChatUser類所示

  

  public class ChatUser { private String ip; private String port; private String userName; private Date lastAccessTime; private Integer status; }

  另外還需要一個表示當前發言人的Talker類表示當前的發言人發言開始時間發言預計結束時間等

  在服務器端的設計中會議室信息服務器應該能以多線程的方式運行即啟動一個會議就新開一個線程每個會議線程維護自己的會議狀態如參會人發言人保存會議歷史發言信息以及清空內存中的數據等操作

  四客戶端設計

  會議室客戶端包括兩個部分一個部分是會議室的管理界面主要包會議室的添刪改查啟動關閉會議服務的操作這部分我們直接使用EasyJWeb Tools中的添刪改查業務引擎AbstractCrudAction可以快速實現界面也比較簡單直接使用EasyJWeb Tools代碼生成工具引擎生成即可會議室管理的客戶端是傳統的Java Web技術因此沒有什麼要考慮的

  客戶端的第二個部分也即會議系統的主要部分該部分主要有兩個界面第一個頁面是會議室進入的選擇頁面也即把已經啟動的會議室列出來用戶選擇一個會議室進入這個頁面也是使用傳統的Java Web技術第二個頁面是進入會議室後的主界面這個界面是整個會議系統的主要界面所有參與會議的操作都在這裡運行的這個界面需要不斷的與服務器端交互傳輸數據傳輸的內容包括用戶的發言其它人給用戶的發言會議室的狀態等有的傳輸信息需要即時響應(如用戶發言)有的信息可以設置成定時響應(如會議室狀態)

  Java Web程序中與服務器端交互數據主要有兩種方式一種是直接刷新頁面另外一種是使用Socket直接跟Web服務器端口通訊由於Socket編程相對復雜我們選擇第一種直接刷新頁面的方式這種方式又可以分為幾種包括傳統的Form提交傳統的自動刷新網頁取得數據以及使用ActiveXObject對象(如xmlhttp)直接與服務器交互數據也即AJAX方式由於使用AJAX方式用戶感覺不到頁面在刷新表現起來好於手動或自動刷新頁面的方式因此我們決定選擇AJAX方式實現客戶端與服務器端進行數據交互

  用戶發言的時候直接使用xmlhttp對象Post數據到服務器為了能不斷接收到別人的發言信息需要定時不斷的從服務器端讀取數據因此需要在客戶端啟動一個定時器每隔一定的時候自動使用xmlhttp對象到服務器端下載別人的發言信息並顯示到會議室信息主界面中另外還要定時刷新參會的人數會議室當前發言人會議室的公告等會議狀態信息這也可以通過從客戶端啟動一個定時器通過xmlhttp對象與服務器交互得到

  另外還有一些操作鎖定會議室踢人指定發言人的發言時間給會議室加密碼等功能也通過xmlhttp的方式與服務器傳輸命令實現

  五核心代碼說明

  服務器端核心代碼

  在EasyJF開源團隊的會議系統中由於是以EasyJF官網的論壇系統後台管理等是集成一起的服務器ChatService與ChatRoom共同合並到了一個ChatServicejava類中實現會議室管理及會議服務功能ChatService類的部分主要代碼如下

  

  package comeasyjfchatbusiness; public class ChatService implements Runnable {  private static final Map service=new HashMap();//會議室服務系統中的當前會議室
存放到該表集合中  private static final int maxServices=;//可以同時開的最大會議室數  private static final SimpleDateFormat df=new SimpleDateFormat(yyyyMMdd);  private final List msgs;//聊天信息Chat  private final List users;//在線用戶ChatUser  private final List talkers;//排隊發言人數Talker  private final List manager;//會議室管理員  private Talker currentTalker;//當前發言人  private String cid;//會議室id  private String title;//會議室主題  private String intro;//會議室簡介  private String owner;//會議室創建人  private int maxUser;//最大在線人數  private int interval;//最大刷新時間間隔  private String vrtype;//訪問權限  private String vrvalue;//訪問值  private String announce;  private String password;//房間進入密碼  private int status;//會議室狀態  private String filePath;  //private Thread thread;  private boolean isStop=false;  public ChatService()  {   thismsgs=new ArrayList();   thisusers=new ArrayList();   thistalkers=new ArrayList();   thismanager=new ArrayList();   thismaxUser=;//最大人同時   thisinterval=**;//分鐘以前的信息  }  /**  * 停止所有會議室  *  */  public static void clear()  {   if(!serviceisEmpty())   {    Iterator it=servicevalues(erator();    while(ithasNext())    {     ChatService chat=(ChatService)itnext();     chatstop();    }   }   serviceclear();  }  /**  * 創建一個會議室  * @param name 會議室ID  * @return  */  public static ChatService create(String name)  {   ChatService ret=null;    if(ntainsKey(name))    {     ChatService s=(ChatService)serviceget(name);     sstop();     serviceremove(name);    } if(servicesize()

  2、MVC處理部分的Action代碼

  在EasyJF的會議系統中,由於使用EasyJWeb作為MVC框架,因此處理Ajax比較簡單,下面是會議室系統的核心Action主要代碼。TW.WINGWIt.coM

  

  package com.easyjf.chat.action; public class ChatAction extends AbstractCmdAction {  private ChatService chatRoom;  public Object doBefore(WebForm form, Module module) {   // TODO Auto-generated method stub   if(chatRoom==null)chatRoom=ChatService.get((String)form.get("cid"));    return super.doBefore(form, module);  }  public Page doInit(WebForm form, Module module) {   // TODO Auto-generated method stub    return doMain(form,module);  }  //用戶登錄進入會議室  public Page doMain(WebForm form, Module module) {   if(chatRoom!=null){    ChatUser user=getChatUser();    if(!chatRoom.join(user))form.addResult("msg","不能加入房間,可能是權限不夠!");    form.addResult("chatRoom",chatRoom);    form.addResult("user",user);   }   else   {    form.addResult("msg","會議未啟動或者會議室不存在!");   }   return module.findPage("main");  }  //處理用戶發言信息  public Page doSend(WebForm form, Module module) {   if(chatRoom==null)return new Page("err","/l","thml");//返回會議室不存在
的錯誤   Chat chat=(Chat)form.toPo(Chat.class);   chat.setCid(chatRoom.geneId());   chatRoom.talk(chat);   return doRecive(form,module);  }  //用戶接收發言信息  public Page doRecive(WebForm form, Module module) {    if(chatRoom==null)return new Page("err","/l","thml");//返回會議室不存
在的錯誤    String lastReadId=CommUtil.null2String(form.get("lastReadId"));    //System.out.println(lastReadId);    form.addResult("list", chatRoom.getNewestMsg(getChatUser(),lastReadId));    return module.findPage("msgList");  }  //用戶刷新會議狀態信息  public Page doLoadConfig(WebForm form, Module module) {   if(chatRoom==null)return new Page("err","/l","thml");//返回會議室不存
在的錯誤   form.addResult("userList", chatRoom.getUsers());   form.addResult("talkerList", chatRoom.getTalkers());   return module.findPage("config");  }  //用戶退出  public Page doExit(WebForm form, Module module) {  if(chatRoom==null)return new Page("err","/l","thml");//返回會議室不存在的
錯誤  hatRoom.exit(getChatUser());  form.addResult("msg","退出成功");  ActionContext.getContext().getSession().removeAttribute("chatUser");  return new Page("msg","/chat/xmlMsg.xml",Globals.PAGE_TEMPLATE_TYPE); }

  3、客戶端AJAX部分核心代碼

  EasyJF會議系統中,服務器發送給客戶端的都是格式化的xml文檔數據。下面是核心的AJAX函數及發送接收會議信息的客戶端代碼。

  

  function newXMLHttpRequest() {  var xmlreq = false;  if (window.XMLHttpRequest) {   xmlreq = new XMLHttpRequest();  } else if (window.ActiveXObject) {   try {    xmlreq = new ActiveXObject("Msxml2.XMLHTTP");  } catch (e1) {  try {    xmlreq = new ActiveXObject("Microsoft.XMLHTTP");  } catch (e2) {  }  } } return xmlreq; } //處理返回信息 //xmlHttp返回值, //method:方法名 方法必須帶一個參數如doRecive(xNode); function handleAjaxResult(req,method) {  return function () {   if (req.readyState == 4) {    if (req.status == 200) {     // 將載有響應信息的XML傳遞到處理函數     var objXMLDoc=new ActiveXObject("Microsoft.XMLDOM");     objXMLDoc.loadXML(req.responseText);     eval("if(objXMLDoc.firstChild)"+method+
"(objXMLDoc.firstChild.nextSibling);");    } else {     //alert("HTTP error: "+req.status);         }    }   }  }  //執行客戶端Ajax命令  //url 數據post地址  //postData 發送的數據包  //handleMethod 處理返回的方法  function executeAjaxCommand(url,postData,handleMethod)  {   var req = newXMLHttpRequest();   req.onreadystatechange =handleAjaxResult(req,handleMethod);   req.open("PO   ST", url, true);   req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");   req.setRequestHeader("charset","utf-8");   req.send(postData);  }  //用戶發言 unction doSend() {  if(!check())return false;  var msg=ntent.value;  var reciver=EditForm.reciver.value;  var url="/chat.ejf?easyJWebCommand=send&cid="+roomId+"&lastReadId=
"+lastReadId;  var postData="sender="+myName+"&reciver="+reciver+"&content="+msg;  clearTimeout(reciveTime);  executeAjaxCommand(url,postData,"recive");  ntent.value=""; } //接收發言信息 function doRecive() {  var reciver=EditForm.reciver.value;  var url="/chat.ejf?easyJWebCommand=recive&cid="+roomId+"&lastReadId=
"+lastReadId;  executeAjaxCommand(url,"","recive"); } //處理接收到的發言信息 function recive(list) {  var id="";  for(var oNode=list.firstChild;oNode;oNode=oNode.nextSibling) // 依次分析每個
節點  {   chatContent.innerHTML+=showMsg(oNode);   id=oNode.getAttribute("cid");  }  if(id!="") lastReadId=id;  chatContent.scrollTop=chatContent.scrollHeight;  reciveTime=setTimeout("doRecive();",5000); }

  六、系統演示

  大家可以到EasyJF開源團隊的官方網站看程序演示效果,地址是:

  ?easyJWebCommand=show&ejid=2538093638804337

  結束語

  Ajax從技術上講主要就是javascript、dhtml、css、xmldom、xmlhttp等一些我們很早就接觸了的技術。而xmldom及xmlhttp也沒有什麼東西,寫程序的時候把參考文檔打開Copy就OK,dhtml及javascript涉及的東西就多了,不能只是看參考文檔,需要把他真正消化,並能靈活動用,這就需要大家都練習了。筆者建議大家不要濫用Ajax.對於高手建議多研究一些業務及系統級算法設計等,對於新手嘛,把基本的技術(客戶端的包括dhtml、css、javascript、xml等,J2EE服務器端的設計模式、UML建模、Servlet、JDBC或ORM系統、XML、EJB及一些框架、工具等)學好才是硬道理。


From:http://tw.wingwit.com/Article/program/Java/hx/201311/25718.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.