2014-10-20 32 views
0

this SO post中,我通過佈線SignalR應用程序的問題來描述,該應用程序允許POST控制器操作回調到觸發POST的特定客戶端。我實現的解決方案涉及在SignalR的東西連線並將該連接ID存儲在隱藏的表單字段中時在JavaScript中獲取SignalR連接ID。然後,當用戶單擊表單上的提交按鈕時,該隱藏表單域將發送到POST操作。SignalR啓動暴露了文檔「就緒」處理程序中的時間間隔

該方案的一個明顯問題是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

嘗試連接時不使用由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 proxy。但通常我會將我的集線器設置爲不傳播生成的腳本,因此外部世界不可見。

+0

謝謝GJohn。我不得不編輯你的答案,讓它起作用。我用「連接」替換了幾個對「$ .connection.hub」的引用,並在.on函數後添加了一個缺失的括號。我還添加了一些評論。我的編輯正在等待「同行評議」。 – 2014-10-20 19:03:28

+0

啊,是的,對不起,使用生成的代理後,啓動方法會有點不同。 – Gjohn 2014-10-20 19:06:27