Skip to content

ASP.NET SignalR continuação introdução

Dando continuidade sobre o primeiro artigo escrito sobre SignalR que foi demonstrado uma pequena introdução, irei falar mais sobre ele e seu funcionamento de mensagens individual (entre dois usuários) e entre todos os usuários conectados com o servidor.

Como exemplo vamos ver um aplicativo de jogo da velha. Neste aplicativo o usuário deverá informar seu nome e com isso será exibido as salas para jogos. Cada sala só pode receber dois jogadores e essas informações de cada sala são vistas quando o usuário acessa o aplicativo. A ideia de utilizar SignalR é que cada jogada deverá ser enviada para o adversário em tempo real e as informações da sala (quais jogadores, quem está ganhando, se a sala está aberta) deve ser enviada para todos que estiverem no sistema. Eu acho esse aplicativo mais difícil do que um bate papo e por isso resolvi traze-lo aqui para demonstração com SignalR.

O aplicativo construído está no Github e de início vou explicar um pouco dos principais objetos construídos:

  • A classe TicTacToeHub do projeto WEB é a classe do SignalR responsável pelo gerenciamento dos trafego de mensagens.
  • A classe TicTacToeService do projeto MODEL é a classe responsável pelos serviços da aplicação. Nela existem métodos para criar as salas a primeira vez que o sistema é iniciado, gravar as jogadas e verificar se existe ganhador.
  • O JS jquery.tictactoe-0.0.1 que se encontra na pasta scripts do projeto WEB é responsável pela comunicação do browser com o servidor. Nele existe métodos de escutas e acesso com o servidor.

Depois das devidas explicações para entendimento da aplicação, vamos agora olhar mais a fundo o funcionamento do jogo da velha.

Como nesta aplicação não utilizamos nenhum modo de armazenamento persistente, a classe do SignalR é responsável por obter uma instancia global do objeto TicTacToeService e assim todas as informações ficam na memória do servidor e vistas por todos os usuários da aplicação.

[sourcecode language=”csharp”]

private TicTacToeService _service;

public TicTacToeHub()
{
_service = TicTacToeService.GetInstance();
}

[/sourcecode]

Quando usuário acessa o sistema e informa seu nome o aplicativo inicia a função java script abaixo

[sourcecode language=”javascript”]

function StartConnectionHub() {

proxy = $.connection.ticTacToeHub;

proxy.state.PlayerName = $(‘#Name’).val();

proxy.client.changeRoom = function (result) {

CreateRooms(result);

};

proxy.client.startGame = function (player) {

startGame(player);

};

proxy.client.prepareMove = function (player) {

prepareMove(player);

};

proxy.client.cellMarker = function (cel, symbol) {

cellMarker(cel, symbol);

};

proxy.client.playerWinner = function (player) {

playerWinner(player);

};

proxy.client.finishedGame = function () {

finishedGame();

};

proxy.client.opponentGiveUp = function () {

opponentGiveUp();

};

$.connection.hub.start().done(

function () {

GetListRooms();

});

}

[/sourcecode]

Como já visto no primeiro artigo, temos que criar um objeto de instancia da classe SignalR, neste caso estamos falando da classe TicTacToeHub. Após isso, a função StartConnectionHub prepara as funções de escuta com o servidor. Um exemplo disso é a função de escuta chamada ChangeRoom que é chamada pelo servidor a todos os seus clientes quando a sala do jogo é alterada, seja pelos participantes ou pela vitória de algum participante. Cada função de escuta deve ser chamada antes da instrução de início de conexão ($.connection.hub.start()) com o SignalR.

Uma coisa interessante que estamos fazendo no momento da conexão com o SignalR é utilizar a função “done”. Está função como o próprio nome dela diz é aguardar o sucesso da conexão (ou finalização do método no servidor e a volta da informação para o cliente) e assim executar as instruções customizadas. Neste caso estamos chamando a função GetListRooms para visualizar na tela todas as salas do jogo.

Uma coisa que tem que ficar clara em relação ao funcionamento com o SignalR é o momento em que um cliente chama o servidor e o momento que o servidor chama seus clientes ou um cliente especifico. Neste projeto temos os dois casos e darei exemplos para melhor entendimento.

  • Cliente chama Servidor

Um exemplo de cliente que chama o servidor é a função java script GetListRooms(). Essa função chama o servidor para listar todas as salas de jogos e isso é feito através do código abaixo:

[sourcecode language=”javascript”]

function GetListRooms() {

proxy.server.getListRooms().done(

function (rooms) {

CreateRooms(rooms);

});

}

[/sourcecode]

Note que estamos chamando a variável “proxy”, àquela criada no início, e depois uma propriedade chamada server, que neste caso é a nossa classe TicTacToeHub que contém o método GetListRooms (UAL, isso é um barato!).

Mas por que estamos utilizando novamente a função done?

Simples, quando esperamos resposta do servidor devemos utilizar a função done para receber a resposta conforme explicado mais acima. Neste caso estamos esperando a lista de salas dos jogos conforme o método do servidor retorna, abaixo sua descrição:

[sourcecode language=”csharp”]

public IList<Room> GetListRooms()

{

return _service.GetListRooms();

}

[/sourcecode]

Por que chamamos via cliente o método com letra minúscula (getListRooms) em vez do seu uso correto (GetListRooms)? Quando utilizamos o SignalR pelo java script há uma convenção de que devemos chamar nossos métodos seguindo o seu padrão.

  • Servidor chama clientes

Um excelente exemplo de como o servidor chama o cliente é o método EnterRoom que tem a função de avisar a todos os usuários do aplicativo (independentemente se estão ou não dentro da sala) sobre o novo usuário e iniciar o jogo com o seu adversário. Note que temos dois tipos de mensagens, uma que avisa a todos os usuários e outra que avisa apenas quem está dentro da sala.

[sourcecode language=”csharp”]

public void EnterRoom(string roomName)

{

var room = _service.BindPlayerInRoom(Context.ConnectionId, Clients.Caller.PlayerName, roomName);

Groups.Add(this.Context.ConnectionId, roomName);

Clients.All.changeRoom(_service.GetListRooms());

if (room.IsFull())

Clients.Group(roomName).startGame(room.PlayerCurrent);

}

[/sourcecode]

Note que para o usuário entrar na sala eu utilizado o serviço do sistema e como parâmetro informo o identificador de conexão e o nome do usuário (através da instrução Clients.Caller.PlayerName, variável criada no cliente e que trafega entre o cliente e servidor). Na próxima instrução é criado um grupo através do nome da sala. Este grupo tem por objetivo fazer com que apenas esse grupo receba certas mensagens como é o caso quando um jogador faz alguma jogada e apenas o adversário deverá receber. A criação de um grupo no SignalR é muito simples conforme visto no código, apenas necessário informar um nome de identificação.

Uma das últimas instruções do método EnterRoom é avisar a todos os usuários sobre a alteração da sala, para que assim possa avisar quem entrou na sala. Isso é feito através da instrução Clients.All.changeRoom, changeRoom é uma função java script de escuta criada no início pelo modo cliente. Podemos escrever o que quiser em vez do método cliente “changeRoom”, este código é dinâmico e é aceito qualquer nome, a regra é que este método de escuta deverá existir no cliente.

A propriedade Clients da classe SignalR é uma propriedade para comunicação com o cliente, neste caso podemos utilizar “All” que significa conversar com todos os usuários conectados ou “Group” que significa conversar com usuários apenas de um grupo especifico.

Para visualizar tudo isso que foi falado sugiro que baixe o projeto e teste para melhor entendimento da lógica construída.

Bom, por hoje é só e espero ter ajudado em um melhor entendimento do SignalR com estes dois artigos.

Published in.Net FrameworkC#Visual Studio

One Comment

  1. Daniel Alves Daniel Alves

    Tem como disponibilizar os códigos desse post??

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *