SignalR 不调用客户端方法
SignalR not calling client methods
所以我已经阅读了与此相关的所有其他 SO 问题,但看起来一切都应该正确设置。我是 运行 一个自托管的 SignalR 控制台应用程序,它有一个空的集线器声明(这是用于从服务器到连接的客户端的单向通信)。
编辑: Link 到重现问题的项目 - https://dl.dropboxusercontent.com/u/66477739/SignalRTest.zip
演示解决方案有 3 个项目:
- SignalRTest.BusinessLogic - 简单的控制台应用程序,每 10 秒发布一条消息。客户端永远不会收到这些消息。这模拟了我的业务逻辑层向连接的客户端推送通知。
- SignalRTest.SelfHost - 自托管 SignalR 应用程序 + 集线器。我向集线器添加了一个 "Send" 方法,只是为了表明当客户端调用
server.send('message');
时一切正常,但当服务器启动消息时它不起作用。 在此控制台中键入 window 并按回车键会将文本发送到网络应用程序。这行得通!
- SignalRTest.UI - 只是一个空白的 MVC 应用程序,只有一个页面可以加载必要的脚本。成功收到的消息只会记录控制台输出,此示例永远不会有任何 UI 更改。
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
应用程序中启动您的服务,那么它将照常工作。
我猜你已经创建了一个构造函数,你可以删除它...
所以我已经阅读了与此相关的所有其他 SO 问题,但看起来一切都应该正确设置。我是 运行 一个自托管的 SignalR 控制台应用程序,它有一个空的集线器声明(这是用于从服务器到连接的客户端的单向通信)。
编辑: Link 到重现问题的项目 - https://dl.dropboxusercontent.com/u/66477739/SignalRTest.zip
演示解决方案有 3 个项目:
- SignalRTest.BusinessLogic - 简单的控制台应用程序,每 10 秒发布一条消息。客户端永远不会收到这些消息。这模拟了我的业务逻辑层向连接的客户端推送通知。
- SignalRTest.SelfHost - 自托管 SignalR 应用程序 + 集线器。我向集线器添加了一个 "Send" 方法,只是为了表明当客户端调用
server.send('message');
时一切正常,但当服务器启动消息时它不起作用。 在此控制台中键入 window 并按回车键会将文本发送到网络应用程序。这行得通! - SignalRTest.UI - 只是一个空白的 MVC 应用程序,只有一个页面可以加载必要的脚本。成功收到的消息只会记录控制台输出,此示例永远不会有任何 UI 更改。
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
应用程序中启动您的服务,那么它将照常工作。
我猜你已经创建了一个构造函数,你可以删除它...