【问题标题】:SignalR startup exposes timing gap in document "ready" handlerSignalR 启动暴露了文档“就绪”处理程序中的时间间隔
【发布时间】:2014-10-20 16:51:22
【问题描述】:

this SO post 中,我描述了连接 SignalR 应用程序的问题,该应用程序允许 POST 控制器操作回调到触发 POST 的特定客户端。我实施的解决方案涉及在连接 SignalR 内容后在 JavaScript 中获取 SignalR 连接 ID,并将该连接 ID 存储在隐藏的表单字段中。然后,当用户单击表单上的提交按钮时,该隐藏的表单字段将发送到 POST 操作。

这个方案的明显问题是 SignalR 需要几秒钟来建立连接;如果用户在此期间单击提交按钮,则 POST 操作将获取连接 ID 的空字符串。好的,简单的解决方案(我会想到):禁用表单加载时的提交按钮,并在建立连接后重新启用它。 (请注意,如果在用户浏览器中禁用了 JavaScript,HTML 必须以启用按钮开始;只有在启用 JS 时,我必须使用 JS 禁用按钮。)

但这就是我的问题:似乎,至少在 IE 11 中:引用自动生成的 SignalR 集线器脚本会导致浏览器显示页面之间有大约两秒的延迟(并允许用户单击按钮) 以及页面就绪脚本运行时。 在这两秒钟的窗口中,用户可以单击提交按钮并将空连接 ID 发送到 POST 操作。

我的观点是这样的。注意这一行:

    <!-- 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>
}

【问题讨论】:

    标签: javascript jquery asp.net asp.net-mvc signalr


    【解决方案1】:

    尝试在不使用 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 找到。它概述了如何使用生成的代理和不使用生成的代理进行设置。只有在使用 POC 时,我才使用过 gerated 代理。但通常我将集线器设置为不广播生成的脚本,因此它对外界不可见。

    【讨论】:

    • 谢谢 GJohn。我不得不稍微编辑你的答案才能让它工作。我用“connection”替换了几个对“$.connection.hub”的引用,并在 .on 函数后添加了一个缺少的括号。我还添加了一些 cmets。我的编辑正在等待“同行评审”。
    • 啊,是的,很抱歉,一旦您不再使用生成的代理,启动方法就会有点不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多