Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Como utilizar socket.io no projeto Alurapic

Usando como base o projeto do Alurapic já com a parte da autenticação implementada, não consegui fazer rodar os exemplos simples de implementação do socket.io. Eu quero atualizar automaticamente um campo no cliente (Angular) assim que ele mudar de valor no servidor, no caso o valor atualizado do banco de dados (mongodb). A pergunta é, como eu configuro o socket.io na nossa arquitetura do projeto com o interceptor e tudo do Alurapic, para ele não dar: unauthorized, ou outro erro qualquer? Fiz o exemplo do socketio-jwt mas também não funcionou. Nosso Auth não autoriza as "requisições" do sockt.io pois não estão consifiguradas nas rotas aceitas pelo servidor. Help.

3 respostas

Boa tarde.

Se você liberou as rotas do socket.io no seu server e ainda não esta tendo acesso, não sei qual problema pode ser, pois justamente citaria a necessidade de abrir essas API para o socket.io. A questão é simples, o socket.io abre uma conexão permanente com sua aplicação e ela não envia o token necessária envolvido na autenticação.

Se quiser uma autenticação por token com socket.io pode consultar

https://auth0.com/blog/auth-with-socket-io/

O trâmite é diferente do que você fez no Angular, porém o conceito é o mesmo. Como nunca diz autenticação com socket.io só consultando a documentação mesmo.

solução!

Olá Flavio obrigado pela resposta. O meu problema inicial foram essas liberações de rotas para o socket.io, eu não soube direito como fazer isso porque ele não manda a requisição como estávamos acostumados. Bom de toda forma consegui uma solução, sem precisar usar autenticação com socket.io. Eu meio que coloquei ele junto com uma rota já definida.

Segue os passos que fiz para fazer rodar:

No server.js:

1° foi necessário mudar a forma como crio o server e a declaração das variáveis ficando assim:

var express = require('express'),
    app = express(),
    http = require('http').Server(app),
    io = require('socket.io')(http),
    port = process.env.PORT || 3000;

//Outras configurações do server.js

Passo a configuração do io no into para o arquivo da api que vai chamar o socket :

consign({ cwd: 'app'})
    .include('models')
    .then('api')
    .then('routes/auth.js') 
    .then('routes')
    .into(app, io);

E o listen no final

http.listen(port, function(){
  console.log('Servidor rodando na porta:'+port);
});

No arquivo da app/api que vai alterar alguma coisa do servidor eu recebo a configuração do io:

module.exports = function(app, io)

E na função que altera algo e preenche um obj eu faço o emit:

io.emit('mensagem',  objetoAlterado);

No Angular.js

Importei no index.html

 <script src="/socket.io/socket.io.js"></script>

Criei uma factory (essa factory é default e necessária)

// From http://briantford.com/blog/angular-socket-io
.factory('socketio', ['$rootScope', function ($rootScope) {
    'use strict';

    var socket = io.connect();
    return {
        on: function (eventName, callback) {
            socket.on(eventName, function () {
                var args = arguments;
                $rootScope.$apply(function () {
                    callback.apply(socket, args);
                });
            });
        },
        emit: function (eventName, data, callback) {
            socket.emit(eventName, data, function () {
                var args = arguments;
                $rootScope.$apply(function () {
                    if (callback) {
                        callback.apply(socket, args);
                    }
                });
            });
        }
    };
}])

No controller

Na declaração do controller chama o socketio da factory

E no corpo do controller recebe o objeto modificado (ou vetor ou outra coisa qualquer):

        socketio.on('mensagem', function (objetoAlterado) {
            $scope.obj = objetoAlterado;
        });

Fiquei algumas horas pra conseguir essa solução que era meio óbvia, eu perguntei e eu mesmo respondi (rs), mas realmente cheguei na solução depois. Fica ai pra algum dia alguém precisar, não sei se ficou muito claro.

Obrigado por compartilhar conosco!