【问题标题】:SignalR: I cannot call .net client method from serverSignalR:我无法从服务器调用 .net 客户端方法
【发布时间】:2012-04-10 12:35:29
【问题描述】:

我想用 .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);
        }
    }
}

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

我做错了什么?我找不到任何工作示例。

编辑

像这样在客户端订阅集线器事件:

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

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

Clients.Notify("Something to notify");

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

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

感谢您的帮助。

【问题讨论】:

    标签: c# signalr


    【解决方案1】:

    在这里看看如何使用 .NET 客户端:

    https://gist.github.com/1324342

    这里还有 API 文档:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 2015-10-26
      • 1970-01-01
      相关资源
      最近更新 更多