Olá tudo bem?! Recentemente, em um dos projetos que estou atuando, surgiu a necessidade de notificar o usuário do sistema sobre a conclusão da execução de um processo, que é iniciada após uma determinada ação do usuário.
Neste meu cenário, eu não quero bloquear a transação e fazer meu usuário esperar até que o processo seja concluído. É importante o usuário saber a conclusão do processo, mas não quero impedi-lo de navegar no sistema. Para tal, decidimos utilizar o signalR como um webHook para notificar o usuário, independentemente de onde ele estiver no sistema.
Configurando o signalR
Basta adicionar o serviço do signalR no startup.cs da aplicação.
1 2 3 4 5 6 7 8 9 10 | public class Startup { //... public void ConfigureServices(IServiceCollection services) { services.AddMvc(); //adicionar o serviço do signalR após o de MVC. services.AddSignalR(); } } |
Agora defino a rota que o signalR utilizará para receber as notificações:
1 2 3 4 5 6 7 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) { //... app.UseSignalR(router => router.MapHub( "/notificacao" )); app.UseMvc(); } |
Para esse cenário, a classe Notificacao.cs será somente uma implementação para o Hub.cs do signalR.
1 2 3 4 5 | using Microsoft.AspNetCore.SignalR; public class Notificacao:Hub { } |
Enviando uma notificação
1 2 3 4 5 6 7 8 9 10 11 | public class ServicoDePublicacao{ private readonly IHubContext<Notificacao> _canalDeNotificacao; public ServicoDePublicacao(IHubContext<Notificacao> canalDeNotificacao) => _canalDeNotificacao = canalDeNotificacao; public async Task Publicar(){ await _canalDeNotificacao.Clients.All.SendAsync( "NotificaPublicacao" , "Publicação com sucesso" ); } } |
Como podemos ver no código acima, para emitir uma notificação, basta eu obter uma referencia da minha conexão criada, utilizando a classe IHubContext, e enviar a mensagem desejada através dela.
No método Publicar estou basicamente enviando a mensagem para todos os clientes que estão assinando o “NotificaPublicacao”.
A primeira parte está feita. Agora vamos para o front-end e ver como obtemos essas notificações.
Configurando o angular
Primeiramente, baixe o pacote @aspnet/signalr na sua aplicação angular.
Criei um serviço na minha aplicação angular para me conectar com a rota do signalr definida no back-end. Segue código abaixo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import { Injectable, EventEmitter, Output } from '@angular/core' ; import { HubConnection, HubConnectionBuilder } from '@aspnet/signalr' ; @Injectable() export class SignalRService { @Output() notificationReceived: EventEmitter; = new EventEmitter(); @Output() connectionEstablished: EventEmitter = new EventEmitter(); private _hubConnection: HubConnection; constructor() { this .createConnection(); this .registerOnServerEvents(); this .startConnection(); } private createConnection() { this ._hubConnection = new HubConnectionBuilder() .withUrl( this .baseUrl) .build(); } private registerOnServerEvents() { this ._hubConnection .on( 'NotificaPublicacao' , (data) => {console.log(data); this .notificationReceived.emit(data);}); } private startConnection(): void { this ._hubConnection .start() .then(() => { console.log( 'Hub de conexão iniciado' ); this .connectionEstablished.emit( true ); }). catch (err => { console.log( 'Erro ao realizar conexão do signalR, tentando novamente' ); setTimeout( this .startConnection(), 5000); }); } } |
No serviço acima, estou basicamente criando uma conexão com o meu Hub de notificação, que foi criado no startup da minha Api, estou registrando as notificações que quero ouvir, que neste caso é a “NotificaPublicacao” e, por fim, me conecto ao Hub. Pronto. Agora em qualquer lugar que utilizar esse serviço, basta me inscrever no evento notificationReceived que, quando o signalr disparar alguma mensagem, meu front-end será notificado. Exemplo:
1 2 | this .signalRService.notificationReceived.subscribe((notificacao) => console.log(notificacao)) |
Bem, é isso. Espero que tenham gostado e que seja util!
Obrigado!
(Cross-post de https://gustavofontes.net/2018/08/29/notificacao-de-processos-com-signalr-no-asp-net-core-angular/)
Gustavo Fontes