Fala galera!
Conforme prometi no primeiro post da série vamos implementar um pequeno exemplo utilizando os Hubs do ASP.NET SignalR para fixar melhor os conceitos.
Recapitulando os Hubs abstraem toda a camada de comunicação entre o servidor e os clientes permitindo de forma facilitada a implementação de cenários de comunicação em tempo real como:
- Notificação dos clientes quando da ocorrencia de eventos no servidor tais como conclusão de processos de longa duração, alteração de status em fluxos de trabalho, etc;
- Comunicação entre aplicações, inclusive em diferentes plataformas, tais como jogos, chats, etc;
Durante este artigo iremos construir um pequeno mural de recados que permitiráque os usuários publiquem mensagens que atualizarão o painel em todos os clientes conectados naquele momento.
Criando nosso mural
A Solution será composta de dois projetos:
- Mural.Server: aplicação console responsável por hospedar nosso servidor SignalR. Poderia ser uma aplicação Web mas escolhi este modelo apenas para efeito de demonstração da versatilidade deste tipo de solução;
- Mural.WEb: é uma WEb Application vazia apenas pra hospedar nossa página HTML e seus scripts. Poderia ser qualquer tipo de aplicação mas também escolhi este modelo pela sua simplicidade;
Então para começar crie uma Blank Solution, adicione os dois projetos e vamos começar a implementa-los.
Mural.Server
Nossa aplicação console precise de apenas um pacote Nuget:
- ASP.NET SignalR Self Host;
Este pacote instalará todo o core do SignalR e se utilizará do OWIN para hospedar uma aplicação Web no endereço: http://localhost:8080.
O SignalR trabalha com um mapeamento padrão em /signalr e disponibiliza o proxy para os hubs, em JavaScript no endpoint /signalr/hubs. Veremos isto em detalhes quando estivermos construindo nosso cliente.
Para que possamos configurar o servidor precisamos adicionar uma nova classe chamada Startup que deve ter a seguinte implementação:
public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); } }
Com isto o SignalR irá se configurar automaticamente. Agora precisamos subir nosso servidor quando a aplicação for inicializada. Altere o método Main da classe Program para:
class Program { static void Main(string[] args) { using (WebApp.Start("http://localhost:8080/")) { Console.WriteLine("Server running at http://localhost:8080/"); Console.ReadLine(); } } }
E para finalizar o projeto de nosso servidor precisamos apenas criar o Hub. Isto é feito através da implementação de uma classe que herda de Hub e todos os seus métodos publicos estão disponíveis para serem chamados pelo cliente.
Já para acionarmos os clientes utilizamos a propriedade Clients e suas propriedades All para todos os clientes conectados, Caller para o chamador atual e Group para enviar para um grupo específico. Em um exemplo mais avançado abordaremos estes conceitos.
Dica: utilize a versão d Hub que recebe uma interface. Isto evitará erros de digitação muito comuns quando utilizamos objetos dynamic.
Logo nossa interface e Hub ficarão desse modo:
public interface IMuralHubClient { void OnMensagemRecebida(string mensagem); }
public class MuralHub: Hub { public void Publicar(string mensagem) { Console.WriteLine("Cliente {0} enviou {1} ...", Context.ConnectionId, mensagem); Clients.All.OnMensagemRecebida(mensagem); } public override Task OnConnected() { Console.WriteLine("Cliente {0} estabeleceu conexão ...", Context.ConnectionId); return base.OnConnected(); } public override Task OnDisconnected(bool stopCalled) { Console.WriteLine("Cliente {0} desconectado ...", Context.ConnectionId); return base.OnDisconnected(stopCalled); } }
Voilá! Nosso servidor está pronto para ser utilizado. Caso voce queira ter certeza disto inicie o debug e aponte seu navegador para http://localhost:8080/signalr/hubs e veja que será retornado um JavaScript contendo toda implementaçÃo do cliente para nosso hub.
Mural.Web
Agora vamos criar nosso cliente. Adicione os seguintes pacotes Nuget:
- Bootstrap;
- ASP.NET SignalR.js;
O Bootstrap srá utilizado para dar uma ar mais profissional a interface do nosso mural, já o SignalR.js é o cliente do SignalR. Ele adicionará automaticamente o jQuery biblioteca necessária tanto pelo Bootstrap quando pelo SignalR.js.
Crie um novo arquivo chamado Index.html com o seguinte conteúdo:
Mural de Recados <div class="container"> <div class="panel panel-default col-md-8 col-sm-12"> <div class="panel-heading">Mural de Recados</div> <div class="panel-body"> <ul class="media-list" id="mural"> </ul> </div> </div> <div class="panel panel-default col-md-4 col-sm-12"> <div class="panel-heading">Publicar Mensagem</div> <div class="panel-body"> <div class="form-group"> Mensagem <div class="form-group"> </div> </div> <div class="form-group"> Publicar </div> </div> </div> </div>
E codificaremos a interação com nosso hub no arquivo mural.js da seguinte forma:
(function($) { $.connection.hub.url = 'http://localhost:8080/signalr'; var hub = $.connection.muralHub; hub.client.OnMensagemRecebida = function(mensagem) { var li = $("<li>"); li.addClass("media") var body = $("<div>") body.addClass("media-body"); body.text(mensagem); li.append(body); $("#mural").append(li); } $(function() { $("#publicar").click(function() { hub.server.publicar($("#mensagem").val()); $("#mensagem").val(''); $("#mensagem").focus(); }); $.connection.hub.start().done(function() { $("#mensagem").focus(); }); }); })(jQuery);
Observemos que no bloco JavaScript realizamos as seguintes etapas:
- Definimos a url do servidor SignalR;
- Criamos uma referencia para o nosso Hub;
- Definimos uma unção anonima que será chamada quando o servidor chamar o método OnMensagemRecebida do cliente;
- Fazemos chamadas ao método Publicar do servidor;
- Inicializamos a conexÃo com o servidor;
O código é bem simples e auto explicativo mas caso tenha alguma duvida terei prazer em responde-las nos comentários.
Por enquanto é isto. Veremos se em postagens superiores criamos coisas mais avançadas e divertidas.
Até a próxima!