C#SignalR异常-在收到调用结果之前,连接开始重新连接 [英] C# SignalR Exception - Connection started reconnecting before invocation result was received

查看:361
本文介绍了C#SignalR异常-在收到调用结果之前,连接开始重新连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发2个应用程序,第一个是C#控制台应用程序,另一个是Asp.net Web应用程序.我正在使用SignalR来连接两者.

I am developing 2 applications, the first being a C# console application and the other an Asp.net web application. I am using SignalR to connect the two.

这是我的C#控制台应用程序(客户端)

This is my C# console application (Client)

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类的实例.依次启动与SignalR集线器的连接,并在单独的线程上启动MonitorHubStatus方法,我实现了该方法,以检查C#控制台应用程序客户端是否仍在主动连接至集线器.

When the console application runs, it creates an instance of the RoboHub class. Which in turn starts a connection to the SignalR hub and on a separate thread starts the method MonitorHubStatus which is something I implemented to check if the C# console application client is still actively connected to the hub.

这是我的Web集线器(在Asp.net Web应用程序内)

This is my Web hub (within the Asp.net Web application)

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

当前,这两个应用程序似乎可以工作一段时间,直到一段时间后此错误随机出现:

Currently the 2 applications seem to work for a time, until after a while this error randomly appears:

在收到调用结果之前,连接开始重新连接.

Connection started reconnecting before invocation result was received.

Web集线器还应该在C#控制台客户端上调用其他任何方法,例如GetGoals方法.乒乓"方法会冻结,并且在一段时间后会引发类似的异常.在整个过程中,Web客户端继续正常运行,并且Web客户端可以与集线器服务器来回通信.

Further more should the web hub call any other method on the C# console client such as the GetGoals method. The 'Ping Pong' method freezes and after time a similar exception is thrown. throughout this the web client continues to function perfectly and the web client can communicate back and forth with the hub server.

有人可以建议这个问题是什么吗?进一步的调查使我相信这与线程有关,但是很难找到问题的根源.

Can anyone suggest what the issue could be? Further investigation leads me to believe it to be something to do with threading, however it is difficult to find the source of the issues.

推荐答案

问题在于调用调用:

_hub.Invoke("MethodName", "Parameters").Wait();

在这里,我告诉它等待响应,但是我没有在Web服务器中编写任何答复机制.

Here I am telling it to wait for a response however I did not program any reply mechanism in the web server.

此错误已解决,方法是切换到:

This error was fix by switching to:

_hub.Invoke("MethodName", "Parameters");

现在,它遵循一种即发即弃"的方法,现在不再出现错误.如果其他人遇到此错误,请务必检查您是否需要回复.

Now it follows a 'fire and forget' methodology and it now no longer gets the error. Should anyone else get this error be sure to check whether you need a response or not.

这篇关于C#SignalR异常-在收到调用结果之前,连接开始重新连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆