c# - SignalR:我无法从服务器调用 .net 客户端方法

标签 c# signalr

我想使用 .NET 客户端实现发布/订阅应用程序,因此我正在通过这个最少的代码测试 SignalR。

这是服务器:

namespace Test.SignalRComm.SimpleServer
{
    using System.Threading.Tasks;
    using log4net;
    using SignalR;
    using SignalR.Hosting.Self;
    using SignalR.Hubs;
    using SignalR.Infrastructure;

    class Program
    {
        private static SignalRServer signalRServer = null;

        static void Main(string[] args)
        {
            signalRServer = new SignalRServer();
            signalRServer.Start();

            System.Console.WriteLine("Press Enter to close...");
            System.Console.ReadLine();

            signalRServer.Stop();
        }
    }

    public class SignalRServer
    {
        private string serverUrl = null;
        public Server signalRServer = null;

        public SignalRServer()
        {
            serverUrl = @"http://localhost:5001/";
            signalRServer = new SignalR.Hosting.Self.Server(serverUrl);
            signalRServer.EnableHubs();
        }

        public void Start()
        {
            signalRServer.Start();
        }

        public void Stop()
        {
            IConnectionManager connManager = signalRServer.DependencyResolver.Resolve<IConnectionManager>();
            dynamic clients = connManager.GetClients<SignalRTestHub>();
            clients.AddMessage("Test");

            signalRServer.Stop();
        }
    }

    public class SignalRTestHub : Hub, IDisconnect
    {
        private static readonly ILog logger = LogManager.GetLogger(typeof(SignalRTestHub));

        public void Register(string token)
        {
            AddToGroup(token).ContinueWith(task =>
            {
                if (task.IsFaulted)
                    logger.Error(task.Exception.GetBaseException());
                else
                {
                    string message = string.Format("Client {0} registered with token <{1}>", Context.ConnectionId, token);
                    logger.Info(message);

                }
            });
        }

        public void Unregister(string token)
        {
            RemoveFromGroup(token).ContinueWith(task =>
            {
                if (task.IsFaulted)
                    logger.Error(task.Exception.GetBaseException());
                else
                    logger.InfoFormat("Client {0} unregistered from token <{1}>", Context.ConnectionId, token);
            });
        }

        public Task Disconnect()
        {
            string message = string.Format("Client {0} disconnected", Context.ConnectionId);
            logger.Info(message);

            return null;
        }
    }
}

这是客户端:

namespace Test.SignalRComm.SimpleClient
{
    using System.Threading.Tasks;
    using log4net;
    using SignalR.Client.Hubs;

    class Program
    {
        private static readonly ILog logger = LogManager.GetLogger(typeof(Program));

        static void Main(string[] args)
        {
            SignalRClient client = new SignalRClient("http://localhost:5001/");
            client.Start().ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    logger.Error("Failed to start!", task.Exception.GetBaseException());
                }
                else
                {
                    logger.InfoFormat("Success! Connected with client connection id {0}", client.ConnectionId);
                    // Do more stuff here
                    client.Invoke("Register", "Test").ContinueWith(tsk =>
                    {
                        if (tsk.IsFaulted)
                            logger.Error("Failed to start!", tsk.Exception.GetBaseException());
                        else
                            logger.Info("Success! Registered!");
                    });
                }
            });

            System.Console.WriteLine("Press Enter to close...");
            System.Console.ReadLine();

            client.Invoke("Unregister", "Test").ContinueWith(tsk =>
            {
                if (tsk.IsFaulted)
                    logger.Error("Failed to stop!", tsk.Exception.GetBaseException());
                else
                    logger.InfoFormat("Success! Unregistered!");
            });
            client.Stop();
        }
    }

    public class SignalRClient : HubConnection
    {
        private static readonly ILog logger = LogManager.GetLogger(typeof(SignalRClient));

        IHubProxy hub = null;

        public SignalRClient(string url)
            : base(url)
        {
            hub = CreateProxy("Test.SignalRComm.SimpleServer.SignalRTestHub");
        }

        public Task Invoke(string methodName, params object[] args)
        {
            return hub.Invoke(methodName, args);
        }

        public void AddMessage(string data)
        {
            logger.InfoFormat("Received {0}!", data);
        }
    }
}

虽然从客户端调用 hub 方法(RegisterUnregister)工作正常,但我无法从 hub 调用客户端 AddMessage 方法. 此外,当客户端关闭时,永远不会调用集线器的 Disconnect 方法。

我做错了什么?我找不到任何有效的例子。

编辑

像这样在客户端订阅 hubs 事件:

hub.On<string>("Notify", message => Console.Writeline("Server sent message {0}", message);

并像这样在集线器上触发事件:

Clients.Notify("Something to notify");

使从服务器到客户端的通知正常工作。

我仍然无法检测到客户端断开连接。我在 hub 上实现了 IDisconnect 接口(interface),但是当客户端连接停止时,不会触发 hub 上的 Disconnect 方法。

感谢您的帮助。

最佳答案

在此处了解如何使用 .NET 客户端:

https://gist.github.com/1324342

API 文档在这里:

https://github.com/SignalR/SignalR/wiki

TL;DR 您需要订阅特定方法,从 hubConnection 派生不会产生任何魔法。

关于c# - SignalR:我无法从服务器调用 .net 客户端方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10088919/

相关文章:

c# - 强制转换以从所选中获取 ID 不起作用

c# - 如何处理空的 linq 查询

c# - ASP.NET SignalR - 空闲时消耗的带宽

c# - 如何在长时间的服务器进程中显示信息丰富的实时进度数据

c# - WPF 与 Datacontext 绑定(bind)

c# - 如何在 C# 或 C++ 中使用条件语句检查/比较四个变量是否相同或不同

c# - 如何从其 View 模型访问自定义控件依赖项属性

asp.net-core - 如何向用户发送 SignalR 消息?

c# - 启动/停止 OWIN 中间件?

amazon-web-services - 什么是AWS完美替代Azure SignalR服务?