如何使用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
服务器调用与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>