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

SignalR 进度条简单示例 - 将实时数据从服务器发送到客户端

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (27投票s)

2016 年 9 月 6 日

MIT

3分钟阅读

viewsIcon

122328

一个简单的项目,展示如何在 ASP.NET MVC 应用程序中使用 SignalR 来跟踪长时间运行的进程的进度,并使用 Bootstrap 模态框在客户端显示。

引言

您的应用程序中有一个长时间运行的任务,并且您希望您的用户知道在他们等待进程完成时发生了什么? 这正是您想要使用 SignalR 功能的原因。 您可以显示一个进度条,显示“正在进行中”,并在进程完成时将其删除,但如果您可以向他们提供有关正在进行的进程状态的更详细信息,岂不是更好。 在 SignalR 推出之前,在 Web 应用程序中执行此操作总是很复杂。

这个简单的应用程序将向您展示如何在几分钟内在您的 MVC 应用程序中实现 SignalR。

将 SignalR 添加到项目

开始使用 SignalR 的第一件事是将其添加到您的项目中。 您可以使用 Nuget 包管理器控制台。

转到:工具 > NuGet 包管理器 > 包管理器控制台

插入以下命令并按 Enter:Install-Package Microsoft.AspNet.SignalR

Visual Studio 会为您安装它。

安装完成后,您可以转到您的 *Startup.cs* 文件(该文件会自动添加到 MVC5 项目中,但如果您没有该文件,请查看此链接以了解它是什么以及您为什么要使用它。 Startup.cs) 并将 SignalR 映射到您的应用程序。

using Microsoft.Owin;
using Owin;

[assembly: OwinStartupAttribute(typeof(SignalRProgressBarSimpleExample.Startup))]
namespace SignalRProgressBarSimpleExample
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);

            app.MapSignalR();
        }
    }
}
...

接下来,我们必须包含一些脚本,最好按此顺序。 我已将其包含在我的 *_Layout._cshtml* 文件中。

  1. jQuery - @Scripts.Render("~/bundles/jquery") - MVC 项目已经包含 Jquery,但您可以以任何您想要的方式包含它
  2. Bootstrap - 我们使用 bootstrap 来设计我们的 Web 应用程序,并使用 Modal Popup div 来显示我们的进度
  3. SignalR - *jquery.signalR-2.0.2.min.js*
  4. /signalr/hubs"

您可以从我的 演示项目下载所有这些脚本。

在添加的脚本下方,我们添加一些 JavaScript,我们将使用它从服务器获取数据。

启动连接并处理从服务器发送的数据

$(function () {

            // Reference the auto-generated proxy for the hub.
            var progress = $.connection.progressHub;
            console.log(progress);

            // Create a function that the hub can call back to display messages.
            progress.client.addProgress = function (message, percentage) {
                //at this point server side had send message and percentage back to the client
                //and then we handle progress bar any way we want it
                
                //Using a function in Helper.js file we show modal and display text and percentage
                ProgressBarModal("show", message +  " " + percentage);
                
                //We're filling blue progress indicator by setting the width property to the variable
                //that was returned from the server
                $('#ProgressMessage').width(percentage);
                
                //closing modal when the progress gets to 100%
                if (percentage == "100%") {
                    ProgressBarModal();
                }                
            };

            //Before doing anything with our hub we must start it
            $.connection.hub.start().done(function () {
            
                //getting the connection ID in case you want to display progress to the specific user
                //that started the process in the first place.
                var connectionId = $.connection.hub.id;
                console.log(connectionId);
            });

        });

SignallR Hub

接下来,我们创建一个名为 *Hubs* 的新文件夹,并创建一个名为 *ProgressHub.cs* 的类,该类继承自 Hub。 我们必须有这个类,SignalR 才能在服务器和客户端之间进行通信。 我们不必在此处定义任何方法,因为在此示例中,我们希望直接从服务器发送数据。 其他每个聊天教程都会从客户端调用该方法,然后将数据发送回当时连接的每个其他客户端。

我们的示例使用其他方法来完成一些工作,然后我们从 hub 外部发送数据。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;

namespace SignalRProgressBarSimpleExample.Hubs
{
    public class ProgressHub : Hub
    {
    }
}

在我们的 HomeController 中,有一个我们从客户端的按钮调用的方法,该方法会完成一些工作,并在每次循环遍历每个项目时将数据发送到客户端。

public JsonResult LongRunningProcess()
        {
    //THIS COULD BE SOME LIST OF DATA
    int itemsCount = 100;

    for (int i = 0; i <= itemsCount; i++)
    {
        //SIMULATING SOME TASK
        Thread.Sleep(500);

        //CALLING A FUNCTION THAT CALCULATES PERCENTAGE AND SENDS THE DATA TO THE CLIENT
        Functions.SendProgress("Process in progress...", i , itemsCount);
    }

    return Json("", JsonRequestBehavior.AllowGet);
}

在完成每个任务的最后,我们调用 Functions.SendProgress("Process in progress...", i , itemsCount); 将数据发送回客户端。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using SignalRProgressBarSimpleExample.Hubs;

namespace SignalRProgressBarSimpleExample.Util
{
    public class Functions
    {
        public static void SendProgress(string progressMessage, int progressCount, int totalItems)
        {
            //IN ORDER TO INVOKE SIGNALR FUNCTIONALITY DIRECTLY FROM SERVER SIDE WE MUST USE THIS
            var hubContext = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();

            //CALCULATING PERCENTAGE BASED ON THE PARAMETERS SENT
            var percentage = (progressCount * 100) / totalItems;

            //PUSHING DATA TO ALL CLIENTS
            hubContext.Clients.All.AddProgress(progressMessage, percentage + "%");
        }
    }
}

hubContext.Clients.All.AddProgress(progressMessage, percentage + "%"); - 将数据发送到当时连接的所有客户端(用于本教程的目的)。 查看有关 SignalR 客户端、组的更多信息...

关注点

在阅读了许多关于实现 SignalR 的教程之后,我决定制作本教程(这是我的第一个教程)来帮助您快速开始使用 SignalR。 此示例不是另一个聊天教程,而是一个进度条教程。

请随意下载示例项目并进行测试...

© . All rights reserved.