在this SO post中,我描述了连接SignalR应用程序的问题,该应用程序允许POST控制器操作回调到触发POST的特定客户端。我实现的解决方案涉及一旦SignalR内容被连线并在隐藏的表单字段中存储该连接ID,就在JavaScript中获取SignalR连接ID。当用户单击表单上的提交按钮时,该隐藏的表单字段将被发送到POST操作。
这个方案的明显问题是SignalR建立连接需要几秒钟;如果用户在此期间单击提交按钮,则POST操作将获取连接ID的空字符串。好的,简单的解决方案(我想过):在表单加载时禁用提交按钮,并在建立连接后重新启用它。 (请注意,HTML必须以启用按钮开始,如果在用户的浏览器中禁用了JavaScript;我必须使用JS仅在启用JS时禁用该按钮。)
但这就是我的问题:似乎至少在IE 11中:引用自动生成的SignalR集线器脚本会导致浏览器显示页面之间大约两秒钟的延迟(并允许用户点击按钮)并且当页面就绪脚本运行时。在这两秒窗口期间,用户可以单击提交按钮并向POST操作发送空连接ID。
我的观点看起来像这样。请注意这一行:
<!-- Reference the autogenerated SignalR hub script. -->
<script src="~/signalr/hubs"></script>
导致页面在页面“就绪”脚本执行之前显示几秒钟!
@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>
$(document).ready(function () {
// Disable the submit buttons (until we have a connection ID)
$('input[type="submit"], button[type="submit"]')
.prop('disabled', true)
.attr('data-sbs-enable-me', '');
// Get a reference to the server "hub" class (camelCase)
var hub = $.connection.myHub;
// Create a function that the hub can call
hub.client.myCallback = function () {
$('#hidden-msg').show();
};
// Start the connection.
$.connection.hub.start()
.done(function () {
// Get our connection ID and store it in a hidden field so that it is
// sent to the POST action
$('#@Html.IdFor(m => m.SignalRConnectionId)')
.attr('value', $.connection.hub.id);
// Enable the buttons
$('[data-sbs-enable-me]')
.prop('disabled', false)
.removeAttr('data-sbs-enable-me');
})
.fail(function () { });
});
</script>
}
答案 0 :(得分:0)
尝试在不使用SignalR集线器生成的集线器代理脚本的情况下进行连接。
@section scripts {
<!-- Reference the SignalR library. -->
<script src="~/Scripts/jquery.signalR-2.1.2.min.js"></script>
<!-- SignalR script to update the page -->
<script>
$(document).ready(function () {
// Disable the submit buttons (until we have a connection ID)
$('input[type="submit"], button[type="submit"]')
.prop('disabled', true)
.attr('data-sbs-enable-me', '');
// Get a reference to the server "hub" class (camelCase)
var connection = $.hubConnection();
var myHubProxy = connection.createHubProxy('myHub');
// Create a function that the hub can call
myHubProxy.on('myCallback', function() {
$("#hidden-msg').show();
});
// Start the connection.
connection.start()
.done(function () {
// Get our connection ID and store it in a hidden field so that it is
// sent to the POST action
$('#@Html.IdFor(m => m.SignalRConnectionId)')
.attr('value', connection.id);
// Enable the buttons
$('[data-sbs-enable-me]')
.prop('disabled', false)
.removeAttr('data-sbs-enable-me');
})
.fail(function () { });
});
</script>
}
可以找到SignalR客户端配置的文档here。它概述了如何使用生成的代理设置并且没有生成的代理。只有在我使用gerated代理时才会使用POC。但通常我将我的集线器设置为不广播生成的脚本,以便外部世界看不到它。