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

使用 ASP.NET WebForm 和 BootStrap 构建 SignalR 聊天应用 - 第一部分

starIconstarIconstarIconstarIconstarIcon

5.00/5 (36投票s)

2017 年 12 月 20 日

CPOL

6分钟阅读

viewsIcon

75565

downloadIcon

7657

在实时聊天应用中集成 SignalR 和 ASP.NET C# WebForm 应用

引言

在本文中,我将与您分享如何在 ASP.NET WebForm 应用中集成和使用 SignalR。

在这里,我们将学习使用 SignalR、Bootstrap 和 jQuery 模态弹出窗口创建一个实时聊天应用程序。有一个针对现有用户的登录系统和针对新用户的注册。首先,用户必须创建一个帐户,然后他们可以使用其登录凭据登录,因此需要进行登录身份验证。登录后,用户可以参与聊天或讨论。用户可以在登录应用程序后更改其显示图片。在开始解释功能之前,请简要概述 SignalR 如下。

SignalR 概述

ASP.NET SignalR 是一个面向 ASP.NET 开发人员的库,它简化了向应用程序添加实时 Web 功能的过程,即服务器代码可以立即将内容推送到已连接的客户端,而不是让服务器等待客户端请求新数据。

SignalR 可用于向您的 ASP.NET 应用程序添加任何“实时”Web 功能。虽然聊天通常被用作示例,但您可以做更多事情。任何时候用户刷新网页以查看新数据,或者页面实现长轮询以检索新数据,它都是使用 SignalR 的候选者。

目标受众

目标受众是具有 ASP.NET 和 C# 基本知识的人。

解释

要做的事情

  • 创建一个 ASP.NET C# WebForm 应用程序。
  • 通过 NuGet 包管理器添加以下程序包。
    1. Bootstrap
    2. jQuery
    3. Font-awesome
    4. Microsoft.AspNet.SignalR
  • 创建 Startup.cs
  • 创建 ChatHub.cs
  • 创建登录 WebForm
  • 创建注册 WebForm
  • 创建聊天 WebForm
  • 在 SQL Server 中创建数据库
  • 代码

使用 C# 创建一个新的 ASP.NET Web 项目,并为其命名,就像我将项目命名为“SignalRChat”一样。

创建项目后,现在,通过 NuGet 包管理器添加程序包,如下图所示

包管理器控制台将打开。您只需输入程序包名称并按 Enter 键即可添加任何程序包。它将在您的项目中下载并安装。您可以在项目引用中看到引用文件,也可以在相应的项目目录中看到程序包文件。

安装软件包

  1. PM> Install-Package bootstrap -Version 3.3.7
  2. PM> Install-Package FontAwesome -Version 4.7.0
  3. PM> Install-Package jQuery -Version 3.2.1
  4. PM> Install-Package Microsoft.AspNet.SignalR -Version 2.2.2

成功安装上述程序包后,上述 DLL 或程序包将安装到您的项目中。您可以在项目解决方案中看到引用文件。

其他引用文件,如 Microsoft.owin,是 Microsoft.AspNet.SignalR 命名空间的依赖项。由于我们的应用程序是基于 OWIN 的应用程序,因此我们必须创建一个类“Startup.cs”。在此文件中,将添加应用程序管道的组件。OWIN 属性指定项目启动的属性类型,并且配置方法设置应用程序的 SignalR 映射。 “Startup.cs”的代码如下所示

using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

现在,创建一个数据库。由于我们将创建一个注册和登录系统,因此我们将从数据库中获取登录详细信息进行登录。当用户注册时,它会将用户详细信息存储到数据库中,并在用户登录应用程序时使用相同的详细信息。

创建数据库

Create Database SignalRdb 

创建一个 并插入管理员用户的记录

USE [SignalRdb]

GO

CREATE TABLE [dbo].[tbl_Users](
       
[ID] [int] IDENTITY(1,1) NOT NULL,
       [UserName] [varchar](50) NULL,
       [Email] [varchar](50) NULL,
       [Password] [varchar](50) NULL,
       [Photo] [varchar](50) NULL,

 CONSTRAINT [PK_tbl_Users] PRIMARY KEY CLUSTERED
(
 [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, _
       ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
insert into [dbo].[tbl_Users] _
    (UserName,Email,Password)values('admin','admin@admin.com','12345');

在这里,我跳过了 SQL Server 数据库连接的解释;我希望您了解数据库连接。您将在我附加的源代码中找到所有内容。

创建数据库后,创建一个新的 WebForm 注册页面 (Register.aspx)。在这里,我使用现成的 CSS 文件来设计我的注册页面。页面将如下所示

Register.cs 的代码

   public partial class Register : System.Web.UI.Page
    {
        ConnClass ConnC = new ConnClass();
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        protected void btnRegister_ServerClick(object sender, EventArgs e)
        {
            string Query = "insert into tbl_Users(UserName,Email,Password)Values
               ('"+txtName.Value+"','"+txtEmail.Value+"','"+txtPassword.Value+"')";
            string ExistQ = "select * from tbl_Users where Email='"+txtEmail.Value+"'";
            if (!ConnC.IsExist(ExistQ))
            {
                if (ConnC.ExecuteQuery(Query))
                {
                    ScriptManager.RegisterStartupScript(this, GetType(), "Message", 
                    "alert('Congratulations!! You have successfully registered..');", true);
                    Session["UserName"] = txtName.Value;
                    Session["Email"] = txtEmail.Value;
                    Response.Redirect("Chat.aspx");
                }
            }
            else
            {
                ScriptManager.RegisterStartupScript(this, GetType(), "Message", 
                "alert('Email is already Exists!! Please Try Different Email..');", true);
            }
        }
    }

现在,创建一个登录页面 (Login.aspx)。在这里,我使用现成的 CSS 文件来设计我的登录页面。页面将如下所示

    public partial class Login : System.Web.UI.Page
    {
        //Class Object
        ConnClass ConnC = new ConnClass();
        protected void Page_Load(object sender, EventArgs e)
        {
           
        }

        protected void btnSignIn_Click(object sender, EventArgs e)
        {
            string Query = "select * from tbl_Users where Email='" + 
                   txtEmail.Value + "' and Password='" + txtPassword.Value + "'";
            if (ConnC.IsExist(Query))
            {
                string UserName = ConnC.GetColumnVal(Query, "UserName");
                Session["UserName"] = UserName;
                Session["Email"] = txtEmail.Value;
                Response.Redirect("Chat.aspx");
            }
            else
                txtEmail.Value = "Invalid Email or Password!!";
        }
    }

创建新的 WebForm “Chat.aspx” - 这是我们应用程序的主页面,成功登录后,此页面将显示给用户。在这里,用户可以与其他在线用户聊天。还有一个“更改个人资料图片”选项,因此用户可以更改其个人资料图片,该图片在聊天时显示,其他用户也可以看到他的个人资料图片。

现在创建 Hub 类,创建一个名为“ChatHub.cs”的新类,所以这是 Hub 类,在这里我们创建的函数是在“Chat.aspx”页面中使用 jQuery 调用。

  public class ChatHub :Hub
    {
        static List<Users> ConnectedUsers = new List<Users>();
        static List<Messages> CurrentMessage = new List<Messages>();
        ConnClass ConnC = new ConnClass();

        public void Connect(string userName)
        {
            var id = Context.ConnectionId;
           
            if (ConnectedUsers.Count(x => x.ConnectionId == id) == 0)
            {
                string UserImg = GetUserImage(userName);
                string logintime = DateTime.Now.ToString();
                ConnectedUsers.Add(new Users { ConnectionId = id, 
                    UserName = userName, UserImage = UserImg, LoginTime = logintime });

                // send to caller
                Clients.Caller.onConnected(id, userName, ConnectedUsers, CurrentMessage);

                // send to all except caller client
                Clients.AllExcept(id).onNewUserConnected(id, userName, UserImg, logintime);
            }
        }
}

在设计页面中,我们调用此函数。在这里,我只给您一个示例,我们在 Hub 类文件中有许多函数,并在设计页面中调用这些函数。

 $(function () {

            // Declare a proxy to reference the hub.
            var chatHub = $.connection.chatHub;
            registerClientMethods(chatHub);
            // Start Hub
            $.connection.hub.start().done(function () {

                registerEvents(chatHub)
               
            });
        });

在上面的 JQuery 函数中,我们正在初始化 hub 连接,并且我们在 hub start 函数中编写其余的函数。请看下面的函数。在此函数中,我们调用了来自 Hub 类“ChatHub.cs”的函数,并通过参数传递值

// Calls when user successfully logged in
            chatHub.client.onConnected = function (id, userName, allUsers, messages, times) {

                $('#hdId').val(id);
                $('#hdUserName').val(userName);
                $('#spanUser').html(userName);
               
                // Add All Users
                for (i = 0; i < allUsers.length; i++) {

                    AddUser(chatHub, allUsers[i].ConnectionId, allUsers[i].UserName, 
                            allUsers[i].UserImage, allUsers[i].LoginTime);
                }

                // Add Existing Messages
                for (i = 0; i < messages.length; i++) {
                    AddMessage(messages[i].UserName, messages[i].Message, 
                               messages[i].Time, messages[i].UserImage);                 
                }
            }

此方法用于发送消息。在这里,我们传递用户名、消息和消息时间,并通过用户名获取用户图像,我们将用户名存储在数据库中,如果用户没有图像,则我们为此类用户设置一个虚拟图像。

public void SendMessageToAll(string userName, string message, string time)
        {
           string UserImg = GetUserImage(userName);
            // store last 100 messages in cache
            AddMessageinCache(userName, message, time, UserImg);

            // Broad cast message
            Clients.All.messageReceived(userName, message, time, UserImg);

        }

图像存储在 Project 目录中,在这里我们必须为用户图像分配一个目录,图像名称将存储在数据库中,图像将存储在“images/DP/”目录中。

 public string GetUserImage(string username)
        {
            string RetimgName = "images/dummy.png";
            try
            {
                string query = "select Photo from tbl_Users where UserName='" + username + "'";
                string ImageName = ConnC.GetColumnVal(query, "Photo");

                if (ImageName != "")
                    RetimgName = "images/DP/" + ImageName;
            }
            catch (Exception ex)
            { }
            return RetimgName;
        }

当客户端在客户端设置连接后请求 SendMessageToAll 方法,并且服务器一旦收到请求,它将处理并向客户端发送响应。有一个方法可以将消息附加到 HTML DIV 并显示在客户端的用户界面上。客户端代码如下所示

 function AddMessage(userName, message, time, userimg) {

            var CurrUser = $('#hdUserName').val();
            var Side = 'right';
            var TimeSide = 'left';

            if (CurrUser == userName) {
                Side = 'left';
                TimeSide = 'right';
            }

            var divChat = '<div class="direct-chat-msg ' + Side + '">' +
                '<div class="direct-chat-info clearfix">' +
                '<span class="direct-chat-name pull-' + 
                         Side + '">' + userName + '</span>' +
                '<span class="direct-chat-timestamp pull-' + TimeSide + '"">' + 
                 time + '</span>' +
                '</div>' +

                ' <img class="direct-chat-img" src="' + 
                   userimg + '" alt="Message User Image">' +
                ' <div class="direct-chat-text" >' + message + '</div> </div>';

            $('#divChatWindow').append(divChat);
         
            var height = $('#divChatWindow')[0].scrollHeight;
            $('#divChatWindow').scrollTop(height);
        }

用户可以设置他们的个人资料图片,也可以更改他们的图片,所以这里有一个更改用户个人资料图片的选项,我们在这里使用了 Bootstrap 模态弹出窗口。

输出

最终输出将如下所示

结论

在这里,我们学习了 SignalR 和 Nuget 包在项目中的集成,这简化了我们项目的工作,还学习了使用 Bootstrap 进行网页设计。基本上,这只是一个简单的聊天应用程序,您可以使用它与朋友聊天,SignalR 不仅仅是这些。SignalR 还有许多其他有效的用途。所以这是“SignalR 聊天应用”教程的第一部分。我将在下一篇文章中解释私聊的集成,我们将在下一篇文章中添加更多有效的聊天功能。

希望这能帮助您,并且您会喜欢这篇文章,我附上了项目源代码。您可以下载源代码以供参考并查看完整源代码。感谢您的阅读...

请在下面的评论部分提供您宝贵的反馈。

历史

  • 2017 年 12 月 20 日:初始版本
© . All rights reserved.