Nas 
aulas anteriores do minicurso de Socket.IO, já preparamos o ambiente, conectamos o websocket do client para o servidor e agora vamos começar a emitir realmente as notificações.
A primeira coisa que vamos fazer é enviar o placar, vamos abrir o template match.ejs dentro de admin. A única coisa que temos de diferente é o time e os gols, nós vamos pegar esses dados e quando o usuário clicar em atualizar placar, iremos enviar isso ao servidor e ele vai disparar via socket.io para todos os clients.
Primeiramente lá no final, após incluir o footer, vamos adicionar um script:
<script src='/js/admin.js'></script>
Esse script ainda não existe, vamos criar agora no diretório public/js, primeiro temos que descobrir qual o ID do botão do formulário, que é update-score e quando o usuário clicar nesse botão, eu quero dar um alert apenas para saber se está rodando:
$(function)(){
    $("#update-score").click(function(){
        alert(1)
        return false;
    })
});
Agora precisamos pegar os dois valores do jogo nos ID's score, e score-b, o notify-score e damos um console.log para saber se está tudo correto:
$(function)(){
    $("#update-score").click(function(){
        const scoreA = $("#score-a").val();
        const scoreB = $("#score-b").val();
        const notify = $("#score-notify").val();
        console.log(scoreA, scoreB, notofy)
        return false;
    })
});
Perceba que o notify continuou com o value 1, isso acontece porque não está checando se esta checked ou não, então fazemos isso:
const notify = $('#score-notify:checked').val()
Agora precisamos enviar isso para o express para ele distribuir via Socket.IO para todos os clients. Ao invés de mandar essa atualização via Socket.IO, eu posso mandar via API, salvar essa informação no banco e aí sim notificar (eu prefiro usar sempre essa forma para eu garantir que eu só envie essa notificação para todo mundo).
$(function)(){
    $("#update-score").click(function(){
        const scoreA = $("#score-a").val();
        const scoreB = $("#score-b").val();
        const notify = $("#score-notify").val();
        $.post("/admin/match/0/score", post {
            scoreA, scoreB, notify
        }, function(data){
            console.log(data)
        })
        return false;
    })
});
Ele não vai conseguir, pois não achou, mas se olharmos a conexão os dados já estão sendo enviados, então temos que receber esses dados lá. Vamos voltar em routes/admin.js e criar novo router:
router.post('/match/:id/score', function (req, res) {
  res.send(req.body)
})
Fizemos isso para termos certeza que os dados estão chegando aqui, então vamos parar o servidor e a resposta do score vai ser exatamente o que eu enviei para ele, agora podemos processar esses dados. Vamos setar o valor no placar do banco de dados. Uma das formas que temos de fazer isso no low-db é pegando o índice do jogo e setar lá dentro falando qual o valor vou enviar para ele. Essa informação vai para todos os jogos, então eu devo emitir para todos que estão conectados no Socket.IO:
router.post('/match/:id/score', function (req, res) {
  db.set(
    'matches[' + req.params.id + '].team-a.score',
    parseInt(req.body.scoreA)
  ).write()
  db.set(
    'matches[' + req.params.id + '].team-b.score',
    parseInt(req.body.scoreB)
  ).write()
  io.emit('score', {
    match: req.params.id,
    scoreA: req.body.scoreA,
    scoreB: req.body.scoreB,
    notify: req.body.notify || 0
  })
  res.send(req.body)
})
Se o notify não existir, ele não vai ser enviado e eu mando zero para não notificar meus usuários. Agora está funcionando perfeitamente, se startarmos o servidor e dermos um f5, vai ser mostrado o valor enviado. Como eu tenho que dar f5 toda hora, tenho que receber no meu client a atualização que o jogo foi alterado, então vamos abrir na pasta js o arquivo match.js:
$(function)(){
    const socket = io();
    socket.on('connect', function(){
        console.log('conected');
    })
    socket.on('score', function(score){
        console.log('score', score)
    })
})
Perceba que agora, ao atualizar o placar, o usuário recebe o objeto score, então precisamos checar se o jogo está na barra de cima e se é o jogo atual para atualizar na barra principal. Para isso vamos em match.ejs e na lista de jogo que fica na parte de cima, já temos um forEach que vai renderizar todos os jogos e temos para cada jogo um 'em' que tem o nome da class com uma referência para o jogo como um todo.
Vamos copiar esse trecho de código em negrito:
<em class="match-<%- index %>-b">
Agora vamos voltar para nosso match do client em js/match.js e fazer o seguinte:
$(function)(){
    const socket = io();
    socket.on('connect', function(){
        console.log('conected');
    })
    socket.on('score', function(score){
        console.log('score', score)
        
        $(". match-"+score.match+"-a").html(score.scoreA)
        $(". match-"+score.match+"-b").html(score.scoreb)
    })
})
Perceba que em A nós escrevemos o valor de score.scoreA e o mesmo no B. Agora temos que atualizar a parte de baixo também, então nós temos o score-team-A e o valor do score por exemplo, porém como eu vou saber se esse jogo é o que eu estou atualmente? Em match.ejs, lá no final, antes do include do footer, vamos fazer um script que define uma constante:
<script>
const MATCH_INDEX = "<%- id %>";
</script>
Quando faço isso, o match.index consegue acessar esse valor, então dentro do nosso match conseguimos checar se estamos em nosso jogo atual:
socket.on('score', function (score) {
  console.log('score', score)
  
  $('. match-' + score.match + '-a').html(score.scoreA)
  $('. match-' + score.match + '-b').html(score.scoreb)
  
  if (MATCH_INDEX == score.match) {
    $('.score-team-a').html(score.scoreA)
    $('.score-team-b').html(score.scoreB)
    if (score.notify == '1') {
      console.log('notificar')
    }
  }
})
Se o jogo é o que recebemos a notificação, nós notificamos esse gol. Em view/match, lá no final, temos uma div que é uma class goooolllll com um áudio, então se estivermos com o notificado ligado vamos dar um play nesse áudio, voltamos no código anterior e adicionamos o seguinte:
if (score.notify == '1') {
  console.log('notificar')
  $('#audio-gol')[0].currentTime = 0
  $('audio-gol')[0].play()
}
Por que fizemos o notificar sim ou não? É possível notificar um gol e caso ele seja anulado, você tira o notificar e tira o placar sem alarmar todos. Podemos também fazer uma animação com aquele div que está ali
if(score.notify=='1'){
    console.log('notificar')
    $('#audio-gol')[0].currentTime=0;
    $('audio-gol')[0].play();
    $('.goooolllll')addClass('goooolllll-anim')
    $('.goooolllll-text')addClass('goooolllll-text-anim')
    $('.goooolllll-text')on('transitionend webkitTransitionEnd oTransitionEnd', function(){
        $('.goooolllll')removeClass('goooolllll-anim')
        $('.goooolllll-text')removeClass('goooolllll-text-anim')
    })
}
Para testar temos que notificar em uma outra aba. Ao clicar, aparece duas classes com essa animação, quando a animação terminar nós removemos essa animação.
Na próxima aula vamos colocar a comunicação do lance a lance e dos vídeos, além de colocar o projeto em um servidor no digitalhost para conseguirmos acessar externamente.
Confira o passo a passo em vídeo:
Curta o 
DevPleno no Facebook, 
inscreva-se no canal e não se esqueça de cadastrar seu e-mail para não perder as novidades. Abraço!