首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

基於 AJAX 與 J2EE 的網上會議室系統設計與實現全記錄

     編輯:Java 相關知識

專案背景與目標

為滿足 EasyJF 開源團隊遠程協作需求,開發一套模擬傳統會議形式的網上會議室系統。核心功能包括:多會議室並發、權限控管、發言模式切換(排隊/自由)、歷史記錄持久化、遊客與論壇帳號整合、文字聊天為主並預留語音視訊擴充介面。

技術棧選型

  • 伺服端:Java + EasyJWeb MVC 框架
  • 客戶端:AJAX (XMLHttpRequest) 非同步交互
  • 資料儲存:會議記錄採用純文字檔,便於部署與維運

伺服端領域模型設計

核心實體類

// 會議室實體
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;       // 創建時間
    // ... getter/setter
}

// 發言記錄
public class Chat {
    private String cid;
    private String sender;        // 發言人
    private String reciver;       // 接收人
    private String content;       // 內容
    private Date vdate;           // 時間
    private Integer types;        // 類型
    private Integer status;
}

// 參會用戶
public class ChatUser {
    private String ip;
    private String port;
    private String userName;
    private Date lastAccessTime;  // 最後活躍時間
    private Integer status;       // 在線/離線/發言中...
}

// 排隊發言者
public class Talker {
    private String userName;
    private Date startTime;
    private Date estimatedEndTime;
}

會議室服務核心類:ChatService

  • 單例 Map 管理所有活躍會議室(Map<String, ChatService>)
  • 實作 Runnable,每個會議室獨立線程維護狀態(run() 每 5 秒輪詢)
  • 核心職責:用戶進出管理、發言佇列控制、歷史訊息持久化至文字檔、定時清理過期資料
  • 關鍵方法:create()、close()、get()、talk()、exit()、Flash()(刷新持久化)

客戶端 AJAX 交互架構

兩大介面層

  1. 會議室管理介面:傳統 Java Web(EasyJWeb 代碼生成器快速構建 CRUD)。
  2. 會議主介面:單頁應用風格,所有互動透過 AJAX 完成:
     • 發言即時推送(XMLHttpRequest POST)
     • 定時輪詢拉取新訊息(setTimeout 5 秒)
     • 狀態同步(人數、當前發言人、公告)
     • 管理指令(鎖定、踢人、設密碼、分配發言時間)

為何選擇 AJAX?

對比 Form 提交、自動刷新、ActiveXObject:AJAX 無感知刷新、用戶體驗最佳、XML 結構化資料便於 JavaScript 處理。

核心代碼解析

Action 層

public class ChatAction extends AbstractCmdAction {
    private ChatService chatRoom;

    public Object doBefore(WebForm form, Module module) {
        if (chatRoom == null) 
            chatRoom = ChatService.get((String)form.get("cid"));
        return super.doBefore(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", "/err.html");
        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) {
        String lastReadId = CommUtil.null2String(form.get("lastReadId"));
        form.addResult("list", chatRoom.getNewestMsg(getChatUser(), lastReadId));
        return module.findPage("msgList"); // 返回 XML 片段
    }

    // 狀態同步
    public Page doLoadConfig(WebForm form, Module module) {
        form.addResult("userList", chatRoom.getUsers());
        form.addResult("talkerList", chatRoom.getTalkers());
        return module.findPage("config");
    }
}

客戶端 JavaScript 核心

// 跨瀏覽器 XMLHttpRequest 工廠
function newXMLHttpRequest() {
    if (window.XMLHttpRequest) return new XMLHttpRequest();
    try { return new ActiveXObject("Msxml2.XMLHTTP"); }
    catch(e) { return new ActiveXObject("Microsoft.XMLHTTP"); }
}

// 統一 AJAX 執行器
function executeAJaxCommand(url, postData, handleMethod) {
    var req = newXMLHttpRequest();
    req.onreadystatechange = handleAJaxResult(req, handleMethod);
    req.open("POST", url, true);
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.setRequestHeader("charset", "utf-8");
    req.send(postData);
}

// 發言
function doSend() {
    if (!check()) return false;
    var url = "/chat.ejf?easyJWebCommand=send&cid=" + roomId + "&lastReadId=" + lastReadId;
    var postData = "sender=" + myName + "&reciver=" + reciver + "&content=" + msg;
    clearTimeout(reciveTime);
    executeAJaxCommand(url, postData, "recive");
    EditForm.content.value = "";
}

// 處理回調
function handleAJaxResult(req, method) {
    return function() {
        if (req.readyState == 4 && req.status == 200) {
            var objXMLDoc = new ActiveXObject("Microsoft.XMLDOM");
            objXMLDoc.loadXML(req.responseText);
            eval("if(objXMLDoc.firstChild) " + method + "(objXMLDoc.firstChild.nextSibling);");
        }
    };
}

// 接收訊息回調
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 會議室體驗

AJAX 本質是 JavaScript、DHTML、CSS、XMLDOM、XMLHttpRequest 等成熟技術的組合。對資深工程師,重點在業務與系統級演算法設計;對新手,夯實客戶端(DHTML/CSS/JS/XML)與伺服端(設計模式/UML/Servlet/JDBC/EJB/框架)基本功才是硬道理。切勿濫用 AJAX,適時適所發揮其「無感知交互」優勢。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved