简体   繁体   English

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

[英]SignalR: I cannot call .net client method from server

I would like to implement a pub/sub application with .NET clients, so I'm testing SignalR by means of this minimal code.我想用 .NET 个客户端实现一个发布/订阅应用程序,所以我正在通过这个最小代码测试 SignalR。

This is the server:这是服务器:

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

and this is the client:这是客户:

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

While invoking hub methods from client ( Register and Unregister ) works fine, I'm not able to call client AddMessage method from hub.虽然从客户端( RegisterUnregister )调用集线器方法工作正常,但我无法从集线器调用客户端AddMessage方法。 Furthermore the Disconnect method of the hub is never called when a client is closed.此外,当客户端关闭时,永远不会调用 hub 的Disconnect方法。

What I'm doing wrong?我做错了什么? I'm not able to find any working example.我找不到任何有效的例子。

Edit编辑

Subscribing to hubs events on the client like this:像这样订阅客户端上的集线器事件:

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

and triggering the event on the hub like this:并像这样在集线器上触发事件:

Clients.Notify("Something to notify");

makes the notifications from server to clients working.使从服务器到客户端的通知正常工作。

I'm still unable to detect a client disconnection.我仍然无法检测到客户端断开连接。 I implemented the IDisconnect interface on the hub, but when a client connection stops, the Disconnect method on the hub isn't triggered.我在集线器上实现了IDisconnect接口,但是当客户端连接停止时,不会触发集线器上的Disconnect方法。

Thanks for your help.谢谢你的帮助。

Take a look at how to use the .NET client here:在这里看看如何使用 .NET 客户端:

https://gist.github.com/1324342 https://gist.github.com/1324342

And API docs here: API 文档在这里:

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

TL;DR you need to subscribe to specific methods, deriving from the hubConnection doesn't make any magic happen. TL;DR 您需要订阅特定方法,从 hubConnection 派生不会产生任何魔法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 是否可以从javascript客户端同步调用Signalr服务器端方法? - Is it possible to synchronously call Signalr server side method from javascript client? 从 SignalR 服务器(Asp.Net Core)调用特定客户端 - Call specific client from SignalR server (Asp.Net Core) signalR调用服务器方法,该方法调用集线器外部的回调方法。 如何从该方法调用客户端功能? - signalR calls a server method and that method calls a callback method ,outside the hub. How can I call client function from that method? SignalR - 如何从服务器上调用服务器上的Hub方法 - SignalR - How can I call Hub Method on server from server 客户端.net SignalR中调用服务器方法 - calling server method in client .net SignalR 非MVC项目中来自客户端的SignalR服务器端方法调用 - SignalR Server side method call from Client side in Non MVC project SignalR IOS Client,Web Socket传输无法从服务器调用该方法 - SignalR IOS Client, Web Socket transport cannot invoke the method from server 无法将在端口上运行的 SignalR 客户端连接到 .NET Core 2.2 服务器 - Cannot connect SignalR client running on a port to a .NET Core 2.2 server SignalR服务器 - >客户端呼叫无法正常工作 - SignalR server --> client call not working 如何从客户端调用signalR服务器方法中的授权方法? - How to invoke authorize method in signalR server method from client?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM