SignalR - 发送消息OnConnected

时间:2015-05-20 22:35:07

标签: c# asp.net signalr signalr-hub signalr.client

我今天一直在尝试使用SignalR并且非常整洁。基本上我想要实现的目标如下:

一旦设备连接,它应该向第一个发送消息。如果有超过1个连接的设备,我想发送两条消息。除了最后连接的客户端之外的所有。并且只有一条消息 最后连接的客户端。

当我将代码放入自定义API控制器并基本上调用该操作时,我使用过的代码非常完美,但这不是我想要的。

我想在设备在OnConnected内连接时立即发送消息,而无需任何用户交互,但是当我将代码置于OnConnected覆盖内时,它会停止工作。它不再发送给特定的客户端(首先连接并最后连接)。

我希望有人能够帮助我解决这个问题,因为我现在已经敲了几个小时。

    public override System.Threading.Tasks.Task OnConnected()
    {
        UserHandler.ConnectedIds.Add(Context.ConnectionId, UserHandler.ConnectedIds.Count + 1);

        int amountOfConnections = UserHandler.ConnectedIds.Count;
        var lastConnection = UserHandler.ConnectedIds.OrderBy(x => x.Value).LastOrDefault();
        var allExceptLast = UserHandler.ConnectedIds.Take(amountOfConnections - 1).Select(x => x.Key).ToList();

        if (amountOfConnections == 1)
        {
            Clients.Client(UserHandler.ConnectedIds.First().Key).hello("Send to only(also first) one");
        }
        else
        {
            Clients.Clients(allExceptLast).hello("Send to everyone except last");
            Clients.Client(lastConnection.Key).hello("Send to only the last one");
        }

        return base.OnConnected();
    }

4 个答案:

答案 0 :(得分:11)

除非我错过了您的问题,否则解决方案看起来很简单,您只需切换到使用

Clients.Caller.hello("Send to only the last one");

而不是试图了解自己最后一个连接ID。与其他相同,您可以使用:

Clients.Others.hello("Send to everyone except last");

您不需要设置所有逻辑,这2行符合您的需要,并且它们在OnConnected内工作。

答案 1 :(得分:4)

感谢所有的帮助(赞成你们)。实际上发现了问题..它在我的客户端内部。我第一次订阅了“你好”#39;功能,然后我启动了HubConnection。一旦我改变了这个订单,一切都运行良好。

它使用以下客户端代码:

    private async Task ConnectToSignalR()
    {
        var hubConnection = new HubConnection("url");
        hubConnection.Headers["x-zumo-application"] = "clientapikey";

        IHubProxy proxy = hubConnection.CreateHubProxy("ChatHub");

        proxy.On<string>("hello", async (msg) =>
        {
            Console.WriteLine(msg);
        });

        await hubConnection.Start();
    }

答案 2 :(得分:3)

由于您尚未建立连接,因此目前无法在.hello()内尝试调用您的客户端OnConnected功能。但是,我们可以定义服务器中心方法,并在我们的连接.done回调时立即调用它。然后,在我们的新服务器方法中,我们可以重新分配您当前在OnConnected中的逻辑。

这将改变我们的设置并引入一些额外的步骤,但请观察以下示例......

// WhateverHub
public override Task OnConnected()
{
    return base.OnConnected()
}

public void AfterConnected()
{
    // if(stuff) -- whatever if/else first user/last user logic
    // {
        Clients.Caller.hello("message")
    // }
}
var proxy= $.connection.whateverHub;

proxy.client.hello = function(message) {
    // last step in event chain
}

$.connection.hub.start().done(function () {
    proxy.server.afterConnected() // call AfterConnected() on hub
});

所以这里的基本想法是第一次

  1. Connect =&gt; .done(function() { ... });
  2. 致电server.afterConnected()
  3. 在该方法中执行逻辑
  4. 如果我们对条件满意,请致电我们的.hello()客户端功能
  5. 注意 - 此实现适用于JavaScript客户端 - 但同样的想法可以转换为.net客户端。这主要是一个架构问题。

答案 3 :(得分:1)

好吧......你要回来了......所以我认为这可能是问题...... 你应该首先执行你的代码,然后返回任务...或者把一个ContinueWith ...像......一样......

    public override Task OnConnected()
    {
        Task task = new Task(() =>
            {
                UserHandler.ConnectedIds.Add(Context.ConnectionId, UserHandler.ConnectedIds.Count + 1);

                int amountOfConnections = UserHandler.ConnectedIds.Count;
                var lastConnection = UserHandler.ConnectedIds.OrderBy(x => x.Value).LastOrDefault();
                var allExceptLast = UserHandler.ConnectedIds.Take(amountOfConnections - 1).Select(x => x.Key).ToList();

                if (amountOfConnections == 1)
                {
                    Clients.Client(UserHandler.ConnectedIds.First().Key).hello("Send to only(also first) one");
                }
                else
                {
                    Clients.Clients(allExceptLast).hello("Send to everyone except last");
                    Clients.Client(lastConnection.Key).hello("Send to only the last one");
                }
            });

        task.ContinueWith(base.OnConnected());

        return task;
    }

我还没有测试过......这只是猜测......