信号器 - 加入多个组

时间:2012-12-16 22:56:23

标签: c# asp.net-mvc-3 signalr signalr-hub

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

除了此处转载的代码外,我还将完整的Visual Studio 2010解决方案上传到以下URL

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

请随时下载并测试它。

以下是我的发现

  1. 在Hub代码中只添加一个组将使应用程序正常工作 很好没有问题
  2. 添加2组将阻止信号器 工作或将只在一个方向工作。即:消息将是 从浏览器1发送到浏览器2但不会被发送 从浏览器2到浏览器1
  3. 原始问题: 我在MVC3网站上使用Signalr 1.0.0-rc1。我的客户有时需要属于多个组。这是我的Hub和客户端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");
       }
    

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

2 个答案:

答案 0 :(得分:6)

您的问题似乎是return Groups.Add(Context.ConnectionId, "foobar");中的AddToGroups在5秒后超时。从Task返回的Groups.Add在SignalR验证具有指定connectionId的客户端已收到add to group命令之前未完成。如果在5秒内没有发生这种情况,Task将被取消。目前似乎有一个错误阻止了Groups.AddOnConnected内的OnReconnected等待。

由于您从TaskOnConnected返回已取消的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();
    }

}

答案 1 :(得分: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)
});