Aguarde...

20 de julho de 2020

Um guia para iniciantes de criação de aplicativos em tempo real com o Node.js

Um guia para iniciantes de criação de aplicativos em tempo real com o Node.js

Aprenda sobre aplicativos em tempo real com o Node.JS criando um

Em um mundo em que o valor do tempo aumenta constantemente, a criação de aplicativos com os quais os usuários possam interagir em tempo real se tornou uma norma para a maioria dos desenvolvedores. A maioria dos aplicativos que vemos hoje, sejam móveis, desktop ou web, tem pelo menos um único recurso em tempo real incluído. Como exemplo, as mensagens e notificações em tempo real são dois dos recursos em tempo real mais usados ​​nos aplicativos.

Neste artigo, apresentamos o desenvolvimento de aplicativos em tempo real usando o Node.js, criando um bate-papo em tempo real. Embora o artigo se concentre nesse caso de uso específico, os conceitos aqui ensinados podem ser aplicados a outros cenários.

De fato, o Node é uma das melhores linguagens de programação disponíveis para criar aplicativos em tempo real devido à sua natureza assíncrona e orientada a eventos. Antes de começar a construir um aplicativo em tempo real, veremos que tipo de aplicativos em tempo real podemos criar usando o Node.js. Se você quiser conhecer mais outras áreas em que o Node.js se destaca ou simplesmente fica aquém, leia meu artigo Quando você deve e não deve usar o Node.js. para seu projeto .

Onde os aplicativos em tempo real são usados?

Como mencionei acima, a entrega de mensagens e notificações são dois dos casos de uso mais comuns para aplicativos em tempo real. Mas podemos usar aplicativos em tempo real para uma infinidade de outros propósitos. Vamos ver o que são. 

Mensagens em tempo real

A maioria de nós está familiarizada com o uso de aplicativos de mensagens em tempo real, especialmente em dispositivos móveis, na forma de Whatsapp, Facebook Messenger e vários outros aplicativos de mensagens. No entanto, as mensagens em tempo real não são limitadas a aplicativos de mensagens puramente. Vemos recursos de mensagens em tempo real em aplicativos de táxi sob demanda, aplicativos de entrega e plataformas colaborativas.

Entrega de Notificação em Tempo Real

A ativação de notificações em tempo real provou ser uma virada no jogo quando se trata de aumentar o envolvimento do usuário com os aplicativos. Por esse motivo, dificilmente você veria um aplicativo moderno que não entrega notificações em tempo real para seus usuários. 

Transmissão ao vivo

As transmissões ao vivo com as quais os usuários podem interagir em tempo real estão se tornando cada vez mais populares depois que as plataformas de mídia social integram as transmissões de vídeo ao vivo a seus aplicativos. Os recursos de transmissão ao vivo do Instagram e do Facebook são os melhores exemplos disso. 

Rastreamento em tempo real

Com a introdução de aplicativos populares de táxi e entrega, como Uber e Amazon, acompanhar o progresso das viagens ou entregas de táxi dos usuários em tempo real tornou-se um requisito essencial. Suas atualizações de progresso em tempo real aumentam a usabilidade e a confiabilidade desses aplicativos. 

Dispositivos IoT

Recursos em tempo real são essenciais para dispositivos IoT. Os dados capturados pelos sensores colocados nos dispositivos IoT são transmitidos, processados ​​e exibidos aos usuários finais com um atraso mínimo. Como a maioria das entradas capturadas por esses dispositivos, como temperatura e iluminação, muda constantemente com o tempo, os aplicativos que trabalham com dispositivos IoT devem poder receber e enviar dados em tempo real. 


Como podemos criar aplicativos em tempo real?

A criação de um aplicativo em tempo real é diferente da criação de um aplicativo Web normal? A resposta é sim. 

Pense em um aplicativo de mensagens em que os usuários possam enviar mensagens em tempo real. Essas mensagens devem aparecer no aplicativo de outros usuários assim que as mensagens forem enviadas. Se implementarmos esse aplicativo como um aplicativo Web normal, onde apenas o cliente pode iniciar solicitações ao servidor para receber dados, o usuário deverá atualizar a página da Web regularmente para ver as mensagens mais recentes ou o lado do cliente deve enviar solicitações AJAX para o servidor em curtos intervalos de tempo para recuperar as mensagens mais recentes. O primeiro dos dois não é muito fácil de usar e o segundo é um desperdício de recursos do aplicativo. Então, claramente, precisamos ter um método diferente para criar aplicativos em tempo real que faça mais sentido. 

O WebSocket fornece a solução que precisamos. O WebSocket é um protocolo de comunicação que permite ao cliente e ao servidor iniciar a comunicação. Em outras palavras, com o WebSocket, o servidor pode enviar dados para o cliente a qualquer momento, sem que o cliente precise solicitar dados primeiro. No caso do aplicativo de mensagens anterior, podemos usar o WebSockets para enviar instantaneamente mensagens para todos os usuários através do servidor. Podemos usar a API WebSocket para se comunicar usando WebSockets ao criar aplicativos. 


Socket.io

No entanto, ao implementar um aplicativo em tempo real usando o Node, não precisamos usar diretamente a API WebSocket. Em vez disso, a biblioteca Javascript e Node.js.Socket.io, que é uma API da API WebSocket, fornece uma implementação muito mais simples do WebSockets para uso. Neste tutorial, usaremos o Socket.io para criar e gerenciar conexões WebSocket entre o cliente e o servidor. 


Criando uma sala de bate-papo em tempo real com o Node.js

Agora que falamos sobre o desenvolvimento de aplicativos em tempo real, podemos começar a criar nosso próprio aplicativo em tempo real. Neste tutorial, vamos construir uma sala de bate-papo simples que os usuários podem usar para se comunicar com outros usuários conectados. Qualquer número de usuários pode se conectar à sala de bate-papo e as mensagens enviadas por um usuário tornam-se instantaneamente visíveis a todos os usuários conectados à sala de bate-papo. 

Nossa sala de chat simples terá o seguinte conjunto de recursos. 

  • Alterar o nome de usuário do usuário
  • Enviar mensagens
  • Mostrar se outro usuário está digitando uma mensagem

Legal, agora que temos nossos requisitos, vamos começar a criar o ambiente e a configurar a estrutura


Configurando o ambiente de aplicativos

Primeiro, crie um novo diretório para o aplicativo. Em seguida, execute the npm initpara configurar o package.jsonarquivo. Certifique-se de que, nesta etapa, você atribua app.jscomo seu script principal; caso contrário, não se preocupe, você sempre poderá alterá-lo package.jsonposteriormente.

Instalar dependências

Neste tutorial, estamos usando os pacotes express, ejs, socket.io e nodemon para criar o aplicativo. 

  • Ejs é um mecanismo de modelo JS popular
  • Discutimos o uso do socket.io anteriormente
  • O Nodemon é um pacote que reinicia o servidor toda vez que fazemos uma alteração no código do aplicativo. Isso elimina a necessidade de parar e iniciar manualmente o servidor toda vez que fazemos uma alteração. Diferentemente dos outros pacotes, instalamos o nodemon como uma dependência de desenvolvimento, uma vez que o usamos apenas para fins de desenvolvimento. 

Instale express, ejs e socket.io usando o seguinte comando. 

npm install express ejs socket.io --save

Instale o nodemon como uma dependência de desenvolvimento usando este comando. 

npm install nodemon --save-dev

Para iniciar o aplicativo com nodemon, devemos adicionar um script de início ao nosso arquivo package.json. 

"scripts": {
    "start": "nodemon app.js",
 },

Em seguida, podemos iniciar o aplicativo executando o seguinte comando na linha de comando. 

npm run start

Se falhar, não se preocupe, é basicamente porque ainda não temos nenhum arquivo de código.

Configure a estrutura do aplicativo

Com todas as dependências necessárias para este projeto instaladas, vamos criar o aplicativo na estrutura do projeto. Para isso, você precisará criar alguns diretórios e, por enquanto, um arquivo chamado app.js. Vamos fazer isso para que a estrutura do seu aplicativo tenha a seguinte aparência:

|--app.js
|--views
|--node_modules
|--package.json
|--public
   |--css
   |--js

Eu acho que a estrutura é bem clara, mas vamos repassar rapidamente:

  • app.js: file que usaremos para hospedar nosso código do lado do servidor
  • views: pasta contendo as visualizações (ejs)
  • node_modules: onde instalamos nossas dependências
  • package.json arquivo de configuração npm
  • public: diretório que usaremos para armazenar nossos ativos, como arquivos css, arquivos javascript (para o lado do cliente) e imagens.

Primeiros passos construindo o servidor

O primeiro que precisamos fazer antes mesmo de pensar em fazer as conexões em tempo real é começar expressa funcionar, para isso, vamos abrir nosso app.jsarquivo e colar o seguinte código:

const express = require('express')
const socketio = require('socket.io')
const app = express()

app.set('view engine', 'ejs')
app.use(express.static('public'))

app.get('/', (req, res)=> {
    res.render('index')
})

const server = app.listen(process.env.PORT || 3000, () => {
    console.log("server is running")
})

Depois de expressconfigurar e usar ejscomo sistema de modelo, podemos começar a trabalhar na inicialização do sockets.io. Para isso, adicione o seguinte código no final do seu app.jsarquivo.

//initialize socket for the server
const io = socketio(server)

io.on('connection', socket => {
    console.log("New user connected")
})

O código é bastante simples: estamos inicializando a socket.iopartir de nossa serverconexão (expressa) e, em seguida, configuramos um uso uniforme io.on()que será acionado toda vez que uma nova conexão com o soquete for estabelecida.

Se você agora executar seu servidor npm start, poderá receber novas conexões de soquete. Então, vamos começar a construir nosso front-end.


Construindo nosso front-end

Nós não gastar muito tempo fazendo o nosso olhar front-end incrível, mas vamos explicar como a conexão com as obras de servidor, como emitcaptureeventos de soquete e vamos aplicar tudo isso em nosso exemplo chat.

Vamos começar criando um modelo em nossa pasta views, para isso crie um index.ejsarquivo e cole o seguinte código:

<!DOCTYPE html>
<head>
    <title>Simple realtime chatroom</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
</head>
<body>
    <div class="container">
        <div class="title">
            <h3>Realtime Chat Room</h3>
        </div>
       
        <div class="card">
            <div class="card-header">Anonymous</div>
            <div class="card-body">
                <div class="input-group">
                    <input type="text" class="form-control" id="username" placeholder="Change your username" >
                    <div class="input-group-append">
                        <button class="btn btn-warning" type="button" id="usernameBtn">Change</button>
                    </div>
                </div>
            </div>
            <div class="message-box">
                <ul class="list-group list-group-flush" id="message-list"></ul>
                <div class="info"></div>
            </div>
            
            <div class="card-footer">
                <div class="input-group">
                    <input type="text" class="form-control" id="message" placeholder="Send new message" >
                    <div class="input-group-append">
                        <button class="btn btn-success" type="button" id="messageBtn">Send</button>
                    </div>
                </div>
            </div>
        </div>

    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
    <script src="/js/chatroom.js"></script>
</body>
</html>

Observe como incluímos o script da biblioteca socket.io do lado do cliente e o arquivo javascript personalizado que vamos usar neste código. 

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
<script src="/js/chatroom.js"></script>

Também temos um botão com ID messageBtnpara enviar uma nova mensagem e outro botão com ID usernameBtnpara enviar um novo nome de usuário. As entradas de nome de usuário e mensagem têm IDs usernamemessagerespectivamente. Espera-se que todas as mensagens do usuário apareçam dentro da lista não ordenada com o ID message-list. Se um usuário estiver amarrando uma mensagem, essas informações aparecerão dentro da div com classe info.

Se você abrir o navegador e acessar http://localhost:3000/o aplicativo, será algo como isto:

Um guia para iniciantes de criação de aplicativos em tempo real com o Node.js
Layout da sala de bate-papo em tempo real

Mas não está fazendo nada, os botões não funcionarão e serão praticamente um aplicativo estático. Então, a seguir, vamos começar a conectar o front-end ao servidor.

Para isso, crie um novo arquivo Javascript chamado chatroom.jsdentro da pasta js (observe no HTML acima, que eu já estou fazendo referência a esse arquivo) do diretório público. Dentro do arquivo Javascript, precisamos nos conectar ao soquete do front-end. Nós podemos fazer assim. 

(function connect(){
    let socket = io.connect('http://localhost:3000')
})()

Visite seu site novamente e em seu terminal (no lado do servidor) você verá algo como:

Um guia para iniciantes de criação de aplicativos em tempo real com o Node.js
Exemplo de log de terminal

Impressionante! seu aplicativo já está funcionando, embora não faça muito. Vamos construir a funcionalidade a seguir


Alterando o nome do usuário

O nome de usuário padrão que usamos para todas as conexões é “Anônimo”. Damos aos usuários a opção de alterar esse nome de usuário. Configuraremos o back-end para alterar o nome de usuário quando o front-end emitir um change_usernameevento. Volte para o código do servidor ( app.js) e edite seu connectionevento para adicionar um novo código.

io.on('connection', socket => {
    console.log("New user connected")

    socket.username = "Anonymous"

    socket.on('change_username', data => {
        socket.username = data.username
    })
})

Em seguida, precisamos ajustar nosso front-end, para que, ao pressionar o botão alterar nome de usuário, ele emita um evento para o servidor com o nome change_username. Veja como criamos o nome emitindo e capturando o mesmo nome de evento? 

Dentro chatroom.js, vamos adicionar um ouvinte de evento usernameBtnpara emitir um change_usernameevento quando o botão for clicado. 

(function connect(){
    let socket = io.connect('http://localhost:3000')

    let username = document.querySelector('#username')
    let usernameBtn = document.querySelector('#usernameBtn')
    let curUsername = document.querySelector('.card-header')
    
    usernameBtn.addEventListener('click', e => {
        console.log(username.value)
        socket.emit('change_username', {username: username.value})
        curUsername.textContent = username.value
        username.value = ''
    })
})()

Agora, se você recarregar a página da web e enviar um novo nome de usuário, verá o seu nome de usuário atual alterado para o novo. Em seguida, vamos começar a enviar mensagens.


Enviando Mensagens

O próximo recurso que vamos implementar é o envio de mensagens. Aqui as coisas começam a ficar um pouco diferentes, até agora dissemos que toda vez que o front-end emite uma mensagem, o servidor a recebe, no entanto, no nosso novo caso, o front-end precisa emitir um new_messageevento, que precisará para ser enviado a todos os clientes conectados, para que eles possam imprimir a nova mensagem.

Primeiro, configuraremos o front-end para emitir um new_messageevento quando uma nova mensagem for enviada. Como o lado do cliente também deve ser configurado para receber novas mensagens que outros usuários enviam do servidor, o aplicativo também deve escutar receive_messageeventos no front-end e mostrar a nova mensagem na página da Web adequadamente. Podemos realizar essas duas tarefas usando o código a seguir que entra na connectfunção anterior em chatroom.js.

let message = document.querySelector('#message')
let messageBtn = document.querySelector('#messageBtn')
let messageList = document.querySelector('#message-list')

messageBtn.addEventListener('click', e => {
    console.log(message.value)
    socket.emit('new_message', {message: message.value})
    message.value = ''
})

socket.on('receive_message', data => {
    console.log(data)
    let listItem = document.createElement('li')
    listItem.textContent = data.username + ': ' + data.message
    listItem.classList.add('list-group-item')
    messageList.appendChild(listItem)
})

Sempre que o receive_messageevento acontece no lado do cliente, alteramos nosso DOM para renderizar a mensagem na tela.

No lado de back-end, quando recebemos um new_messageevento, precisamos emitir um novo evento para todos os clientes, para isso usamos a io.sockets.emit()função. Altere seu connectionevento no seu app.jsarquivo da seguinte maneira:

io.on('connection', socket => {
    console.log("New user connected")

    socket.username = "Anonymous"

    socket.on('change_username', data => {
        socket.username = data.username
    })


    //handle the new message event
    socket.on('new_message', data => {
        console.log("new message")
        io.sockets.emit('receive_message', {message: data.message, username: socket.username})
    })

})

Ao manipular o new_messageevento, o próprio servidor emite um receive_messageevento para os clientes conectados com dados sobre a nova mensagem. Este evento é recebido por todos os usuários conectados ao servidor, incluindo aquele que enviou a mensagem, para que a nova mensagem seja exibida em suas interfaces de sala de bate-papo. 

Se agora você abrir o aplicativo da web no navegador (você pode ter várias instâncias), poderá começar a conversar (com você mesmo?: P)

Você pode se conectar à sala de bate-papo usando dois navegadores separados e brincar com o recurso de envio de mensagens e ver como as mensagens que um usuário envia aparecem instantaneamente nas interfaces de aplicativos dos dois usuários. 

Um guia para iniciantes de criação de aplicativos em tempo real com o Node.js
Sala de bate-papo em tempo real – Enviando mensagens

Estou digitando ….

Na maioria dos aplicativos de mensagens em tempo real que usamos hoje, vemos um texto simples que diz “o usuário X está digitando …” sempre que outro usuário digita uma mensagem. Isso dá ao aplicativo uma sensação mais em tempo real e melhora a experiência do usuário. Nós vamos adicionar esse recurso ao nosso aplicativo. 

Primeiro, vamos considerar a implementação do front-end. Nós adicionamos um novo ouvinte de evento à caixa de entrada de mensagem para emitir um typingevento sempre que um pressionamento de tecla ocorre. Se as teclas pressionadas na caixa de entrada de mensagens indicam que o usuário está digitando uma mensagem, o typingevento informa ao servidor que o usuário está digitando uma mensagem. O lado do cliente também escuta os typingeventos emitidos pelo servidor para saber se outro usuário está digitando uma mensagem no momento e mostrá-la na interface do usuário. 

Novamente, dentro da função connect chatroom.js, adicionamos o código a seguir. 

let info = document.querySelector('.info')

message.addEventListener('keypress', e => {
    socket.emit('typing')
})

socket.on('typing', data => {
    info.textContent = data.username + " is typing..."
    setTimeout(() => {info.textContent=''}, 5000)
})

Se um usuário estiver digitando uma mensagem, outros usuários receberão o texto ” está digitando …” por 5 segundos. 

Agora, precisamos configurar o back-end para lidar com eventos de digitação. O código que usamos aqui é este. 

socket.on('typing', data => {
    socket.broadcast.emit('typing', {username: socket.username})
})

Aqui, o socket.io usa a broadcastfunção para notificar os clientes conectados. Quando usamos broadcast, todos os usuários, exceto quem está digitando a mensagem, recebem o evento de digitação do servidor. Portanto, todo usuário, exceto aquele que digita a mensagem, é mostrado no texto ” está digitando …”. 

Mais uma vez, você pode se conectar à sala de bate-papo a partir de dois navegadores e ver como isso funciona em tempo real. 

Um guia para iniciantes de criação de aplicativos em tempo real com o Node.js
Sala de bate-papo em tempo real – Digitação

Impressionante!


Resumo

Hoje, o uso de recursos em tempo real com aplicativos para desktop, dispositivos móveis e Web quase se tornou uma necessidade. Neste artigo, abordamos vários aplicativos de aplicativos em tempo real e aprendemos a criar uma sala de bate-papo em tempo real com a ajuda do Node.js. e do Socket.io. Para continuar a partir daqui, você pode tentar melhorar essa sala de chat adicionando mais recursos e usando um banco de dados para persistir em mensagens mais antigas ou implementar outro aplicativo em tempo real com um caso de uso diferente.

Obrigado pela leitura!

Postado em Blog
Escreva um comentário