5

编辑:David Fowler 要求提供完整代码以尝试复制问题。这是完整的代码

除了这里转载的代码,我还上传了完整的Visual Studio 2010解决方案到以下网址

http://www.sendspace.com/file/lfeurf(网址现已过期,不再有效)

请随时下载并测试它。

这是我的发现

  1. 在 Hub 代码中仅添加一个组将使应用程序正常工作,没有问题
  2. 添加 2 个组将阻止信号器工作或仅在一个方向工作。即:消息将从浏览器1传输到浏览器2,但不会从浏览器2传输到浏览器1

原始问题:我在 MVC3 网站中使用 Signalr 1.0.0-rc1。我的客户有时需要属于多个组。这是我的集线器和客户端javascript中的代码

客户端 javascript 和 HTML

<script type="text/javascript">
    //start signalr
    var message = $.connection.messageHub;

    // Declare a function on the message hub so the server can invoke it          
    message.client.send = function (message) {
        alert(message);
    }

    // Start the connection and join groups
    $.connection.hub.start();

    //bind click event of button to invoke send function on server
    $(document).ready(function () {
        $("#target").click(function () {
            message.server.send("Hello from signalr");
        });
    });
</script>

<button id="target">Click to send message to other clients</button>

服务器端集线器

public class MessageHub: Hub
    {
        public Task AddGroups()
        {
            //add 1st group
            Groups.Add(Context.ConnectionId, "foo");
            //add 2nd group
            return Groups.Add(Context.ConnectionId, "foobar");
        }

        //this method will be called from the client
        public void Send(string message)
        {
            Clients.OthersInGroup("foobar").send(message);
        }

        //automatically join groups when client first connects
        public override Task OnConnected()
        {
            return AddGroups();
        }

        //rejoin groups if client disconnects and then reconnects
        public override Task OnReconnected()
        {
            return AddGroups();
        }

    }

上面的代码应该在每个客户端第一次连接时添加两个组,但它不起作用。我使用调试器单步执行了 C# 代码,没有抛出任何错误。我也没有看到使用 Chrome 控制台的任何 javascript 错误,但客户端上没有调用 Send 函数。然后我更改了 AddGroups() 方法以仅添加一个组,如下所示

public Task AddGroups()
   {
        //dont add first group
        //Groups.Add(Context.ConnectionId, "foo");
        //add only second group
        return Groups.Add(Context.ConnectionId, "foobar");
   }

现在我的应用程序完美运行。如何添加第二组?看来我误解了加入多个组。谁能告诉我正确的方法吗?

4

2 回答 2

7

您的问题似乎return Groups.Add(Context.ConnectionId, "foobar");AddToGroups5 秒后超时。在SignalR 验证具有指定的客户端已收到添加到组命令之前,Task返回的 fromGroups.Add不会完成。connectionId如果这在 5 秒内没有发生,Task则取消。似乎目前存在一个错误,阻止在andGroups.Add内部等待。OnConnectedOnReconnected

由于您Task要从OnConnectedand返回取消的OnReconnected内容,因此服务器正在阻止客户端建立连接。

一种解决方法是像这样忽略Task返回的Groups.Add

public class MessageHub: Hub
{
    public Task AddGroups()
    {
        //add 1st group
        Groups.Add(Context.ConnectionId, "foo");
        //add 2nd group
        return Groups.Add(Context.ConnectionId, "foobar");
    }

    //this method will be called from the client
    public void Send(string message)
    {
        Clients.OthersInGroup("foobar").send(message);
    }

    //automatically join groups when client first connects
    public override Task OnConnected()
    {
        AddGroups();
        return base.OnConnected();
    }

    //rejoin groups if client disconnects and then reconnects
    public override Task OnReconnected()
    {
        AddGroups();
        return base.OnReconnected();
    }

}
于 2012-12-17T23:03:18.547 回答
2

MyHub.cs

public async Task Subscribe(IEnumerable<string> groups)
    {
        foreach(var group in groups)
        {
            await Groups.Add(Context.ConnectionId, group);
        }
    }

Javascript:

$.connection.hub.start().done(function () {
                var groups = ["foo","bar"];

                tileHub.server.subscribe(groups)
});
于 2014-03-23T20:20:20.733 回答