如何使用SignalR向客户端报告文件进度

本文关键字:文件 报告 客户端 何使用 SignalR | 更新日期: 2023-09-27 18:09:07

我写了一个组件,获取和excel文件,并将其数据存储到数据库中。因为我想让这个类支持不同的环境(例如在控制台应用程序中使用它),所以我决定创建一些事件:

public interface IDataSeeder
{
    Task Seed(string fileName);
    event EventHandler<UserSucceedEventArgs> UserAdded;
    event EventHandler<UserErrorEventArgs> Error;
    event EventHandler<UserUpdateEventArgs> UserUpdated;
    event EventHandler<FinishDataSeederEventArgs> ProcessCompleted;
}

每个事件将在Seed方法内的不同位置触发。它在我的控制台应用程序中很有魅力。
现在我想在我的ASP中使用这个组件。. NET MVC应用程序,为此我决定使用SignalR将事件的数据推送到客户端,所以我创建了一个这样的集线器:

public class ProgressHub : Hub
{
    public static void UserAdded(UserSucceedEventArgs e)
    {
        var ctx = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();
        ctx.Clients.All.userAdded(e);
    }
    public static void Error(UserErrorEventArgs e)
    {
        var ctx = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();
        ctx.Clients.All.error(e);
    }
    public static void UserUpdated(UserUpdateEventArgs e)
    {
        var ctx = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();
        ctx.Clients.All.userUpdated(e);
    }
    public static void ProcessCompleted(FinishDataSeederEventArgs e)
    {
        var ctx = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();
        ctx.Clients.All.processCompleted(e);
    }
}

然后我创建了这个动作方法来获取上传的文件,并把它传递给我的组件:

[HttpPost]
public async Task<ActionResult> AddFromExcel(HttpPostedFileBase excelFile)
{
    if (excelFile != null)
    {
        var fileName = Utilities.UploadFile.UploadFile.UploadCommonFile(excelFile, "users");
        _dataSeeder.UserAdded += DataSeeder_Succeed;
        _dataSeeder.Error += DataSeeder_Error;
        _dataSeeder.UserUpdated += DataSeeder_Update;
        _dataSeeder.ProcessCompleted += DataSeeder_Finish;
        await _dataSeeder.Seed(Server.MapPath($"~/Content/Files/users/{fileName}"));
        return RedirectToAction("AddFromExcel");
    }
    return RedirectToAction("List");
}
private static void DataSeeder_Finish(object sender, FinishDataSeederEventArgs e)
{
    ProgressHub.ProcessCompleted(e);
}
private static void DataSeeder_Update(object sender, UserUpdateEventArgs e)
{
    ProgressHub.UserUpdated(e);
}
private static void DataSeeder_Error(object sender, UserErrorEventArgs e)
{
    ProgressHub.Error(e);
}
private static void DataSeeder_Succeed(object sender, UserSucceedEventArgs e)
{
    ProgressHub.UserAdded(e);
}

您可以看到,在每个事件处理程序中,我使用我的信号集线器通知客户端。

所有这些过程就像一个消息传递系统,但我不知道如何在web应用程序中实现它。我的代码的一个缺陷是,在附加事件处理程序后,我立即将用户重定向到另一个动作方法,我知道它必须是一个异步过程,但我不知道如何使我的事件异步。

任何想法?

如何使用SignalR向客户端报告文件进度

您要做的是匹配SignalR服务器调用与JavaScript函数,将结果显示给连接的客户端:

<script type="text/javascript">
   // the proxy to your hub
   var hub = $.connection.ProgressHub;
   // the function that will be called when you call
   // ctx.Clients.All.userAdded(e);
   hub.client.userAdded = function (data) {
      // show the data
      alert(data);
   };
   // follow suit with the rest of the functions
   hub.client.error = function (data) {
      alert(data);
   };
   // etc
</script>