65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 AJAX 的简单聊天应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (12投票s)

2010年10月27日

CPOL

3分钟阅读

viewsIcon

112475

downloadIcon

11146

使用 AJAX 的简单聊天应用程序

引言

这是一个简单的聊天应用程序,用于演示在 ASP.NET 中使用 XMLHttpRequest (AJAX)。这是一个一对一的用户聊天应用程序,但可以轻松扩展以支持多人聊天。

作为演示应用程序,在用户注册时不会维护额外的用户详细信息,也不会使用 CAPTCHA 检查或其他安全措施。

负责 AJAX 通信的主要代码与我上一篇文章中解释的相同,可以在 AJAXDemo.aspx 中找到。

因此,AJAXRequest() 函数用于在浏览器和服务器之间传输所有数据。

背景

有关 AJAXRequest() 函数的所有详细信息,请参阅 AJAXDemo.aspx

在此聊天应用程序中,部分数据(例如 RequestCodeusernamepassword)通过 HTTP 标头发送,而像 message userlist 这样的数据则正常发送在内容中。

这很容易解释了大多数 AJAX 数据交换可能性的用法。

Using the Code

演示应用程序是一个 ASP.NET Web 应用程序。它使用 Microsoft SQL 数据库来存储用户消息和用户登录信息。

数据库 .mdf 文件包含在 APP_Data 文件夹中,并且文件 "DatabaseScript.sql" 包含设置新数据库的所有数据库脚本。

目前,我已注释掉用于在数据库存储过程中维护消息历史记录的代码,但如果需要,可以启用它。

浏览器 -> 服务器 -> 浏览器之间的通信方式如下:

  1. 客户端 (浏览器) 发送带有 RequestCode 的请求。
  2. 服务器解析请求代码以确定请求的目的 (例如。LoginLogoutSendMessageReceiveMessage 等)。
  3. 服务器处理请求,进行处理,并将适当的响应发送回来,同时附带请求的数据。
  4. 接收方客户端始终轮询服务器以获取消息。一旦服务器有要发送给接收方的消息,消息就会在服务器的响应中发送。
var MessagePollingInterval = 3000 ;  	// Interval of polling for message
var OLUsersPollingInterval = 9000;  		// Interval of polling for online users 

这些是保存轮询间隔的变量。

消息以加密方式与服务器交换。在此应用程序中使用的加密/解密算法是简单的替换密码。

var EncryptionKey = 3;  //Encryption Key: 0 to disable encryption

这保存了应该在客户端和服务器端都相同的加密密钥。

以下是加密/解密函数:

function Encrypt(PlainText, Key) {
    var to_enc = PlainText.toString().replace(/^\n+/, "").replace
	(/\n+$/, "");  //Nozel: remove \n

	var xor_key=Key;
	var the_res="";//the result will be here
	for(i=0;i<to_enc.length;++i)
	{
	    ////the_res += String.fromCharCode((xor_key ^ to_enc.charCodeAt(i))); 
		//Nozel:  Xor Cipher . 
		//But encoded characters are not always allowed in http headers

	    if (to_enc.charCodeAt(i) <= 32) {
	        //Keep c as it is
	        the_res += String.fromCharCode((to_enc.charCodeAt(i))); //Nozel: Bypass 
			//Invalid characters which are not supported in Http headers
	     }
	    else {
	        the_res += String.fromCharCode
		((to_enc.charCodeAt(i)) - Key); //Nozel: Normal substitution Cipher
	    }
	}
	return(the_res);
}

function Decrypt(CipherText, Key) {
    var to_dec = CipherText;
    var xor_key = Key;
    var PlainText = "";
    for (i = 0; i < to_dec.length; i++) {

       ///// PlainText += String.fromCharCode((xor_key ^ to_dec.charCodeAt(i)));   
     //Nozel:  Xor Cipher . But encoded characters are not always allowed in HTTP headers

        if (to_dec.charCodeAt(i) <= 32) {
            //Keep c as it is
            PlainText += String.fromCharCode((to_dec.charCodeAt(i)));  
	  //Nozel:   Bypass Invalid characters which are not supported in HTTP headers
        }
        else {
            PlainText += String.fromCharCode
		((to_dec.charCodeAt(i)) + Key);  //Nozel:   Normal substitution Cipher
        }
    }
    return (PlainText);
} 

服务器端处理程序中的 C# 代码中实现了类似的函数来执行加密/解密。

这是通过 Ajax 请求发送消息的代码片段:

function SendMessage() {
    if (ValidateSendMessageWindow()) {
        var URL = "SecureChatServer.ashx";
        var covert = "False";
        if (URL == null) { alert("Request URL is Empty"); }
        else {
            HTMLmessage = document.getElementById('Message').value.toString().replace
			(/\r\n?/g, '<br/>');
            message = Encrypt(HTMLmessage, EncryptionKey);
            recepient = Encrypt
		(document.getElementById('Recepient').value, EncryptionKey);
            AjaxRequest(ProcessSendMessageResponse, URL, "POST", 
		{Message:message , Recepient:recepient}, '', { RequestCode: 'SC005'});

			//.
			//.
			//.
			}}} 

所有必需的数据都传递给 'AjaxRequest' 函数,该函数将数据发送到通用处理程序 'SecureChatServer.ashx'。

这是为 RequestCode: SC005 执行的代码:

 LoggedInUser = userlogin.IsUserLoggedIn(SessionID, UserIPAddress);
 if (LoggedInUser != null)  // Check is user is logged in
 {
  Messages newMessage = new Messages(); // Message Data Access Layer

 Message = Decrypt(context.Request.Params["Message"], 
	EncryptionKey);  // Extract the message data from the request and decrypt it.
 Recepient = Decrypt(context.Request.Params["Recepient"], 
	EncryptionKey);  // Extract the recipient data from the request and decrypt it.
 if (newMessage.WriteMessage(LoggedInUser, Recepient, 
	Message))  //Write the message to database through Message Data access layer
  {
 context.Response.AddHeader("CustomHeaderJSON", 
	"ResponseStatus:'RS-OK'");  //add the Success indicator to the response header
 }
 else
 {
 context.Response.AddHeader("CustomHeaderJSON", 
    "ResponseStatus:'RS-Failed'");  //add the Failure indicator to the response header
 }

.

.

.
} 

此响应以及 HTTP 标头中新添加的成功/失败指示器由服务器发送回来。

最后,在 AJAX 请求完成后,将执行 Handler 函数。所有来自服务器的响应都可以在 handler 函数中获得。

在这种情况下,指定的 handler 函数是 'ProcessSendMessageResponse',这是它的定义:

 function ProcessSendMessageResponse() {
    var ResponseStatus = GetHeader(ResponseHeaderJSON, 'ResponseStatus');
    if (ResponseStatus == "RS-OK") {
		//.
		//.
		//.
		}} 

正如您所见,'ResponseStatus' 的值是从 Response HTTP 标头中提取的,这些标头在函数中随时可用。由于 'ResponseHeaderJSON' 是一个 JSON 字符串,因此使用 'GetHeader' 函数从 JSON 字符串中提取特定值。

然后检查 'ResponseStatus' 的值以通知消息发送的成功/失败。

对于所有函数,如接收消息、登录、注销、获取在线用户列表等,都使用类似的过程。

大多数 UI 功能,如窗口拖动、工具提示、平滑显示/隐藏等,都是使用 JQuery 库实现的。

关注点

这是一个基本实现,可以扩展以支持其他功能,例如更详细的用户注册、多人聊天以及普通聊天应用程序的其他功能。

此应用程序的主要目的是提供对如何将 XmlHttpRequest 与 ASP.NET 用于 Web 应用程序中的不同目的的简单明了的理解。

© . All rights reserved.