SignalR – Trocando mensagens e notificações entre Server/Client de forma global e individual

Standard

No post anterior sobre o SignalR, fiz uma introdução rápida sobre a biblioteca, onde conseguimos observar que realmente é muito fácil a utilização da lib, além de demonstrar como podemos realizar a troca de mensagens/notificações entre server/client em tempo real.
Neste artigo, vou demonstrar como podemos requisitar uma função em server-side, e após o término, notificar todos os usuários conectados (client-side), ou apenas algum(ns) usuário(s) específico(s).

Para todos os exemplos, estou considerando que a importação dos scripts e referências para o SignalR já tenham sido realizadas (No artigo anterior eu demonstro como definir as referências e scripts para o SignalR funcionar corretamente).

Notificação Global

Veja como é simples o envio de notificações em tempo real para todos os usuários conectados, primeiramente vamos criar nossa conexão no script do cliente (client-side):

<script language="javascript" type="text/javascript">

    $(function () {

	// Cria objeto de conexão
	var nomeHubClient = $.connection.nomeHub;

        // Função que envia mensagem para o servidor
        $("#btnEnviaMsg").click(function () {

	    var mensagem = $('#mensagem').val();
            nomeHubClient.enviaMensagem(mensagem);
            $('#mensagem').val("");

        });

        // Inicia a conexão
        $.connection.hub.start(function () {
            // Envia para o servidor o usuário que está criando a conexão
	    // O campo #nomeUsuario é apenas um campo presente na nossa página aspx que identifica o nome do usuário em questão (Não é obrigatório)
	    nomeHubClient.join($('#nomeUsuario').val(""));
        });

        // Função chamada em real-time pelo servidor
        nomeHubClient.novaMensagem = function (mensagem) {
            mensagem = $("#mensagens").html() + "<br />" + mensagem;
            $("#mensagens").html(mensagem);
        };
    });

</script>


Em seguida vamos criar nossa classe de conexão (Hub) no servidor:

[HubName("nomeHub")]
public class NomeHub : Hub
{

	public void Join(string nomeUsuario)
	{
		EnviaMensagem(string.format("usuário {0} logado.", nomeUsuario));
	}

	public void EnviaMensagem(string mensagem)
	{
		Clients.novaMensagem(mensagem);
	}
}

Podemos ver que ao inciar a conexão, o método Join será chamado automaticamente, posteriormente, a propriedade Clients dispara para todas os clientes conectados (todas conexões abertas) a mensagem recebida.

 

Notificação Individual

Vamos ver agora como podemos fazer para enviar uma notificação apenas para um usuário específico. Para tanto temos a propriedade $.connection.hub.id, esta propriedade gera automaticamente uma especie de guid para nossa conexão, podendo assim via server-side, saber para qual conexão enviar a notificação.
Desta forma, ficamos com o seguinte bloco de código:

<script language="javascript" type="text/javascript">

    $(function () {

	// Cria objeto de conexão
	var nomeHubClient = $.connection.nomeHub;

        // Função que envia mensagem para o servidor
        $("#btnEnviaMsg").click(function () {

	    var mensagem = $('#mensagem').val();
            nomeHubClient.enviaMensagem(mensagem);
            $('#mensagem').val("");

        });

        // Inicia a conexão
        $.connection.hub.start(function () {
	    // Obtém o ID da conexão criada
            var conexaoId = $.connection.hub.id;		

            // Envia para o servidor o nome do usuário que está criando a conexão e o ID da conexão criada
	    // O campo #nomeUsuario é apenas um campo presente na nossa página aspx que identifica o nome do usuário em questão (Não é obrigatório)
	    nomeHubClient.join($('#nomeUsuario').val(""), conexaoId);
        });

        // Função chamada em real-time pelo servidor
        nomeHubClient.novaMensagem = function (mensagem) {
            mensagem = $("#mensagens").html() + "<br />" + mensagem;
            $("#mensagens").html(mensagem);
        };
    });

</script>

Agora basta modificarmos nossa classe Hub no servidor, para que faça uso do ID da conexão enviada como parâmetro:

[HubName("nomeHub")]
public class NomeHub : Hub
{
	public void Join(string nomeUsuario, string conexaoId)
	{
		EnviaMensagem(string.format("usuário {0} logado.", nomeUsuario), conexaoId);
	}

	public void EnviaMensagem(string mensagem, string conexaoId)
	{
		Clients[conexaoId].novaMensagem(mensagem);
	}
}

Bem fácil e simples não? ao especificar o id da conexão na propriedade Clients, apenas a conexão informada receberá a notificação com a mensagem. Neste exemplo, enviamos a notificação para o próprio usuário que realizou a ação, porém, da mesma forma que obtemos o ID da conexão do próprio usuário, podemos utilizar um ID de outra conexão (para tanto, teríamos que implementar alguma estrutura para listar as conexões abertas, para que assim, seja possível o usuário selecionar a quem deseja notificar).
Uma outra forma de notificarmos apenas o usuário que realizou a ação, é utilizando a propriedade Caller, veja:

public void Join(string nomeUsuario, string conexaoId)
{
	EnviaMensagem(string.format("usuário {0} logado.", nomeUsuario), conexaoId);
}

public void EnviaMensagem(string mensagem, string conexaoId)
{
	// Notifica apenas o usuário que possui o ID da conexão
	Clients[conexaoId].novaMensagem(mensagem);         

	// Notifica apenas o usuário que realizou a chamada ao método Join
	Caller.novaMensagem(mensagem);
}

Bom pessoal, por hoje era isso. Espero que tenham gostado, em breve mais artigos sobre SignalR. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *