【发布时间】:2014-10-19 19:15:43
【问题描述】:
短版
在我的 POST 操作例程中,如何向客户端中运行的某些 JavaScript 发送通知?似乎 SignalR 应该是一个简单的解决方案,但我不知道如何在 POST 操作的客户端页面中对位于 JavaScript 中的 SignalR 客户端进行回调。
具体来说,我似乎需要一个“连接 ID”才能让 SignalR 与特定客户端对话,但我不知道如何在我的 POST 操作或客户端 JavaScript 中获取其中一个。
整个(不那么丑陋)的故事
在我的 MVC 应用中,我的 POST 操作可能需要很长时间才能完成。如果 POST 操作决定需要很长时间才能完成,我想通知页面上的一些 JavaScript,以便它可以向用户显示 “请稍候...” 通知。
这似乎是 SignalR 应该让我非常轻松的事情。在basic tutorial之后,我添加了一个Hub并在我的视图中创建了一个JS回调:
请注意,集线器没有方法。我的客户只需要一个只读通知。无需调用 Hub 上的任何方法向外界写入消息。
public class MyHub: Hub
{
}
该视图只有一个带有提交按钮的表单和一个隐藏的“请稍候”消息,SignalR 例程可以显示该消息。视图模型有一个字符串属性,我可以使用它来将 SignalR“连接 ID”传递给 POST 控制器(假设我知道如何获取它)。
@model SignalRTest.Models.MyViewModel
@using (Html.BeginForm()) {
@Html.HiddenFor(m => m.SignalrConnectionId)
<button type="submit" class="btn btn-primary">Go to it!</button>
}
<div id="hidden-msg" hidden="hidden">
<p>Please wait...</p>
</div>
@section scripts {
<!-- Reference the SignalR library. -->
<script src="~/Scripts/jquery.signalR-2.1.2.min.js"></script>
<!-- Reference the autogenerated SignalR hub script. -->
<script src="~/signalr/hubs"></script>
<!-- SignalR script to update the page -->
<script>
$(function () {
// Get a reference to the server "hub" class (camelCase)
var hub = $.connection.interviewDoneHub;
// Get our connection ID and store it in a hidden field
// so that it is sent to the POST action
// var connectionId = $.connection.hub.id; //This doesn't work!
// $('#@Html.IdFor(m => m.SignalrConnectionId)').attr(connectionId, '');
// Create a function that the hub can call
hub.client.myCallback = function () {
$('#hidden-msg').show();
};
// Start the connection.
$.connection.hub.start().done(function () {
});
});
</script>
}
同时在我的 POST 控制器操作中,我调用了 JS 回调:
[HttpPost]
public async Task<ActionResult> MyAction(MyViewModel model)
{
// We've decided that this will take a while. Tell the client about it...
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.myCallback();
//context.Clients.Client(model.SignalrConnectionId).myCallback();
await Task.Delay(2000);
return RedirectToAction("NextPage");
}
现在,我的问题是:作为概念验证测试,我使用这段代码来调用 JS 回调:
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.myCallback();
这只是花花公子。但是,显然,我想调用与 POST 操作关联的特定客户端。 C# Intellisense 告诉我应该可以调用
context.Clients.Client("connectionId").myCallback();
但我不知道如何获得所需的“connectionId”字符串。我认为我无法在 POST 控制器中获取客户端 ID,因为那时我没有任何类型的 SignalR 连接到客户端。我想我会让客户端获取它的连接 ID 并将其提供给视图模型中的 POST 控制器,但我还没有找到从 SignalR 框架中获取连接 ID 的神奇 JS 代码。
我发现了几篇 SO 文章中的事实陈述:
connectionId = $.connection.hub.id;
但这会返回undefined。我找到了这个SignalR JS Client Wiki page,上面写着:
连接.id
获取或设置当前连接的客户端ID
但这也会返回undefined。
这又回到了我原来的问题。也许我不了解连接 ID 是什么的基本知识......
【问题讨论】:
-
您的 MVC 控制器是否有原因不能在需要时简单地连接到您的集线器,然后简单地告诉集线器发送此消息并为其提供您想要通知的 connectionId?
-
这就是问题的重点。我不知道如何获取连接 ID。
标签: javascript asp.net asp.net-mvc asp.net-mvc-4 signalr