網頁聊天室

<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>
網頁聊天的基本原理很簡單,在使用者發送訊息給伺服端時,同時取回新的聊天訊息,在使用者沒有發送訊息,同時查詢伺服端是否有新的訊息,並顯示在頁面中。

不過重點就在於取得訊息或重新取得訊息的方式,在過去,是在讓瀏覽器定時重新整理網頁,每一次除了新的訊息之外,往往伴隨著大量重複的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;
}
}

<script type="text/javascript"><!-- google_ad_client = "pub-9750319131714390"; google_ad_width = 160; google_ad_height = 600; google_ad_format = "160x600_as"; google_ad_type = "text_image"; google_ad_channel = ""; //--> </script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script><iframe width="160" scrolling="no" height="600" frameborder="0" allowtransparency="true" hspace="0" vspace="0" marginheight="0" marginwidth="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-9750319131714390&amp;dt=1179111675171&amp;lmt=1177046893&amp;format=160x600_as&amp;output=html&amp;url=http%3A%2F%2Fcaterpillar.onlyfun.net%2FGossip%2FAjaxGossip%2FChatRoom.html&amp;ad_type=text_image&amp;ref=http%3A%2F%2Fcaterpillar.onlyfun.net%2FGossip%2FAjaxGossip%2FAjaxGossip.html&amp;cc=15&amp;flash=9&amp;u_h=768&amp;u_w=1024&amp;u_ah=740&amp;u_aw=1024&amp;u_cd=16&amp;u_tz=480&amp;u_his=2&amp;u_java=true&amp;u_nplug=18&amp;u_nmime=58" name="google_ads_frame"></iframe>

<script type="text/javascript"><!-- google_ad_client = "pub-9750319131714390"; google_ad_width = 160; google_ad_height = 600; google_ad_format = "160x600_as"; google_ad_type = "text_image"; google_ad_channel = ""; //--> </script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script><iframe width="160" scrolling="no" height="600" frameborder="0" allowtransparency="true" hspace="0" vspace="0" marginheight="0" marginwidth="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-9750319131714390&amp;dt=1179111675187&amp;lmt=1177046893&amp;prev_fmts=160x600_as&amp;format=160x600_as&amp;output=html&amp;url=http%3A%2F%2Fcaterpillar.onlyfun.net%2FGossip%2FAjaxGossip%2FChatRoom.html&amp;ad_type=text_image&amp;ref=http%3A%2F%2Fcaterpillar.onlyfun.net%2FGossip%2FAjaxGossip%2FAjaxGossip.html&amp;cc=15&amp;flash=9&amp;u_h=768&amp;u_w=1024&amp;u_ah=740&amp;u_aw=1024&amp;u_cd=16&amp;u_tz=480&amp;u_his=2&amp;u_java=true&amp;u_nplug=18&amp;u_nmime=58" name="google_ads_frame"></iframe>

你可能感兴趣的:(JavaScript,html,servlet,Google,Flash)