【问题标题】:Can a SignalR Hub receive events from clients? And if so, how?SignalR Hub 可以接收来自客户端的事件吗?如果是这样,怎么办?
【发布时间】:2019-05-24 12:25:28
【问题描述】:

我有一个 signalR 集线器,它需要能够从客户端接收事件,然后通知连接到集线器的所有其他客户端。

这可能吗?

我希望我的“集线器”应用程序能够接收和发送消息。我只能弄清楚如何发送消息。这是我现在拥有的:

应用程序 1-- 集线器

启动类:

  public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.AddSignalR().AddHubOptions<EventsHub>(options =>
            {
                options.HandshakeTimeout = TimeSpan.FromMinutes(5);
                options.EnableDetailedErrors = true;
            });
            services.AddTransient(typeof(BusinessLogic.EventsBusinessLogic));          
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

            app.UseSignalR((configure) =>
            {
                configure.MapHub<EventsHub>("/hubs/events", (options) =>
                {
                });
            });          
        }

在应用程序 1 中设置集线器

 public class EventsHub : Hub
    {
        public EventsHub()
        {
        }

        public override Task OnConnectedAsync()
        {
            if (UserHandler.ConnectedIds.Count == 0)
            {
                //Do something on connect
            }
            UserHandler.ConnectedIds.Add(Context.ConnectionId);
            Console.WriteLine("Connection:");
            return base.OnConnectedAsync();
        }

        public override async Task OnDisconnectedAsync(Exception exception)
        {
          //Do something on Disconnect

        }


        public static class UserHandler
        {
            public static HashSet<string> ConnectedIds = new HashSet<string>();
        }
    }

业务逻辑:


    public class EventsBusinessLogic
    {
        private readonly IHubContext<EventsHub> _eventsHub;

        public EventsBusinessLogic(IHubContext<EventsHub> eventsHub)
        {
            _eventsHub = eventsHub;                       
        }

        public async Task<Task> EventReceivedNotification(ProjectMoonEventLog eventInformation)
        {
            try
            {             
                 await _eventsHub.Clients.All.SendAsync("NewEvent", SomeObject);        
            }
            catch (Exception e)
            {

                throw new Exception(e.Message);
            }
        }
    }


在第二个应用程序中,它侦听来自集线器的事件或消息:

启动.cs

  private static void ConfigureAppServices(IServiceCollection services, string Orale, string Sql)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddOptions();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            //set up of singletons and transients

            services.AddHostedService<Events.EventingHubClient>();
        }

连接到应用程序 1 的 ClientHub:

public class EventingHubClient : IHostedService
    {
        private HubConnection _connection;

        public EventingHubClient()
        {

            _connection = new HubConnectionBuilder()
                .WithUrl("http://localhost:61520/hubs/events")
                .Build();


            _connection.On<Event>("NewEvent",
    data => _ = EventReceivedNotification(data));

        }

        public async Task<Task> EventReceivedNotification(Event eventInformation)
        {
            try
            {


              //Do something when the event happens     

                return Task.CompletedTask;
            }
            catch (Exception e)
            {

                throw new Exception(e.Message);
            }

        }


        public async Task StartAsync(CancellationToken cancellationToken)
        {
            // Loop is here to wait until the server is running
            while (true)
            {
                try
                {
                    await _connection.StartAsync(cancellationToken);
                    Console.WriteLine("Connected");
                    break;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    await Task.Delay(100);
                }
            }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return _connection.DisposeAsync();
        }

    }

这可行,但现在我希望应用程序 2 能够向应用程序 1 发送消息?所以我需要一段与 application2 中的 EventsBusinessLogic 类类似的代码来向应用程序 1 发送消息。

我希望这已经足够清楚了吗?这是 SignalR 的目的吗?

【问题讨论】:

    标签: asp.net-core signalr signalr-hub


    【解决方案1】:

    请参考signalR文档signalR documentation for .net client

    我猜你的 Hub 方法是这样的

    public async Task SendTransaction(Transaction data)
    {
        await Clients.All.SendAsync("TransactionReceived", data);
    }
    

    然后在客户端添加方法

    在构造函数中添加

     connection.On<Transaction>("TransactionReceived", (data) =>
        {
            this.Dispatcher.Invoke(() =>
            {
               var transactionData = data;
            });
            });
    

    然后SendTransaction 预计在服务器上

    private async void SendTransaction(Transaction data)
    {
        try
        {
            await connection.InvokeAsync("SendTransaction", data);
        }
        catch (Exception ex)
        {                
            // 
            throw
        }
    }
    

    【讨论】:

    • 假设 HUB 关心在服务器上创建“新帐户”时。我们如何在集线器上获得该事件?我是否引用到它自己的集线器的连接?
    • 您是指服务器(集线器)端“新帐户”还是客户端(客户端集线器)“新帐户”?无论如何,请在您的问题中更新它 - 您使用了什么以及问题是什么。
    • 问题更新了,请看一下是否更有意义?感谢您的帮助
    • 请查看 SignalR 文档。客户端有connection.InvokeAsync方法需要使用。
    • 你没有抓住重点。我将使用connection.InvokeAsync,但 HUB 是如何处理的呢?我希望集线器在调用 connection.InvokeAsync 时做一些事情。就像在客户端中,您可以在 connection.on&lt;&gt;.... 上调用方法
    猜你喜欢
    • 2011-03-23
    • 2011-02-16
    • 2019-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    相关资源
    最近更新 更多