Может ли SignalR Hub получать события от клиентов? И если да, то как? - PullRequest
0 голосов
/ 24 мая 2019

У меня есть концентратор 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>();
        }
    }

BusinessLogic:


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


Во втором приложении, которое прослушивает события или сообщения от концентратора:

Startup.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>();
        }

ClientHub дляподключиться к приложению 1:

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?Поэтому для отправки сообщений в приложение 1 мне нужен такой же фрагмент кода, что и в классе EventsBusinessLogic в application2.

Надеюсь, это достаточно ясно?Это цель SignalR?

1 Ответ

0 голосов
/ 24 мая 2019

См. Документацию signalR документацию signalR для клиента .net

Я полагаю, в вашем методе 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
    }
}
...