2016-10-02 164 views
0

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

编辑:链接到项目,再现问题 - https://dl.dropboxusercontent.com/u/66477739/SignalRTest.zip

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

  • SignalRTest.BusinessLogic - 简单的控制台应用程序,刚刚发布的消息每10秒。这些消息永远不会被客户端收到。这模拟了我的业务逻辑层将通知推送给连接的客户端。
  • SignalRTest.SelfHost - 自托管的SignalR应用程序+集线器。我向集线器添加了一个“发送”方法,只是为了显示当客户端呼叫server.send('message');时一切正常,但在服务器启动消息时它不起作用。 在此控制台窗口中键入并按回车键将发送该文本到Web应用程序。这工作!
  • 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..."); 
01调用代码

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

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

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

的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); 
     } 
    } 
} 

,如果我在控制台窗口中输入并按下回车键,则消息将成功发送到客户端,并且它将记录在控制台输出窗口中。

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

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"); 

我卡我为什么不能从外部组件消息发布到连接的客户端调用代码。

+0

所以你设置在控制台应用程序的服务器signlarR,然后尝试从另一个组件发布的消息(同时仍运行相同的控制台应用程序)它失败了? – Evk

+0

是的,这是正确的。 – Scott

+0

也许你有最小的VS项目,再现? – Evk

回答

2

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

+0

BusinessLogic项目调用SelfHost项目中存在的MessagePublisher.Publish()(并反过来尝试将消息推送到连接的客户端 - 从SelfHost中)。 BusinessLogic类中没有任何与SignalR有关的代码。我是否正确理解你的顾虑? – Scott

+0

您的BusinessModel是您运行的控制台应用程序。是的,它引用SelfHost,但它不运行SignalR,为什么它应该能够发布任何内容?不要运行BusinessLogic作为控制台应用程序,而是从主机引用它。 – Evk

+0

要澄清更多,只有主机信号员可以将消息发布到客户端的过程中,您不能从其他进程执行该操作 – Evk

0

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