SignalR 2.2 客户端未收到任何消息
Posted
技术标签:
【中文标题】SignalR 2.2 客户端未收到任何消息【英文标题】:SignalR 2.2 clients not receiving any messages 【发布时间】:2016-08-25 15:00:59 【问题描述】:我有一个在控制台应用程序上下文中运行的自托管 SignalR 应用程序。我通过使用包装类连接到其中的集线器,以防止我不得不从我的 ASP.NET 项目中引用 SignalR.Core 程序集。所以它是我的应用程序中的另一个 C# 类,负责将消息广播到连接的客户端。
我可以直接从 javascript 调用 PlanHub
方法(Register
和 Unregister
),这些断点会被命中。但是,当我从集线器外部的类调用客户端方法时(即使我使用Clients.All
来消除组注册问题),客户端永远不会收到消息。我做错了什么?
运行此代码时,我可以验证Clients.All.updateStatus(planId, message);
代码是否成功命中,但客户端控制台上没有记录任何内容。
以下是相关代码:
PlanHub.cs
public class PlanHub : Hub
private const string GroupPrefix = "PlanGroup_";
public void Register(int companyId)
Groups.Add(Context.ConnectionId, $"GroupPrefixcompanyId");
public void Unregister(int companyId)
Groups.Remove(Context.ConnectionId, $"GroupPrefixcompanyId");
PlanPublisher.cs
public class PlanPublisher
private readonly static Lazy<PlanPublisher> _instance = new Lazy<PlanPublisher>(() =>
new PlanPublisher(GlobalHost.ConnectionManager.GetHubContext<PlanHub>().Clients));
private IHubConnectionContext<dynamic> Clients get; set;
private PlanPublisher(IHubConnectionContext<dynamic> clients)
Clients = clients;
public static PlanPublisher Instance => _instance.Value;
public void UpdateStatus(int planId, string message)
//This code gets hit and no exceptions are thrown, but the clients
//never receive the message. Using Clients.All instead of my
//Groups for testing -- still doesn't work
Clients.All.updateStatus(planId, message);
调用代码(从另一个 C# 类中)
PlanPublisher.Instance.UpdateStatus(plan.Id, $"Publishing started for plan.Name...");
Javascript
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="~/scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="http://localhost:8080/signalr/hubs"></script>
<script>
$(document).ready(function()
$.connection.hub.url = "http://localhost:8080/signalr";
var planMessagePublisher = $.connection.planHub;
planMessagePublisher.client.updateStatus = function (planId, message)
console.log('Status: ' + planId + ' - ' + message);
;
$.connection.hub.start().done(function()
//This works! My PlanHub.Register method gets called successfully
planMessagePublisher.server.register(@Model.CompanyId);
// New connection ID is successfully sent to console
console.log('Now connected, connection ID=' + $.connection.hub.id);
);
);
</script>
JS 控制台调试器输出
jquery.signalR-2.2.0.min.js?v=8588299:8 [06:23:19 GMT-0700 (Pacific Daylight Time)] SignalR: Auto detected cross domain url.
jquery.signalR-2.2.0.min.js?v=8588299:8 [06:23:19 GMT-0700 (Pacific Daylight Time)] SignalR: Client subscribed to hub 'planhub'.
jquery.signalR-2.2.0.min.js?v=8588299:8 [06:23:19 GMT-0700 (Pacific Daylight Time)] SignalR: Negotiating with 'http://localhost:8080/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22planhub%22%7D%5D'.
jquery.signalR-2.2.0.min.js?v=8588299:8 [06:23:19 GMT-0700 (Pacific Daylight Time)] SignalR: webSockets transport starting.
jquery.signalR-2.2.0.min.js?v=8588299:8 [06:23:19 GMT-0700 (Pacific Daylight Time)] SignalR: Connecting to websocket endpoint 'ws://localhost:8080/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAA5D8YUVyzBEG4tTlTaGn0MgAAAAACAAAAAAADZgAAwAAAABAAAABDjF1MaCTzZI0XTM8gC29xAAAAAASAAACgAAAAEAAAAKrk0jv%2FKF4YFzDvNwmSR8IoAAAAacm1d1r7dJpjOtVtCFIFRpugkubyZm1e5Z8OtOFtnhZyEBO1SO4lqhQAAABiG7hBydTiypPh8k2ZYz20ropNxw%3D%3D&connectionData=%5B%7B%22name%22%3A%22planhub%22%7D%5D&tid=6'.
jquery.signalR-2.2.0.min.js?v=8588299:8 [06:23:19 GMT-0700 (Pacific Daylight Time)] SignalR: Websocket opened.
jquery.signalR-2.2.0.min.js?v=8588299:8 [06:23:19 GMT-0700 (Pacific Daylight Time)] SignalR: webSockets transport connected. Initiating start request.
jquery.signalR-2.2.0.min.js?v=8588299:8 [06:23:19 GMT-0700 (Pacific Daylight Time)] SignalR: The start request succeeded. Transitioning to the connected state.
jquery.signalR-2.2.0.min.js?v=8588299:8 [06:23:19 GMT-0700 (Pacific Daylight Time)] SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332, keep alive timeout of 20000 and disconnecting timeout of 30000
jquery.signalR-2.2.0.min.js?v=8588299:8 [06:23:19 GMT-0700 (Pacific Daylight Time)] SignalR: Invoking planhub.Register
jquery.signalR-2.2.0.min.js?v=8588299:8 [06:23:19 GMT-0700 (Pacific Daylight Time)] SignalR: Invoked planhub.Register
它注册成功,但从未收到任何数据。 Clients.All.updateStatus(planId, message);
断点被多次命中,但控制台从未收到任何额外的日志记录数据。
编辑: 有人建议我调查一下自定义依赖解析器是否在起作用。此处发布的代码存在于其自己的项目中,除了您在此处看到的内容外,几乎没有其他内容。调用PlanPublisher.UpdateStatus()
的代码确实有一个自定义依赖解析器,但这无关紧要,因为它在自己的程序集中被隔离了。 PlanPublisher.cs
和 PlanHub.cs
包含在一个非常简单的项目中,它只引用了 SignalR.Core 和 SignalR.SelfHost。
【问题讨论】:
您需要提供最小的示例来重现您的问题。我只是尝试使用您在服务器端和客户端提供的确切代码运行,它运行良好,没有任何问题。 @Scott,你设法以某种方式解决它吗?因为我面临着同样的问题。有趣的部分——如果我尝试为小组发布,它会起作用,但不适用于所有人。另一方面,当我创建一个单独的项目只是为了尝试此功能时,一切正常。 【参考方案1】:我试图简化您的示例(使用 SignalR 2.2.0)
集线器类:
public class PlanHub : Hub
private const string GroupPrefix = "PlanGroup_";
// hubcontext
private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext <PlanHub> ();
public void Register(int companyId)
Groups.Add(Context.ConnectionId, $"GroupPrefixcompanyId");
public void Unregister(int companyId)
Groups.Remove(Context.ConnectionId, $"GroupPrefixcompanyId");
// static method using hub context
public static void Static_UpdateStatus(int planId, string message)
hubContext.Clients.All.updateStatus(planId, message);
由于我没有真正的后端并且我不知道您将如何做到这一点,所以我只是设置了一个计时器,每 10 秒从 C# 调用该方法。
调用和虚拟计时器:
public void startTimer()
timer = new System.Timers.Timer();
timer.Elapsed += new System.Timers.ElapsedEventHandler(ExecuteTimerJob);
timer.Interval = 10000; // 10 sec
timer.Start();
public static void ExecuteTimerJob(object source, System.Timers.ElapsedEventArgs e)
// this is the call from C#
PlanHub.Static_UpdateStatus(123, "some message");
JS:
$(function ()
var planHub = $.connection.planHub;
$.connection.hub.start().done(function ()
console.debug('Connected to PlanHub...');
)
planHub.client.updateStatus = function (planId, message)
console.log("planId: " + planId);
console.log("message: " + message);
);
浏览器控制台中的结果:
【讨论】:
【参考方案2】:试试这个:
public void UpdateStatus(int planId, string message)
var clients = GlobalHost.ConnectionManager.GetHubContext<PlanHub>().Clients;
clients.All.updateStatus(planId, message);
我认为问题在于 PlanPublisher 在中心上下文(和 Clients)创建之前被初始化。
【讨论】:
感谢您的建议。刚试了一下,还是一样的。 能贴出.js控制台调试吗?$.connection.hub.logging = true;
以上是关于SignalR 2.2 客户端未收到任何消息的主要内容,如果未能解决你的问题,请参考以下文章