Neste artigo, mostraremos como criar um aplicativo de bate-papo em tempo real usando as seguintes tecnologias:
- Redis
- Node.js + Express.js
- Socket.IO
- Heroku
Redis
O Redis é um armazenamento de estrutura de dados na memória de código aberto (licenciado BSD), usado como banco de dados, cache e agente de mensagens. Ele suporta estruturas de dados como strings, hashes, listas, conjuntos, conjuntos ordenados com consultas de intervalo, bitmaps, hiperloglogs e índices geoespaciais com consultas de raio.
Neste tutorial do aplicativo, nos conectaremos a um dos clusters usando a hospedagem ScaleGrid para Redis™*.
Node.js
Uma plataforma criada no tempo de execução JavaScript do Chrome para criar aplicativos de rede rápidos e escalonáveis com facilidade. O Node.js usa um modelo de E/S sem bloqueio e orientado a eventos que o torna leve e eficiente, portanto, perfeito para aplicativos em tempo real com uso intenso de dados executados em dispositivos distribuídos.
Express.js
Uma estrutura Node.js. Node.js é uma plataforma que permite que o JavaScript seja usado fora dos navegadores da Web para criar aplicativos da Web e de rede. Isso significa que você pode criar o servidor e o código do lado do servidor para um aplicativo como a maioria das outras linguagens da Web, mas usando JavaScript.
Socket.IO
Uma biblioteca JavaScript para aplicativos da Web em tempo real que permite comunicação bidirecional em tempo real entre clientes e servidores da Web. O Socket.IO tem dois componentes:uma biblioteca do lado do cliente que é executada no navegador e uma biblioteca do lado do servidor para Node.js. Ambos os componentes têm APIs quase idênticas.
Heroku
Uma plataforma em nuvem que permite às empresas criar, entregar, monitorar e dimensionar aplicativos. A plataforma Heroku é a maneira mais rápida de passar da ideia ao URL, ignorando todas essas dores de cabeça de infraestrutura.
Este artigo pressupõe que você já tenha o Redis, Node.js e o Heroku Toolbelt instalados em sua máquina.
Configuração
Crie uma pasta e dê um nome a ela. Você pode criá-lo em qualquer lugar em sua máquina, pois o Node.js não precisa de um servidor especial como o Apache/nginx.
Etapa 1
Inicialize um arquivo package.json executando npm init
.
{ "name":"node-socket-redis-chat-scalegrid", "version":"0.0.1", "description":"Um aplicativo de bate-papo em tempo real usando Redis, Node.js e Socket.IO" , "dependencies":{ "body-parser":"^1.15.2", "express":"^4.10.2", "redis":"^2.6.3", "socket.io":"^1.7 .1" }, "main":"index.js", "scripts":{ "start":"node index.js" }, "engines":{ "node":"4.1.1" }}Etapa 2
Instale as seguintes dependências:
- expressjs
- soquete
- redis
… e alguns outros métodos utilitários:
- parser de corpo
executando o seguinte comando:
npm install --save expressjs socket.io redis body-parser
Etapa 3
Crie uma pasta pública para armazenar nossos arquivos CSS e JS:
/public/css/main.css/public/js/main.js
Etapa 4:
Crie uma pasta de visualizações para armazenar nosso arquivo HTML principal:
/views/index.html
Etapa 5:
Crie um creds.json
arquivo que conterá as credenciais para se conectar ao nosso Redis™ Cluster. Deve seguir o seguinte formato:
{ "usuário":"", "senha":"", "host":"", "porta":6379}
Etapa 6:
Crie o index.js
arquivo que hospedará nosso código Node.js e servirá como ponto de partida para o Heroku.
Etapa 7:
Adicione um .gitignore
arquivo para que a pasta node_modules não seja verificada no Heroku:
node_modules
Após concluir a 7ª etapa, você deverá ter a seguinte estrutura:
.├── creds.json├── index.js├── package.json├── public│ ├── css│ │ └── main.css│ └── js│ └│ └│. js└── visualizações └── index.html
Etapa 8
Agora que tudo está configurado, podemos começar a escrever nosso código de back-end. Primeiro de tudo, precisamos trazer todos os nossos módulos. Então, abra o arquivo index.js e cole o seguinte:
var express =require('express');var bodyParser =require('body-parser');var app =express();var http =require('http').Server(app);var io =require('socket.io')(http);var fs =require('fs');var creds ='';var redis =require('redis');var client ='';var port =process.env .PORT || 8080;// Express Middleware para servir static // arquivos e analisar a solicitação bodyapp.use(express.static('public'));app.use(bodyParser.urlencoded({ extended:true}));// Iniciar o Serverhttp.listen(port, function() { console.log('Server Started. Listening on *:' + port);});// Armazenar pessoas em chatroomvar chatters =[];// Armazenar mensagens em chatroomvar chat_messages =[ ];
Antes de começarmos a escrever qualquer código, precisamos de um cluster executando o Redis. Felizmente, o ScaleGrid for Redis™ oferece uma solução de hospedagem de alto desempenho, com um clique e totalmente gerenciada.
Se você ainda não é um membro, pode se inscrever para uma avaliação gratuita de 30 dias aqui.
Caso contrário, faça login em seu painel e crie um novo cluster Redis™ na seção Redis™:
Quando a criação do cluster estiver concluída, anote as informações acima e adicione-as aos campos relevantes do creds.json
Arquivo.
Agora que temos nossas credenciais configuradas, estamos prontos para criar nosso cliente Redis no Node que se conectará ao nosso cluster e começará a armazenar pares de valores-chave.
Adicione o seguinte código ao arquivo index.js:
// Ler credenciais de JSONfs.readFile('creds.json', 'utf-8', function(err, data) { if(err) throw err; creds =JSON.parse(data); client =redis .createClient('redis://' + creds.user + ':' + creds.password + '@' + creds.host + ':' + creds.port); // Redis Client Ready client.once('ready ', function() { // Libera o Redis DB // client.flushdb(); // Inicializa os Chatters client.get('chat_users', function(err, reply) { if (reply) { chatters =JSON.parse(reply ); } }); // Inicializa as mensagens client.get('chat_app_messages', function(err, reply) { if (reply) { chat_messages =JSON.parse(reply); } }); });});O código acima faz duas coisas:
- Lê as credenciais de
creds.json
e cria um cliente Redis que é usado para realizar operações de valor-chave- Quando o cliente estiver pronto, nós preenchemos os
chatters
e aschat_messages
para que todos os novos membros que ingressarem poderão ver o histórico de bate-papo.Agora vamos escrever algumas APIs para lidar com o aplicativo de bate-papo. Precisamos das seguintes APIs:
- Entrar na sala [POST]
- Sair da sala [POST]
- Enviar mensagem [POST]
- Obter mensagens [GET]
- Obter membros [GET]
Vamos começar com a API Join Room. Isso é chamado quando qualquer novo usuário inicia o aplicativo e tenta ingressar na sala de bate-papo:
// API - Join Chatapp.post('/join', function(req, res) { var username =req.body.username; if (chatters.indexOf(username) ===-1) { chatters. push(username); client.set('chat_users', JSON.stringify(chatters)); res.send({ 'chatters':chatters, 'status':'OK' }); } else { res.send({ 'status':'FALHADO' }); }});
Aqui temos a API para sair da sala de bate-papo:
// API - Leave Chatapp.post('/leave', function(req, res) { var username =req.body.username; chatters.splice(chatters.indexOf(username), 1); client.set ('chat_users', JSON.stringify(chatters)); res.send({ 'status':'OK' });});
Enviando e armazenando a mensagem:
// API - Send + Store Messageapp.post('/send_message', function(req, res) { var username =req.body.username; var message =req.body.message; chat_messages.push({ ' sender':username, 'message':message }); client.set('chat_app_messages', JSON.stringify(chat_messages)); res.send({ 'status':'OK' });});
Receba todas as mensagens na sala:
// API - Get Messagesapp.get('/get_messages', function(req, res) { res.send(chat_messages);});
Obter todos os membros:
// API - Obter Chattersapp.get('/get_chatters', function(req, res) { res.send(chatters);});
Depois que tivermos todas as APIs configuradas, precisamos escrever o código Socket.IO para emitir eventos quando certas propriedades, como as seguintes, forem atualizadas:
- Contagem de quartos
- Mensagens
// Socket Connection// UI Stuffio.on('connection', function(socket) { // Dispara o evento 'send' para atualizar a lista de mensagens na UI socket.on('message', function(data) { io .emit('send', data); }); // Dispara 'count_chatters' para atualizar o Chatter Count na UI socket.on('update_chatter_count', function(data) { io.emit('count_chatters', data); } );});
Esses eventos são então captados no front-end pela biblioteca Socket.IO, que por sua vez atualiza a interface do usuário.
Etapa 9
Agora, precisamos construir nossa interface do usuário que permitirá que os usuários façam login e conversem.
Abra o index.html
arquivo e adicione o seguinte código:
Node.js + Socket.io + Redis Chat | ScaleGrid Node.js + Socket.io + Redis Chat | ScaleGrid
Etapa 10
Para fazer nosso HTML funcionar, precisamos adicionar alguns eventos JavaScript AJAX que irão lidar com as várias operações como entrar em uma sala, sair, enviar uma mensagem etc.
O código a seguir obtém o número de conversas para que possamos atualizar a interface do usuário sobre o número total de pessoas na sala:
$.get('/get_chatters', function(response) { $('.chat-info').text("Existem atualmente " + response.length + " pessoas na sala de chat"); chatter_count =response.length; //atualizar a contagem de conversas});
Este código permite que os usuários entrem na sala de bate-papo. Lembre-se de que os nomes de usuário são únicos e não podem ser duplicados:
$('#join-chat').click(function() { var username =$.trim($('#username').val()); $.ajax({ url:'/join' , type:'POST', data:{ username:username }, success:function(response) { if (response.status =='OK') { //username ainda não existe socket.emit('update_chatter_count', { 'action':'increase' }); $('.chat').show(); $('#leave-chat').data('username', username); $('#send-message' ).data('username', username); $.get('/get_messages', function(response) { if (response.length> 0) { var message_count =response.length; var html =''; for (var x =0; x " + response[x]['sender'] + "" + resposta[x]['message'] + ""; } $('.messages').html(html); } }); $('.join-chat').hide(); //esconde o container para entrar na sala de chat. } else if (response.status =='FAILED') { //nome de usuário já existe alert("Desculpe, mas o nome de usuário já existe, por favor escolha outro"); $('#username').val('').focus(); } } });});
Aqui está o código para permitir que os usuários saiam da sala de bate-papo:
$('#leave-chat').click(function() { var username =$(this).data('username'); $.ajax({ url:'/leave', type:'POST ', dataType:'json', data:{ username:username }, success:function(response) { if (response.status =='OK') { socket.emit('message', { 'username':username, 'message':username + " saiu da sala de bate-papo.." }); socket.emit('update_chatter_count', { 'action':'decrease' }); $('.chat').hide(); $ ('.join-chat').show(); $('#username').val(''); alert('Você saiu com sucesso da sala de bate-papo'); } } });});Aqui está o código que é executado toda vez que alguém envia uma mensagem:
$('#send-message').click(function() { var username =$(this).data('username'); var message =$.trim($('#message').val ()); $.ajax({ url:'/send_message', type:'POST', dataType:'json', data:{ 'username':username, 'message':message }, success:function(response) { if (resposta.status =='OK') { socket.emit('message', { 'username':username, 'message':message }); $('#message').val(''); } } });});A seguir está o código Socket.IO que escuta eventos do back-end e atualiza a interface do usuário. Por exemplo, adicionar novas mensagens à área de mensagens, atualizar a contagem de conversas, etc.:
socket.on('send', function(data) { var username =data.username; var message =data.message; var html =""; $('.messages').append(html);});socket. on('count_chatters', function(data) { if (data.action =='increase') { chatter_count++; } else { chatter_count--; } $('.chat-info').text("Existem atualmente " + chatter_count + " pessoas na sala de bate-papo");});" + nome de usuário + "" + mensagem + "E pronto! Inicie o servidor usando
npm start
e abra várias janelas do navegador para simular vários usuários.
Uma demonstração do aplicativo está disponível aqui: https://node-socket-redis-chat.herokuapp.com/
Para implantar este aplicativo no Heroku, confira os documentos: https://devcenter.heroku.com/categories/deployment
Todo o código-fonte também está disponível no GitHub para você bifurcar e trabalhar: https://github.com/Scalegrid/code-samples/tree/sg-redis- node-socket-chat/redis-node-socket-chat
Como sempre, se você criar algo incrível, twitte-nos sobre isso @scalegridio.
Se você precisar de ajuda com o gerenciamento e a hospedagem do Redis™, vamos simplificar as coisas para você com nossos serviços profissionais.