0

Web サイト A ( ) で SignalR 永続接続を使用していlocalhost:6599ます。A/index.html をレンダリングして /goose (私の接続名!) に接続すると、SSE 経由でグループが尊重されます。コードを Web サイト B にコピーし ( localhost:58660)、$.connection を絶対 URL に変更すると ( http://localhost:6599/goose)、Web サイト B の signalR クライアントは同じグループに送信されたメッセージを受信しません。

同時に、Web サイト B はメッセージを送信でき、Web サイト A のクライアントはそれらをグループで受信します。グループ メッセージからブロードキャストに変更すると、メッセージは Web サイト A と B の両方のクライアントに届きます。

ウェブサイト A の私のコード:

    <div id="data"></div>

    <script>
        $(document).ready(function() {
            var connection = $.connection('/goose', "group=123", true);

            connection.start().done(function() {

                connection.received(function(data) {
                    console.log(data);
                    $("#data").html(data);
                });

                connection.send("123:hooo");
            }
            );

        });

    </script>

サーバー側:

public class GooseConnection : PersistentConnection
{
    protected override Task OnConnected(IRequest request, string connectionId)
    {
        var group = request.QueryString["group"];

        return Groups.Add(connectionId, group);
    }

    protected override Task OnReceived(IRequest request, string connectionId, string data)
    {
        // Messages are sent with the following format
        // group:message
        string[] decoded = data.Split(':');
        string groupName = decoded[0];
        string message = decoded[1];

        // Send a message to the specified
        return Groups.Send(groupName, message);
    }

    protected override Task OnDisconnected(IRequest request, string connectionId)
    {
        return Groups.Remove(connectionId, request.QueryString["group"]);
    }

}

ウェブサイト B の私のコード:

var connection = null;
        $(document).ready(function () {
            connection = $.connection('http://localhost:6599/goose', "group=123", true);

            connection.start({ jsonp: true }).done(function () {

                connection.received(function (data) {
                    console.log(data);
                    alert('oooyeah');
                    $("#data").html(data);
                });

                connection.send("123:hooo");
            }
            );

        });

        function tryagain() {
            connection.send("123:hooo");
        }

ウェブサイト A からのトレース (フォーマットについて申し訳ありません):

[21:31:58 GMT+0000 (GMT Standard Time)] SignalR: Negotiating with
'/goose/negotiate'. jquery.signalR-1.0.0-rc2.min.js:10 [21:31:58 GMT+0000 (GMT Standard Time)] SignalR: Attempting to connect to SSE endpoint 'http://localhost:6599/goose/connect?transport=serverSentEvents&connectionId=93b07a1b-779f-44e9-87f3-3eb201a97fdd&group=123&tid=0' jquery.signalR-1.0.0-rc2.min.js:10 [21:31:59 GMT+0000 (GMT Standard Time)] SignalR: EventSource connected jquery.signalR-1.0.0-rc2.min.js:10 [21:31:59 GMT+0000 (GMT Standard Time)] SignalR: Now monitoring keep alive with a warning timeout of 40000 and a connection lost timeout of 60000 jquery.signalR-1.0.0-rc2.min.js:10 hooo localhost:18 [21:44:30 GMT+0000 (GMT Standard Time)] SignalR: EventSource readyState: 0 jquery.signalR-1.0.0-rc2.min.js:10 [21:44:30 GMT+0000 (GMT Standard Time)] SignalR: EventSource reconnecting due to the server connection ending jquery.signalR-1.0.0-rc2.min.js:10 [21:44:32 GMT+0000 (GMT Standard Time)] SignalR: EventSource calling close() jquery.signalR-1.0.0-rc2.min.js:10 [21:44:32 GMT+0000 (GMT Standard Time)] SignalR: EventSource reconnecting

Web サイト B からのトレース:

[21:30:33 GMT+0000 (GMT Standard Time)] SignalR: Auto detected cross domain url. jquery.signalR-1.0.0-rc2.min.js:10 [21:30:33 GMT+0000 (GMT Standard Time)] SignalR: Negotiating with 'http://localhost:6599/goose/negotiate'. jquery.signalR-1.0.0-rc2.min.js:10 [21:30:33 GMT+0000 (GMT Standard Time)] SignalR: SignalR: Initializing long polling connection with server. jquery.signalR-1.0.0-rc2.min.js:10 [21:30:33 GMT+0000 (GMT Standard Time)] SignalR: Attempting to connect to 'http://localhost:6599/goose/connect?transport=longPolling&connectionId=d01cebe3-28f6-4150-a606-b9d64224edd7&group=123&tid=3' using longPolling. jquery.signalR-1.0.0-rc2.min.js:10 [21:30:33 GMT+0000 (GMT Standard Time)] SignalR: Longpolling connected jquery.signalR-1.0.0-rc2.min.js:10 [21:30:33 GMT+0000 (GMT Standard Time)] SignalR: Attempting to connect to 'http://localhost:6599/goose?transport=longPolling&connectionId=d01cebe3-28f…cloud.Spotify.Goose.Connections.GooseConnection.123%22%5D&group=123&tid=10' using longPolling. jquery.signalR-1.0.0-rc2.min.js:10 [21:32:29 GMT+0000 (GMT Standard Time)] SignalR: Attempting to connect to 'http://localhost:6599/goose?transport=longPolling&connectionId=d01cebe3-28f…acloud.Spotify.Goose.Connections.GooseConnection.123%22%5D&group=123&tid=2' using longPolling. jquery.signalR-1.0.0-rc2.min.js:10

私が試したこと:

  • 自動再接続を global.asax に追加します ( GlobalHost.HubPipeline.EnableAutoRejoiningGroups();)
  • .start({jsonp:true}) を手動で設定する
  • 各クライアントへのブロードキャスト var context = GlobalHost.ConnectionManager.GetConnectionContext(); context.Connection.Broadcast("これはハックでした"); これは機能します。

さらにデバッグに関するアドバイスをいただければ幸いです。アンディ

4

2 に答える 2

1

グループに関する問題は、クライアントが再接続したときにグループが自動的に再参加しないことが原因である可能性があります。同じドメインで実行している場合、これは問題ではありません。これは、クライアントが、基礎となる接続に問題がない限り再接続しない永久フレームまたはサーバー送信イベント トランスポートを使用している可能性が高いためです。

ただし、SignalR へのクロスオリジン アクセスには、WebSocket またはロング ポーリング トランスポートのいずれかが必要です。グループで発生している問題を考慮して、後者が使用されている可能性があります。(注: WebSocket をサポートするには、SignalR サーバーが Windows 8 または 2012 で .NET 4.5 を実行している必要があります)。ロング ポーリング トランスポートは、メッセージを受信するたびに SignalR サーバーに再接続する必要があります。

この問題を修正するには、次を追加します。

public class GooseConnection : PersistentConnection
{
    protected override IEnumerable<string> OnRejoiningGroups(IRequest request, IEnumerable<string> groups, string connectionId)
    {
        return groups;
    } 
}

OnRejoiningGroups空のコレクションではなくパラメーターを返すようにオーバーライドすることgroupsで、クライアントが再接続したときに、以前に所属していたすべてのグループに再参加できるようになります。ただし、RC2 の時点で、SignalR は、再接続しようとしているクライアントが実際に以前に再参加しようとしているグループに属していたことを確認しません。このgroupsパラメーターは、再接続要求のクエリ文字列から単純に取得されます。もちろん、行儀の良いクライアントは、以前所属していたグループに再参加しようとするだけですが、RC2 で自動グループ再参加を有効にすると、攻撃者は自分自身を任意のグループに追加できるようになります。これは多くのアプリケーションでは問題になりませんが、グループの再参加がデフォルトで有効になっていないのはそのためです。

SignalR の RTM バージョンでは、グループの自動再参加が既定で有効になります。クライアントが再参加しようとするグループのリストもサーバーによって署名され、より安全になります。

于 2013-02-15T22:38:05.727 に答える
0

EnableAutoRejoiningGroupsは Hubs API の機能であり、下位のPersistentConnectionAPI レイヤーで作業しているため、役に立ちません。@ Halter73が言ったように、レイヤーOnRejoiningGroupsでそれを行う方法です。PersistentConnection

于 2013-02-15T16:57:17.243 に答える