客户端未从控制器接收SignalR消息

时间:2017-12-19 15:35:12

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

我正在尝试使用SignalR从控制器向客户端组发送消息。 当我的一个控制器中发生事件时,我需要使用信号器集线器推送一条消息,以便在我的客户端屏幕上显示为警报。 我知道这里已经提出了很多问题,我已经阅读并尝试了很多这些问题。由于我是SignalR的新手,他们中的一些人甚至已经帮我把东西放到位。 目前一切似乎都到位了。客户端可以连接到集线器并加入组,控制器可以从集线器调用方法。但客户端从未收到消息,我无法弄清楚原因。我怀疑控制器调用的hub方法没有“看到”客户端,但我无法理解什么是错误。

Hub的代码:

public static class UserHandler
{
    public static HashSet<string> ConnectedIds = new HashSet<string>();
}

[HubName("myHub")]
public class MyHub : Hub
{
    private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
    public void Notify(string groupName, string message)
    {
        Clients.Group(groupName).displayNotification(message);
    }

    public static void Static_Notify(string groupName, string message)
    {
        var toto = UserHandler.ConnectedIds.Count();
        hubContext.Clients.Group(groupName).displayNotification(message);
        hubContext.Clients.All.displayNotification(message);//for testing purpose
    }

    public Task JoinGroup(string groupName)
    {
        return Groups.Add(Context.ConnectionId, groupName);
    }

    public Task LeaveGroup(string groupName)
    {
        return Groups.Remove(Context.ConnectionId, groupName);
    }

    public override Task OnConnected()
    {
        UserHandler.ConnectedIds.Add(Context.ConnectionId);
        return base.OnConnected();
    }

    public override Task OnDisconnected(bool StopCalled)
    {
        UserHandler.ConnectedIds.Remove(Context.ConnectionId);
        return base.OnDisconnected(StopCalled);
    }
}

以下是来自我的控制器的电话:

//(For simplification and readability I define here variables actually obtained by treating some data )
//I already checked that problem did not come from missing data here
string groupName = "theGroupName";
string message = "My beautifull message.";

//prepare signalR call
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();

//Following commented lines are different attempts made based on exemples and answers I found here and on others sites.
//The uncommented one is the one in use at the moment and is also based on an answer (from SO i think)

//context.Clients.Group(_userEmail).displayNotification(message);
//context.Clients.Group(_userEmail).Notify(_userEmail,message);
  MyHub.Static_Notify(_userEmail, message);

这是客户端代码:

$(document).ready(function () {
    var userGroup = 'theGroupName';
    $.connection.hub.url = 'http://localhost/SignalRHost/signalr';
    var theHub = $.connection.myHub;
    console.log($.connection)
    console.log($.connection.myHub)

    theHub.client.displayNotification = function (message) {
        console.log('display message');
        alert(message);
    };

    $.connection.hub.start()
        .done(function () {
            theHub.server.joinGroup(userGroup);
            console.log("myHub hub started : " + $.connection.hub.id)
            console.log(theHub)
        })
        .fail(function () {
            console.log('myHub hub failed to connect')
        });

});

请帮助我理解我无法理解的逻辑或我错过的错误。

编辑:

回答Alisson的评论: Startup.cs我忘了显示

public void Configuration(IAppBuilder app)
    {
        app.Map("/signalr", map =>
        {
            map.UseCors(CorsOptions.AllowAll);
            var hubConfiguration = new HubConfiguration { };
            map.RunSignalR();
        });
    }

重要的事情我也忘了提及:

  • Controller,集线器和客户端是3个不同的项目(因为全局应用程序架构我必须分离集线器逻辑) 所有这些都在我的localhost IIS上,但在不同的端口上
  • 我在“OnConnected”和“onDiconnected”事件上设置了断点,客户端正常连接和断开连接

1 个答案:

答案 0 :(得分:1)

您只需要一个应用程序作为服务器,在您的情况下它应该是SIgnalRHost项目。您的控制器项目应该是服务器的客户端,因此它只需要这个包:

Install-Package Microsoft.AspNet.SignalR.Client 

您的控制器项目实际上不需要引用包含集线器类的项目。在您的控制器中,您将使用C#SignalR客户端连接到服务器(就像在javascript客户端中一样),加入组并调用集线器方法:

var hubConnection = new HubConnection("http://localhost/SignalRHost/signalr");
IHubProxy myHub = hubConnection.CreateHubProxy("MyHub");
await hubConnection.Start();
myHub.Invoke("JoinGroup", "theGroupName");
myHub.Invoke("Notify", "theGroupName", "My beautifull message.");

...最后,您根本不需要Static_Notify

  

由于您将组名称作为Notify上的参数传递   方法,您不需要从控制器加入组。   只有在尝试将消息发送到同一个时才需要   组控制器已连接(然后你不需要通过   组名作为参数)。

SignalR C# Client Reference