Grupo de Usuários em SignalR
Olá pessoal, neste segundo post sobre SignalR vamos falar sobre como enviar mensagens ao chamador (caller) e como destinar mensagem somente a um grupo de usuários.
Para quem não viu o primeiro post sobre SignalR, ele é uma biblioteca Async para .NET para ajudar a criar aplicativos web interativos em tempo real e multiusuário.
Para começar vamos utilizar o exemplo do post anterior, onde fizemos um chat simples utilizando o SignalR, neste post vamos adicionar uma opção para o usuário escolher um grupo, e as mensagens serão enviadas somente a este grupo, e ele recebera somente mensagens do grupo ao qual ele pertence.
Com o projeto aberto, vamos alterar a class Hub do nosso projeto, no caso Chat.cs e deixa-la como mostro no código a seguir:
public class Chat : Hub { //Deve ter um metodo EnviarMensagem no JavaScript public void EnviarMensagem(string mensagem, string grupo) { mensagem = "<em>" + DateTime.Now.ToString("HH:mm:ss") + "h [" + grupo + "]</em> " + mensagem; //Chama um metodo implementado no cliente via JavaScritp Clients[grupo].adicionarMensagem(mensagem); } public void AdicionaGrupo(string grupo) { //(caller)Manda uma chamada de método somente para quem requisitou o //adicionarGrupo Caller.adicionarMensagem("Entrou no grupo: " + grupo); Groups.Add(Context.ConnectionId, grupo); } public void RemoveGrupo(string grupo) { Caller.adicionarMensagem("Saiu do grupo:" + grupo); Groups.Remove(Context.ConnectionId, grupo); } }
Como você pode perceber, adicionamos dois novos métodos AdicionaGrupo e RemoveGrupo, no primeiro método AdicionaGrupo recebemos uma string grupo como parâmetro, que vai representar o nome do nosso grupo, este método é bem simples, usamos o objeto Caller para invocar o método adicionarMensagem do nosso JavaScript, porem ele irá invocar o adicionarMensagem somente do usuário que fez a requisição, ao contrário do objeto Clients que dispara a mensagem para todos os usuários que estão assinando nosso Hub, já a segunda linha do nosso método criamos um Grupo no nosso Hub, invocando o método Add do Groups, para isso devemos passar o ID da conexão do usuário (Context.ConnectionId) e o nome do grupo que queremos adiciona-lo.
Já no segundo método, RemoverGrupo, fazemos justamente o contrário do primeiro que é remover o usuário do grupo passado como parâmetro.
Reparem também que trocamos o código do nosso primeiro método da class Chat.cs, adicionamos o [grupo] na frente do Clients, para que o SignalR possa enviar as mensagens a todos que pertencem a determinado grupo, caso não adicionemos o grupo na frente do Clients, o SignalR ira enviar a mensagem a todos que estiverem assinando nosso Hub.
Agora que implementamos a nossa classe Hub, vamos para a implementação da parte em JavaScritp, neste nosso exemplo ele fica dentro do arquivo Index.cshtml
<script type="text/javascript"> $(function () { // Cria um proxy da nossa classe Chat do Servidor var chat = $.connection.chat; var grupoAtual = 'todos'; chat.adicionarMensagem = function (message) { $('#mensagens').append('<li>' + message + '</li>'); }; $("#btnEnviar").click(function () { // Chama o metodo da classe Chat do servidor chat.enviarMensagem($('#msg').val(), $('#grupo').val()); }); $('#grupo').change(function () { chat.removeGrupo(grupoAtual); grupoAtual = $('#grupo').val(); chat.adicionaGrupo(grupoAtual); }); // Inicia a conexão $.connection.hub.start(function () { chat.adicionaGrupo(grupoAtual); }); }); </script>
Começamos adicionando no inicio do arquivo o grupoAtual do usuário, para que ele já comece com um grupo selecionado. Foi adicionado o evento change ao Select #grupo, para que ele chame o método removeGrupo do nosso Hub, passando o grupoAtual, e logo após isso ele adicione o novo grupo do usuário, chamando o adicionaGrupo, passando como parâmetro o valor selecionado no Select #grupo.
Para concluir vamos adicionar o HTML neste mesmo arquivo (index.cshtml), para que ele exiba algumas opções de grupo.
<label> grupo: <select id="grupo" > <option value="todos">Todos</option> <option value="adm">Administradores</option> <option value="usuario">Usuarios</option> </select> </label>
Com isso acabamos nossa implementação, que é bem simples por sinal, mas já demonstra o poder do SignalR em gerenciar os grupos e o chamador, para que você possa testar, abra três instancias do browser, escolha um grupo para o primeiro, e para as outras duas instâncias escolha o mesmo grupo, e escreva uma mensagem em cada uma delas, você vera uma tela semelhante a mostrada na imagem inicial deste post.
Você pode baixar o exemplo do primeiro post e deste post acessando o meu GitHub.
Bom era isso pessoal e sucesso a todos!