4

我想用 .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当客户端关闭时,永远不会调用集线器的方法。

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

编辑

在客户端订阅 hubs 事件,如下所示:

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

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

Clients.Notify("Something to notify");

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

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

谢谢你的帮助。

4

1 回答 1

2

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

https://gist.github.com/1324342

和这里的 API 文档:

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

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

于 2012-04-10T15:37:30.450 回答