web-dev-qa-db-ja.com

SignalRはstart()。done()の後で常に準備ができているとは限りませんか?

SignalRで動作する小さなプロジェクトがありますが、非常に一貫性のない動作が発生しています。

_<script type="text/javascript">
    $(function () {
        var chat = $.connection.brewBattleHub;
        $.connection.hub.start().done(function () {
            $("#broadcast").click(function () {
                // Call the chat method on the server
                chat.server.roll($("#username").val(), $("#drinkname").val());
            });
            chat.server.sendMessage("SignalR loaded...");
        });
    });
</script>
_

ページをロードすると、「SignalRがロードされました」というメッセージが表示される場合と、表示されない場合があります。

このページには他にもいくつかの機能があり、これも機能しない場合があります。ボタンをクリックして物事を十分に起こせば、最終的にはすべてが一度に完了します...この時点から、すべてが黄金色になり、完全に機能します。

start().done()?すべての準備ができていることを確認しませんか?

===補遺、私はjquery mobileを参照していません(グーグルはそうするときにバグがあると述べました)

18
4imble

今週、.done()のコードが実行されなかったことを除いて、同様の問題が発生しました。ロギングを有効にしましたが、何もログに記録されませんでした。ブラウザのコンソールを確認してもエラーはありませんでした。ブラウザの開発ツールを見ると、start()を呼び出したときにネットワークアクティビティがなかったことがわかりました。 $ .connection.myhubclassによって返されるプロキシにすべてのメソッドが含まれていることを確認したので、サーバーと通信でき、サーバー側のコードが正しく設定されていることがわかりました。

コードとドキュメントを何度も確認した後、私は何も悪いことをしていないと確信しました。 SignalRは非常に単純なので、例に従うと間違って実行するのはかなり困難です。私はこれを理解しようとしてかなり長い間机の上で頭を殴りました。

次に、コンソールからSignalRのstartメソッドを実行すると、機能することに気付きました。そのため、接続を開始するのが早すぎたと思いました。これから初期化コードを変更することで問題を解決しました:

$.connection.hub.start().done(function () {
  //Do interesting stuff
});

これに:

setTimeout(function () {
    $.connection.hub.start().done(function () {
      //Do interesting stuff
    });
}, 5000);

その遅延を5秒からもっと短い時間に減らすことができると確信していますが、余分な時間は、ブラウザーが接続を作成する準備を整えるために必要な時間であるように見えました。その遅延が発生すると、ロギングが機能し始め、接続が確立され、サーバー側のOnConnected()が実行され、done()がクライアントで実行されました。

これを理解した後、JavaScriptの読み込み順序を再確認しました。何かが順不同で読み込まれているのではないかと思いましたが、SignalRサンプルによると順序は正しいです。 jQuery、SignalR、/ signalr/hubsをロードしてから、すべてを初期化するスクリプトファイルをロードします。

なぜその遅延が必要だったのかについての提案を歓迎します。どのドキュメントにも表示されていないので、自分がやったことがあるかもしれません。幸い、このページでは、SignalRを起動する前のわずかな遅延は問題ではありません。

13
Steve Hiner

SignalRロギングを有効にして、問題のデバッグに役立ててください。開始が成功しない場合に備えて、failハンドラーを追加することもできます(これはありそうにありませんが)。これを実行したら、ブラウザのF12ツールを調べて、JSとネットワークログを確認できます。

<script type="text/javascript">
    $(function () {
        $.connection.hub.logging = true;
        var chat = $.connection.brewBattleHub;
        $.connection.hub.start().done(function () {
            $("#broadcast").click(function () {
                // Call the chat method on the server
                chat.server.roll($("#username").val(), $("#drinkname").val());
            });
            chat.server.sendMessage("SignalR loaded...");
        }).fail(function (reason) {
            console.log("SignalR connection failed: " + reason);
        });
    });
</script>
9
halter73

私は解決策を見つけました(私の問題による限り)。 IE11でSignalRを約7〜8秒間ロードしましたが、コンソールで「デバッグ」しようとしましたが、ロードの遅延の原因が見つかりました。

[13:13:04 GMT + 0200(...)] SignalR:iframeのロードイベントへのバインド。
[13:13:09 GMT + 0200(...)] SignalR:接続しようとしたときにforeverFrameがタイムアウトしました。
[13:13:09 GMT + 0200(...)] SignalR:フレームを永久に停止します。

5秒かかりました。 iframeを読み込もうとします。

IE11は通常longPollingを使用できるため、適切な解決策はiframeをオフにすることです。

$.connection.hub.start(({ transport: ['webSockets', 'serverSentEvents', 'longPolling'] }))
3
Jarzyn

切断後に接続を再確立しようとしたときにのみ発生する同様の問題がありました。切断ハンドラーからstart()を呼び出し、start.done()からメッセージを送信しようとしました。次に、SignalRの準備ができていないというエラーメッセージが表示されました。

ログでstart.done()がすぐに解決されたので、私の場合は切断から開始、そして送信への呼び出しがあったことに気づきました。切断ハンドラーにsetTimeoutを追加して、開始と送信が切断から切り離されるようにしました。それで問題は解決しました。

0
Johan Franzén