0

我在网站 A ( localhost:6599) 中使用 SignalR 持久连接。在渲染 A/index.html 并连接到 /goose(我的连接名称!)时,组在 SSE 上受到尊重。将代码复制到网站 B ( localhost:58660) 并将 $.connection 更改为绝对 URL ( http://localhost:6599/goose) 时,来自网站 B 的 signalR 客户端不会收到发送到同一组的消息。

同时B站可以发送消息,A站客户端会在群里接收。从组消息更改为广播,消息同时到达网站 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

来自网站 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 或长轮询传输。考虑到您在团体中遇到的问题,后者可能会在您的情况下使用。(注意:您的 SignalR 服务器需要在 Windows 8 或 2012 上运行 .NET 4.5 才能支持 WebSockets)。每次接收消息时,长轮询传输都必须重新连接到 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 回答