SignalR 不调用客户端方法

SignalR not calling client methods

所以我已经阅读了与此相关的所有其他 SO 问题,但看起来一切都应该正确设置。我是 运行 一个自托管的 SignalR 控制台应用程序,它有一个空的集线器声明(这是用于从服务器到连接的客户端的单向通信)。

编辑: Link 到重现问题的项目 - https://dl.dropboxusercontent.com/u/66477739/SignalRTest.zip

演示解决方案有 3 个项目:

PublishStatusHub.cs

public class PublishStatusHub : Hub
{
}

JS

$(document).ready(function () {
    $.connection.hub.url = "http://localhost:8080/signalr";

    var publish = $.connection.publishStatusHub;

    publish.client.addMessage = function (message) {
        console.log(message);
    };

    $.connection.hub.start().done(function() { });
});

从单独的程序集中调用代码

var context = GlobalHost.ConnectionManager.GetHubContext<PublishStatusHub>();
context.Clients.All.addMessage("Starting publish...");

虽然我可以看到上面的代码被执行了(通过断点),但是客户端方法并没有被调用。

我确实打开了 SignalR 日志记录并且没有抛出任何异常。此外,它从不记录传入的消息。

有趣的是,我可以通过自托管控制台应用程序 Program.cs 中的 Main() 方法将消息发送到客户端:

Program.cs

static void Main(string[] args)
{
    string url = "http://localhost:8080";
    using (WebApp.Start(url))
    {
        Console.WriteLine("Server running on {0}", url);

        while (true)
        {
            string message = Console.ReadLine();

            IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<PublishStatusHub>();
            hubContext.Clients.All.addMessage(message);
        }
    }
}

现在,如果我在控制台中键入 window 并按回车键,消息将成功发送到客户端并记录在控制台输出 window 中。

但是,如果我将此代码移动到同一个控制台应用程序中的另一个文件,然后从另一个程序集调用它(这是最终目标),它会再次失败:

MessagePublisher.cs

public class MessagePublisher
{
    public void Publish(string message)
    {
        IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<PublishStatusHub>();
        hubContext.Clients.All.addMessage(message);
    }
}

从单独的程序集中调用代码

var messagePublisher = new MessagePublisher();
messagePublisher.Publish("Test message");

我对为什么无法从外部程序集向连接的客户端发布消息感到困惑。

在您发布的项目中,您试图从完全不同的控制台应用程序 (SignalRTest.BusinessLogic) 发布消息。此应用程序不托管 SignalR 服务,因此不知道连接的客户端。所有客户端都连接到另一个进程中另一个应用程序 (SinglaRTest.SelfHost) 托管的服务。所以这是不可能的。如果您将在 BusinessLogic 应用程序中启动您的服务,那么它将照常工作。

我猜你已经创建了一个构造函数,你可以删除它...