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

我想用.NET客户端实现一个pub / sub应用程序,所以我通过这个最小的代码测试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);
        }
    }
}

从客户端(注册和取消注册)调用集线器方法工作正常,我无法从集线器调用客户端AddMessage方法.
此外,当客户端关闭时,永远不会调用集线器的Disconnect方法.

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

编辑

订阅客户端上的集线器事件,如下所示:

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

并在集线器上触发事件,如下所示:

Clients.Notify("Something to notify");

使从服务器到客户端的通知工作.

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

谢谢你的帮助.

最佳答案 在这里看一下如何使用.NET客户端:

https://gist.github.com/1324342

和API文档在这里:

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

TL; DR你需要订阅特定的方法,从hubConnection派生不会发生任何魔术.

点赞