No artigo passado, abordei aplicações em tempo real com a biblioteca SignalR, onde demonstrei seu uso em uma streaming API.
Como citei no artigo, um uso muito comum desta biblioteca é na criação de chats. Para conhecer mais recursos dela, vamos criar este tipo de aplicação.
Começando pelo começo
Antes de mais nada, criaremos uma aplicação web:
dotnet new web -n ChatSignalR
E nela, iremos criar um Hub:
namespace ChatSignalR.Hubs
{
public class ChatHub: Hub
{
public async Task SendMessage(string usuario, string mensagem)
{
await Clients.All.SendAsync("ReceiveMessage", usuario, mensagem);
}
}
}
Note que para esta aplicação o Hub possui um método. Será para este método que o cliente enviará mensagens. Assim que a mensagem for recebida, o Hub a enviará para todos os clientes.
Esta será a dinâmica do nosso chat. Um chat aberto, onde todos os usuários conectados receberão todas as mensagens dos demais usuários.
Na parte do servidor, por fim, é necessário habilitar o SignalR e registrar o hub na classe Startup
:
public class Startup
{
public void ConfigureServices(IServiceCollection services) => services.AddSignalR();
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chat");
});
}
}
Criando o cliente:
O nosso cliente será uma página web simples, que conterá um campo para o usuário informar seu nome e uma mensagem:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Mensagens</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" >
</head>
<body>
<div class="container col-6">
<div class="form-group">
<label for="usuario">Usuário</label>
<input type="text" id="usuario" class="form-control"/>
</div>
<div class="form-group">
<label for="mensagem">Mensagem</label>
<textarea class="form-control" id="mensagem" rows="2"></textarea>
</div>
<input type="button" class="btn btn-primary" id="send" value="Enviar Mensagem" />
</div>
<div class="row">
<div class="col-12">
<hr />
</div>
</div>
<div class="container col-6">
<ul class="list-group" id="messagesList"></ul>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/aspnet-signalr/1.1.4/signalr.min.js'></script>
<script src='main.js'></script>
</body>
</html>
Na parte do JavaScript, conectaremos ao Hub do servidor e definiremos o envio e recebimento de mensagens:
"use strict";
var connection = new signalR.HubConnectionBuilder().withUrl("/chat").build();
$("#send").disabled = true;
connection.on("ReceiveMessage", function (user, message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var li = $("<li></li>").text(user + ": " + msg);
li.addClass("list-group-item");
$("#messagesList").append(li);
});
connection.start().then(function () {
$("#send").disabled = false;
}).catch(function (err) {
return console.error(err.toString());
});
$("#send").on("click", function (event) {
var user = $("#usuario").val();
var message = $("#mensagem").val();
connection.invoke("SendMessage", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
Note que quando uma mensagem for recebida, ela é exibida em uma lista:
connection.on("ReceiveMessage", function (user, message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var li = $("<li></li>").text(user + ": " + msg);
li.addClass("list-group-item");
$("#messagesList").append(li);
});
E no envio é indicado o método definido no Hub:
$("#send").on("click", function (event) {
var user = $("#usuario").val();
var message = $("#mensagem").val();
connection.invoke("SendMessage", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
Curso C# (C Sharp) - APIs REST com ASP.NET Web API
Conhecer o curso1,2, 3…. Testando
Agora, ao executar a aplicação e abrir várias abas, note que todos os usuários irão receber as mensagens que forem enviadas:
Simples, não é?
Você pode obter o código da aplicação demonstrado neste artigo no meu Github.