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

使用 AJAX 在 ASP.NET 中实现的聊天应用程序(弹出窗口)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (26投票s)

2010 年 5 月 7 日

CPOL

3分钟阅读

viewsIcon

156474

downloadIcon

23229

使用 AJAX 和 SQL Server 在 ASP.NET 中实现的聊天应用程序。

引言

在这篇文章中,我想分享我在开发聊天应用程序方面的工作,该应用程序可以与您的常规 ASP.NET 应用程序一起使用。我正在使用 AJAX 和 SQL Server 作为后端。由于我使用了 UpdatePanel,因此只能在 ASP.NET 2.0 或更高版本中使用。

使用代码

该应用程序的工作方式如下

  • 显示在线用户列表.
  • 可以从后端数据库加载在线用户列表,并在用户登录到应用程序时记录一个条目。 用户名将显示为超链接,每个用户都有唯一的聊天 ID。

  • 当前登录用户将单击用户名以打开一个新的聊天窗口,然后键入消息.
  • 单击用户名时,将使用聊天 ID 作为参数调用 OpenChatBox() 函数。 当用户键入任何消息并单击“发送”按钮时,该消息将被发送到服务器并使用提供的聊天 ID 存储到数据库中。

    function OpenChatBox(uid, chatid) {
        var win = window.open("ChatBox.aspx?uid=" + uid + "&cid=" + 
                  chatid, "ChatWindow" + chatid + 
                  document.getElementById('hidCurrentUser').value, 
                  "status=0,toolbar=0, menubar=0, width=450, height=550");
        top = top + 50;
        if (top > screen.availHeight - 550)
            top = 100;
        left = left + 50;
        if (left > screen.availWidth - 450)
            left = 100;
        
        win.moveTo(left, top);
        chats[chats.length] = win;
        return false;
    }

    消息存储在 ASP.NET 中实现。

    Private Sub SendMessage(ByVal msg As String)
        Dim con As SqlConnection = New SqlConnection( _
                "Data Source=.\SQLEXPRESS;AttachDbFilename=" & _ 
                "D:\Dev\Projects\WebChat\WebChat\App_Data\WebChat" & _ 
                ".mdf;Integrated Security=True;User Instance=True")
        con.Open()
        Dim comm As SqlCommand = New SqlCommand("stp_SendMessage", con)
        comm.CommandType = CommandType.StoredProcedure
        Dim paramSender As SqlParameter = New SqlParameter( _
            "@Sender", SqlDbType.VarChar, 10)
        paramSender.Value = HttpContext.Current.User.Identity.Name
        comm.Parameters.Add(paramSender)
    
        Dim paramRec As SqlParameter = New SqlParameter( _
            "@Reciever", SqlDbType.VarChar, 10)
        paramRec.Value = ViewState("uid")
        comm.Parameters.Add(paramRec)
    
        Dim paramMsg As SqlParameter = New SqlParameter( _
           "@Msg", SqlDbType.VarChar, 1000)
        paramMsg.Value = msg
        comm.Parameters.Add(paramMsg)
    
        'store the chat id supplied from browser
        Dim paramChatId As SqlParameter = New SqlParameter( _
         "@ChatId", SqlDbType.VarChar, 100)
        paramChatId.Value = ViewState("vwChatId").ToString()
        comm.Parameters.Add(paramChatId)
    
        comm.ExecuteNonQuery()
        con.Close()
    
    End Sub

    Flow.JPG

  • 在收件人的屏幕上,将出现一个新的弹出窗口.
  • 在每个用户的主页上,每 5 秒运行一次脚本,以 ping 服务器以查找任何消息。

    function PingServer() {
        PingServerForMsg()
        setTimeout(PingServer, 5000);
    }
    
    
    function PingServerForMsg() {
           // Use ajax to call the GetChatMsg.aspx to get any new messages.
    
            xmlHttp = GetXmlHttpObject(stateChangeHandler);
    }

    此 JavaScript 消息将调用 *GetChatMsg.aspx* 页面以获取新消息,下面显示的是 *GetChatMsg.aspx* 的代码

    Imports System.Data
    Imports System.Data.SqlClient
    
    Partial Public Class GetChatMsg
        Inherits System.Web.UI.Page
    
        Protected Sub Page_Load(ByVal sender As Object, _
                  ByVal e As System.EventArgs) Handles Me.Load
            Response.Clear()
            Response.ClearContent()
            'set response to not to cache, to avoid the ajax from displaying old message.
            Response.AddHeader("Cache-Control", "no-cache, must-revalidate")
    
            Dim ds As DataSet = GetMessage(HttpContext.Current.User.Identity.Name)
            Dim strMsg As String = ""
            If ds.Tables.Count > 0 Then
    
                If ds.Tables(0).Rows.Count > 0 Then
    
                    For Each dr As DataRow In ds.Tables(0).Rows
                        If strMsg.Length > 0 Then
                            strMsg += "#"
                        End If
                        strMsg += dr("Sender").ToString() + "&"
                        strMsg += dr("ChatId").ToString() + "&"
                        strMsg += dr("Msg").ToString().Replace("&", _
                                     "_@AMP__").Replace("#", "_@HASH__")
                    Next
    
                End If
            End If
    
            Response.Write(strMsg)
    
            Response.End()
        End Sub
    
        Private Function GetMessage(ByVal strUid As String) As DataSet
            Dim dsMsgs As DataSet = New DataSet()
            Dim con As SqlConnection = New SqlConnection( _
                    "Data Source=.\SQLEXPRESS;AttachDbFilename=D:\Dev\" & _ 
                    "Projects\WebChat\WebChat\App_Data\WebChat.mdf;" & _ 
                    "Integrated Security=True;User Instance=True")
            con.Open()
            Dim comm As SqlCommand = New SqlCommand("stp_GetMessage", con)
            comm.CommandType = CommandType.StoredProcedure
            Dim paramSender As SqlParameter = New SqlParameter( _
                "@Uid", SqlDbType.VarChar, 10)
            paramSender.Value = HttpContext.Current.User.Identity.Name
            comm.Parameters.Add(paramSender)
    
            If (Request.QueryString("cid") <> Nothing) Then
                Dim paramChatId As SqlParameter = New SqlParameter( _
                                 "@ChatId", SqlDbType.VarChar, 100)
                paramChatId.Value = Request.QueryString("cid")
                comm.Parameters.Add(paramChatId)
            End If
    
            Dim da As SqlDataAdapter = New SqlDataAdapter(comm)
            da.Fill(dsMsgs)
    
            con.Close()
            Return dsMsgs
        End Function
    
    End Class

    在浏览器端,在获取新消息时,如果聊天 ID 是新的,则浏览器将打开一个弹出窗口;如果已经为与新消息关联的聊天 ID 打开了一个弹出窗口,则将显示该消息。

    function stateChangeHandler() {
        //readyState of 4 or 'complete' represents that data has been returned 
        if (xmlHttp.readyState == 4 || xmlHttp.readyState == 'complete') {
            //Gather the results from the callback 
            var str = xmlHttp.responseText;
    
            if (str != "" ) {
                //document.getElementById('txtMsg').value = str;
                //eval(str);
                var msgs = str.split('#');
    
                for (ind = 0; ind < msgs.length; ind++) {
                    msgs[ind] = msgs[ind].replace("_@HASH__", "#");
                    var msg = msgs[ind].split("&");
                    msg[0] = msg[0].replace("_@AMP__", "&");
                    msg[1] = msg[1].replace("_@AMP__", "&");
                    msg[2] = msg[2].replace("_@AMP__", "&");            
                    var blnExisting = false;
                    for (iind = 0; iind < chats.length; iind++) {
                        try
                        {
                            if (chats[iind] != null && chats[iind].name == 
                                "ChatWindow" + msg[1] + 
                                document.getElementById('hidCurrentUser').value)
                            blnExisting = true;
                        }
                        catch(e){}
                    }  
                    if( blnExisting == false)
                        OpenChatBox(msg[0], msg[1]);
                }
            }
        }
    }
  • 用户可以通过当前窗口进行通信.
  • 收件人可以在同一窗口中使用消息回复。 弹出窗口具有屏幕 *ChatBox.aspx*,该屏幕具有 JavaScript 代码的 *ChatBox.js* 引用,以再次每秒 ping 服务器。 但是这次,它使用分配给该窗口的聊天 ID。 因此,每个聊天都有一个唯一的聊天 ID,并且聊天消息由聊天 ID 在后端维护,并且弹出窗口通过聊天 ID 进行通信。 此处使用了 UpdatePanel,以避免用户单击“发送消息”时聊天窗口闪烁。 并且当收件人收到消息时,该消息将在服务器上删除。

  • 单个用户可以一次与多个用户通信.
  • 用户可以与任意数量的用户聊天,因为弹出窗口用于每个聊天,每个聊天都有唯一的聊天 ID。 聊天 ID 生成为“时间戳 + 发送者 ID + 接收者 ID”。

单击“发送”按钮后,键入的消息将由代码隐藏保存到 SQL Server 中的表中(此处,可以使用任何其他数据库)。 在接收者端,在 AJAX 调用中,消息读取器将读取与接收者相关的消息并发送给接收者。 请查看附加的 ASP.NET 代码的源代码,该代码适用于 Visual Studio 2008,但是相同的代码可以用于 VS 2005 (ASP.NET 2.0),而无需进行任何更改。

当第一个用户发送消息时,该消息将保存到后端的所选用户。 当在接收者上运行的应用程序(在示例中的 *default.aspx* 中实现)时,AJAX 用于每 5 秒 ping 一次服务器以查找消息。

增强功能

  • 开发人员可以尝试实现保存聊天历史记录。
  • 可以在用户控件中实现在线用户列表,使其可重用。
  • 可以更改聊天窗口以包括消息时间和图像。
© . All rights reserved.