用户操作
[留言]  [发消息]  [加为好友] 
订阅我的博客
XML聚合    FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
wqhzxy87812389的公告
卓越科技招聘软件偏执狂,喜欢软件胜过喜欢自己,爱公司胜过爱自己。
文章分类
    存档

    原创  网页聊天室 收藏

    網頁聊天的基本原理很簡單,在使用者發送訊息給伺服端時,同時取回新的聊天訊息,在使用者沒有發送訊息,同時查詢伺服端是否有新的訊息,並顯示在頁面中。

    不過重點就在於取得訊息或重新取得訊息的方式,在過去,是在讓瀏覽器定時重新整理網頁,每一次除了新的訊息之外,往往伴隨著大量重複的HTML標籤等內容。

    如果使用非同步請求,取得XML回應訊息,並動態更新頁面中顯示聊天訊息的部份,這麼一來,就可以節省掉下載重複頁面內容的頻寬,使用者的畫面也會更穩定,不會因為重新整理而發生閃爍的感覺。

    例如,您可以寫一個簡單的聊天頁面:

    • ChatRoomEx-1.html
    <!DOCTYPE html 
    PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=BIG5">
    <title>聊天室</title>
    <script type="text/javascript" src="ChatRoomEx-1.js"></script>
    </head>
    <body>
    <p>
    輸入訊息: <input id="text"/>
    <input type="button" value="傳送" onclick="sendMessage()"/>
    </p>

    <p>聊天室訊息:</p>
    <table align="left">
    <tbody id="dynamicUpdateArea"></tbody>
    </table>
    </body>
    </html>

    您可以在這個頁面中的欄位中輸入文字,而下方會有個顯示訊息的區域,每次的新訊息將只在該區域更新,頁面中其餘的部份不用變動,所以不用重複下載,來看一下JavaScript的部份:
    • ChatRoomEx-1.js
    var xmlHttp;

    function createXMLHttpRequest() {
    if (window.ActiveXObject) {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest) {
    xmlHttp = new XMLHttpRequest();
    }
    }

    function sendMessage() {
    var msg = document.getElementById("text").value;

    // 使用者只是隨意按下傳送鈕,但文字欄位中沒有文字
    if(msg === "") {
    // 那就重新整理訊息區好了
    refreshMessage();
    return;
    }

    // 傳送訊息
    var param = "task=send&msg=" + msg;
    // ajax請求
    ajaxRequest(param);
    // 清空文字欄位
    document.getElementById("text").value = "";
    }

    // 定時查詢用這個
    function queryMessage() {
    var param = "task=query";
    ajaxRequest(param);
    }

    function ajaxRequest(param) {
    var url = "ChatRoomServlet?timeStamp=" + new Date().getTime();
    createXMLHttpRequest();
    xmlHttp.onreadystatechange = refreshMessage;
    xmlHttp.open("POST", url);
    xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
    xmlHttp.send(param);
    }

    function refreshMessage() {
    if(xmlHttp.readyState == 4) {
    if(xmlHttp.status == 200) {
    // 處理顯示訊息的表格區域
    var table_body = document.getElementById("dynamicUpdateArea");
    var length = table_body.childNodes.length;
    var i;
    for (i = 0; i < length; i++) {
    // 先移除原有的列(row)
    table_body.removeChild(table_body.childNodes[0]);
    }

    // 處理取回的訊息
    var messages = xmlHttp.responseXML.getElementsByTagName("message");
    length = messages.length;
    for(i = length - 1; i >= 0 ; i--) {
    var message = messages[i].firstChild.data;
    // 在表格中新增一列來排列訊息
    var row = createRow(message);
    table_body.appendChild(row);
    }
    // 下次2秒後會再查詢一下有無新訊息
    setTimeout(queryMessage, 2000);
    }
    }
    }

    function createRow(message) {
    var row = document.createElement("tr");
    var cell = document.createElement("td");
    var cell_data = document.createTextNode(message);
    cell.appendChild(cell_data);
    row.appendChild(cell);
    return row;
    }

    伺服端必須傳回以下的XML格式,表示目前伺服端所管理的聊天室中可取得的訊息:
    <messages>
        <message>聊天訊息一</message>
        <message>聊天訊息二</message>
        <message>聊天訊息三</message>
    </messages>

    以下是個簡單的聊天室Servlet:

    • ChatRoomServlet.java
    package onlyfun.caterpillar;

    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.LinkedList;
    import java.util.List;

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    public class ChatRoomServlet extends
    javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    private static LinkedList<Message> messages = new LinkedList<Message>();

    private List<Message> addMessage(String text) {
    if (text != null && text.trim().length() > 0) {
    messages.addFirst(new Message(text));
    while (messages.size() > 10) {
    messages.removeLast();
    }
    }

    return messages;
    }

    private List<Message> getMessages() {
    return messages;
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    List<Message> list = null;

    if("send".equals(request.getParameter("task"))) {
    String msg = request.getParameter("msg");
    // 中文處理
    msg = new String(msg.getBytes("ISO-8859-1"), "UTF8");
    list = addMessage(msg);
    }
    else if("query".equals(request.getParameter("task"))){
    list = getMessages();
    }

    response.setContentType("text/xml");
    response.setHeader("Cache-Control", "no-cache");
    response.setCharacterEncoding("UTF8");

    PrintWriter out = response.getWriter();
    out.println("<messages>");
    for(int i = 0; i < list.size(); i++) {
    String msg = list.get(i).getText();
    out.println("<message>" + msg + "</message>");
    }
    out.println("</messages>");
    out.close();
    }
    }

    • Message.java
    package onlyfun.caterpillar;

    public class Message {
    private String text;

    public Message(String newtext) {
    text = newtext;
    if (text.length() > 256) {
    text = text.substring(0, 256);
    }
    text = text.replace('<', '[');
    text = text.replace('&', '_');
    }

    public String getText() {
    return text;
    }
    }

     

    发表于 @ 2007年08月23日 22:39:00 | 评论( loading... ) | 编辑| 举报| 收藏

    旧一篇:自动表单填写 | 新一篇:javascript的技巧

    • 发表评论
    • 评论内容:
    •  
    Copyright © wqhzxy87812389
    Powered by CSDN Blog