C# SignalR 异常 - 连接在收到调用结果之前开始重新连接
C# SignalR Exception - Connection started reconnecting before invocation result was received
我正在开发 2 个应用程序,第一个是 C# 控制台应用程序,另一个是 Asp.net Web 应用程序。我正在使用 SignalR 连接两者。
这是我的 C# 控制台应用程序(客户端)
public class RoboHub
{
public static IHubProxy _hub;
public RoboHub()
{
StartHubConnection();
_hub.On("GetGoals", () => GetGoals());
_hub.On("PrintMessageRobot", x => PrintMessageRobot(x));
Thread thread = new Thread(MonitorHubStatus);
thread.Start();
}
public void GetGoals()
{
//TODO: Does stuff
}
public void PrintMessageRobot(string msg)
{
Console.WriteLine(msg);
}
public void StartHubConnection()
{
Console.WriteLine("Robo Hub Starting");
string url = @"http://localhost:46124/";
var connection = new HubConnection(url);
_hub = connection.CreateHubProxy("WebHub");
connection.Start().Wait();
Console.WriteLine("Robo Hub Running");
}
public void MonitorHubStatus()
{
while (true)
{
Thread.Sleep(1000);
_hub.Invoke("Ping", "ping").Wait();
Console.WriteLine("WebHub Pinged : " + DateTime.Now);
}
}
}
当控制台应用程序运行时,它会创建一个 RoboHub 实例 class。这反过来启动与 SignalR 集线器的连接,并在单独的线程上启动 MonitorHubStatus 方法,这是我实现的,用于检查 C# 控制台应用程序客户端是否仍主动连接到集线器。
这是我的 Web 中心(在 Asp.net Web 应用程序中)
public class WebHub : Hub
{
/// <summary>
/// This method should be called by the Web Clients.
/// This method should call the method on the robot clients.
/// </summary>
public void GetGoalsHub()
{
lock (UserHandler.Connections)
{
if (UserHandler.Connections.Any(connection => connection.Contains("Robot")))
{
Clients.All.GetGoals();
}
}
//TODO add Error method to call on the client
}
/// <summary>
/// Override Methods
/// </summary>
/// <returns></returns>
public override Task OnConnected()
{
lock (UserHandler.Connections)
{
//Find out who is connecting based on the User-Agent header
var query = (from r in Context.Headers
where r.Key == "User-Agent"
select r).SingleOrDefault().ToString();
if (query.Contains("SignalR.Client.NET45"))
{
UserHandler.Connections.Add("Robot : " + Context.ConnectionId);
}
else
{
UserHandler.Connections.Add("Web Application : " + Context.ConnectionId);
GetGoalsHub();
}
}
Clients.All.UpdateConnections(UserHandler.Connections);
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
lock (UserHandler.Connections)
{
for (int i = 0; i < UserHandler.Connections.Count; i++)
{
if (UserHandler.Connections[i].Contains(Context.ConnectionId))
{
UserHandler.Connections.Remove(UserHandler.Connections[i]);
}
}
}
Clients.All.UpdateConnections(UserHandler.Connections);
return base.OnDisconnected(stopCalled);
}
public void Ping(string msg)
{
Clients.All.PrintMessageRobot("Pong : " + DateTime.Now);
}
}
public static class UserHandler
{
public static List<string> Connections = new List<string>();
}
目前这两个应用程序似乎可以工作一段时间,直到一段时间后随机出现此错误:
Connection started reconnecting before invocation result was received.
此外,Web 中心还应调用 C# 控制台客户端上的任何其他方法,例如 GetGoals 方法。 'Ping Pong' 方法冻结,并在一段时间后抛出类似的异常。在此期间,Web 客户端继续完美运行,并且 Web 客户端可以与中心服务器来回通信。
任何人都可以提出问题所在吗?
编辑:进一步的调查使我相信它与线程有关,但是很难找到问题的根源。
调用调用有问题:
_hub.Invoke("MethodName", "Parameters").Wait();
这里我告诉它等待响应,但是我没有在网络服务器中编写任何响应机制。
此错误已通过切换到以下内容得到修复:
_hub.Invoke("MethodName", "Parameters");
现在它遵循 'fire and forget' 方法,现在不再出现错误。如果其他人收到此错误,请务必检查您是否需要回复。
如果发送到服务器端的数据是 'Non-serializable'(例如)不具有 [Serializable] 属性的业务对象列表
,您将收到相同的错误消息
当有效载荷太大时,我遇到了同样的异常。我通过在 signlr.net 的启动声明中更改以下行来修复它。它删除了大小限制
GlobalHost.Configuration.MaxIncomingWebSocketMessageSize = null;
我正在开发 2 个应用程序,第一个是 C# 控制台应用程序,另一个是 Asp.net Web 应用程序。我正在使用 SignalR 连接两者。
这是我的 C# 控制台应用程序(客户端)
public class RoboHub
{
public static IHubProxy _hub;
public RoboHub()
{
StartHubConnection();
_hub.On("GetGoals", () => GetGoals());
_hub.On("PrintMessageRobot", x => PrintMessageRobot(x));
Thread thread = new Thread(MonitorHubStatus);
thread.Start();
}
public void GetGoals()
{
//TODO: Does stuff
}
public void PrintMessageRobot(string msg)
{
Console.WriteLine(msg);
}
public void StartHubConnection()
{
Console.WriteLine("Robo Hub Starting");
string url = @"http://localhost:46124/";
var connection = new HubConnection(url);
_hub = connection.CreateHubProxy("WebHub");
connection.Start().Wait();
Console.WriteLine("Robo Hub Running");
}
public void MonitorHubStatus()
{
while (true)
{
Thread.Sleep(1000);
_hub.Invoke("Ping", "ping").Wait();
Console.WriteLine("WebHub Pinged : " + DateTime.Now);
}
}
}
当控制台应用程序运行时,它会创建一个 RoboHub 实例 class。这反过来启动与 SignalR 集线器的连接,并在单独的线程上启动 MonitorHubStatus 方法,这是我实现的,用于检查 C# 控制台应用程序客户端是否仍主动连接到集线器。
这是我的 Web 中心(在 Asp.net Web 应用程序中)
public class WebHub : Hub
{
/// <summary>
/// This method should be called by the Web Clients.
/// This method should call the method on the robot clients.
/// </summary>
public void GetGoalsHub()
{
lock (UserHandler.Connections)
{
if (UserHandler.Connections.Any(connection => connection.Contains("Robot")))
{
Clients.All.GetGoals();
}
}
//TODO add Error method to call on the client
}
/// <summary>
/// Override Methods
/// </summary>
/// <returns></returns>
public override Task OnConnected()
{
lock (UserHandler.Connections)
{
//Find out who is connecting based on the User-Agent header
var query = (from r in Context.Headers
where r.Key == "User-Agent"
select r).SingleOrDefault().ToString();
if (query.Contains("SignalR.Client.NET45"))
{
UserHandler.Connections.Add("Robot : " + Context.ConnectionId);
}
else
{
UserHandler.Connections.Add("Web Application : " + Context.ConnectionId);
GetGoalsHub();
}
}
Clients.All.UpdateConnections(UserHandler.Connections);
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
lock (UserHandler.Connections)
{
for (int i = 0; i < UserHandler.Connections.Count; i++)
{
if (UserHandler.Connections[i].Contains(Context.ConnectionId))
{
UserHandler.Connections.Remove(UserHandler.Connections[i]);
}
}
}
Clients.All.UpdateConnections(UserHandler.Connections);
return base.OnDisconnected(stopCalled);
}
public void Ping(string msg)
{
Clients.All.PrintMessageRobot("Pong : " + DateTime.Now);
}
}
public static class UserHandler
{
public static List<string> Connections = new List<string>();
}
目前这两个应用程序似乎可以工作一段时间,直到一段时间后随机出现此错误:
Connection started reconnecting before invocation result was received.
此外,Web 中心还应调用 C# 控制台客户端上的任何其他方法,例如 GetGoals 方法。 'Ping Pong' 方法冻结,并在一段时间后抛出类似的异常。在此期间,Web 客户端继续完美运行,并且 Web 客户端可以与中心服务器来回通信。
任何人都可以提出问题所在吗? 编辑:进一步的调查使我相信它与线程有关,但是很难找到问题的根源。
调用调用有问题:
_hub.Invoke("MethodName", "Parameters").Wait();
这里我告诉它等待响应,但是我没有在网络服务器中编写任何响应机制。
此错误已通过切换到以下内容得到修复:
_hub.Invoke("MethodName", "Parameters");
现在它遵循 'fire and forget' 方法,现在不再出现错误。如果其他人收到此错误,请务必检查您是否需要回复。
如果发送到服务器端的数据是 'Non-serializable'(例如)不具有 [Serializable] 属性的业务对象列表
,您将收到相同的错误消息当有效载荷太大时,我遇到了同样的异常。我通过在 signlr.net 的启动声明中更改以下行来修复它。它删除了大小限制
GlobalHost.Configuration.MaxIncomingWebSocketMessageSize = null;