上一周,我讨论到如何在因特网浏览器和SQL Server2000中建立一个基于XML数据岛(data islands)聊天程序。在本文中,我将引入源代码并解释每一部分的工作机制。
上一周我所编写的文章,在SQL script的MESSAGES表疏漏了一个域:type int的handle_id。一旦你添加这一域,你就可以成功地建立登录画面。
登录画面只为用户显示了一个INPUT窗体元素(txtHandle)以及一个Submit按钮。对于Submit按钮的onclick()事件,其功能是验证txtHandle值是否为空并进入聊天页面:
<html>
<head>
<script language="JavaScript">
function validate_form() {
if (document.thisForm.txtHandle.value != "")
{
document.thisForm.submit();
} else {
alert("Please enter a
valid handle.");
}
}
</script>
</head>
<body>
<form method="POST" action="chat.asp" name="thisForm"
id="thisForm">
Enter your handle to continue:<br>
<input type="text" name="txtHandle" id="txtHandle"
size="15"
maxlength="63"><br>
<input type="button" value="Submit" onclick="validate_form()">
</form>
</body>
</html>
在聊天页面中,检查句柄是否存在。如果不存在,即显示一个信息以提示用户返回到登录界面。如果登录继续,聊天页面就会被建立并显示给用户。
<%@ Language=VBScript %>
<%
Option Explicit
Response.Buffer = True
Response.Expires = -1
Dim adInteger, adVarChar
adInteger = 3
adVarChar = 200
Dim dom, stream, datax
Set dom = Server.CreateObject("MSXML2.DOMDocument")
dom.async = False
Set stream = Server.CreateObject("ADODB.Stream")
Set datax = Server.CreateObject("DATAX2.GenericSQL")
datax.GetConnection "TechSQLTest"
Dim handle, handle_id
handle = Request.Form("txtHandle")
Set stream = datax.RunSPReturnStream("do_login", Array(Array("@handle",
adVarChar, 63, handle)))
stream.Position = 0
dom.loadXML "<root>" & stream.ReadText(-1) & "</root>"
stream.Close
If dom.parseError.errorCode <> 0 Then
Err.RaisevbObjectNumber, "", dom.parseError.reason
End If
If Not dom.selectSingleNode("//error") Is Nothing Then
%>
<html>
<body>
<%=dom.selectSingleNode("//description").text%><br>
<a href="chat_login.asp">Try Again.</a><br>
</body>
</html>
<%
ExitGracefully
End If
handle_id = dom.selectSingleNode("//handle_id").text
%>
<html>
<head>
<script language="JavaScript">
varmsg_proxy = new ActiveXObject("MSXML2.XMLHTTP");
varusr_proxy = new ActiveXObject("MSXML2.XMLHTTP");
varsnd_proxy = new ActiveXObject("MSXML2.XMLHTTP");
varmsg_tmr = setInterval("check_messages()", 1500);
varusr_tmr = setInterval("check_users()", 3000);
vardom = new ActiveXObject("MSXML2.DOMDocument");
dom.async = false;
function window_onload() {
check_messages();
check_users();
}
var checking = false;
function check_messages() {
if (checking) return;
setTimeout("checking = true;", 25);
msg_proxy.open("POST", "chat_server.asp?action=msg",
false);
msg_proxy.send("<root><handle_id>"
+ document.all.txtHandleID.value +
"</handle_id></root>");
varsMsgs = "<root>" + msg_proxy.responseText
+ "</root>";
dom.loadXML(sMsgs);
var nodes = dom.selectNodes("//MESSAGES");
varnodes_length = nodes.length;
for (vari = 0; i < nodes_length; i++) {
xmlMessages.documentElement.appendChild(nodes[i]);
}
if (xmlMessages.documentElement.childNodes.length
> 255)
xmlMessages.documentElement.removeChild(xmlMessages.documentElement.childNodes[
0]);
setTimeout("checking = false;", 25);
}
function check_users() {
usr_proxy.open("POST", "chat_server.asp?action=usr",
false);
usr_proxy.send();
xmlUsers.loadXML(usr_proxy.responseText);
}
function tblMessages_onreadystatechange() {
document.all.divMessages.scrollTop = Math.max(0, document.all.divMessages.scrollHeight
-
document.all.divMessages.offsetHeight);
}
var sending = false;
function btnSend_onclick() {
if (sending) return;
if (document.all.txtSend.value == "") return;
setTimeout("sending = true;", 25);
dom.loadXML(xmlBlank.xml);
dom.selectSingleNode("//action_id").text = 2;
dom.selectSingleNode("//handle_id").text
= document.all.txtHandleID.value;
dom.selectSingleNode("//message").text = document.all.txtSend.value;
snd_proxy.open("POST", "chat_server.asp?action=snd",
false);
snd_proxy.send(dom.xml);
document.all.txtSend.value = "";
setTimeout("sending = false;", 25);
}
function txtSend_onkeydown() {
if (window.event.keyCode == 13) {
btnSend_onclick();
window.event.keyCode = 0;
}
}
function logout() {
snd_proxy.open("POST", "chat_server.asp?action=out",
false);
snd_proxy.send("<MESSAGES><action_id>4</action_id><handle_id>"
+
document.all.txtHandleID.value
+ "</handle_id></MESSAGES>");
}
</script>
</head>
<body onload="window_onload()" onbeforeunload="logout()">
<xml id="xmlMessages" name="xmlMessages">
<root>
<MESSAGES>
<action_id>1</action_id>
<message>Welcome to
chat...</message>
</MESSAGES>
</root>
</xml>
<xml id="xmlBlank" name="xmlBlank">
<MESSAGES>
<action_id/>
<handle_id/>
<message/>
</MESSAGES>
</xml>
<xml id="xmlUsers" name="xmlUsers">
<root>
<HANDLES>
<handle/>
<handle_id/>
</HANDLES>
</root>
</xml>
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td align="center">
<div style="overflow:auto;width:300px;height:400px;border:2px
menu
inset;" name="divMessages"
id="divMessages">
<table cellpadding="2"
cellspacing="0" border="0" width="100%"
name="tblMessages"
id="tblMessages" dataSrc="#xmlMessages"
onreadystatechange="tblMessages_onreadystatechange()">
<tr>
<td><span
dataFld="message"></span></td>
</tr>
</table>
</div>
</td>
<td align="center">
<div style="overflow:auto;width:100px;height:400px;border:2px
menu
inset;">
<table cellpadding="2"
cellspacing="0" border="0" width="100%"
name="tblUsers"
id="tblUsers" dataSrc="#xmlUsers">
<tr>
<td><span
dataFld="handle"></span></td>
</tr>
</table>
</div>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="text"
name="txtSend" id="txtSend" size="55"
maxlength="255"
onkeydown="txtSend_onkeydown()">
<input type="button"
name="btnSend" id="btnSend" value="Send"
onclick="btnSend_onclick()">
</td>
</tr>
</table>
<input type="hidden" name="txtHandleID" id="txtHandleID"
size="5"
value="<%=handle_id%>">
</body>
</html>
<%
ExitGracefully
Sub ExitGracefully()
Set dom = Nothing
Set stream = Nothing
Set datax = Nothing
Response.End
End Sub
%>