2017-09-06 25 views
0

Ich bin in einer Echtzeit-Anwendung zu arbeiten, und ich bin mit Socket.io diese Funktion zu erhalten.Socket.io mehr Verbindungen, wenn Seite aktualisiert

Was ich bisher habe ist, wenn ein Benutzer etwas (Text) posten, meine Sockets Server erhalten diese Nachricht und dann sendet es an meinen Controller, um diese Daten auf einer DB (MySQL) zu speichern. Dann wird dieselbe Nachricht über denselben Socket-Server an den Client zurückgegeben.

Eigentlich funktioniert dies gut, aber wenn ich meinen Browser aktualisieren und eine neue Nachricht veröffentlichen, werden die Daten zweimal in die Datenbank eingefügt, so dass ich erhalten die gleichen zwei Nachrichten in meinem Klienten. Dies passiert jedes Mal, wenn ich die Seite aktualisiere. Wenn ich also die Seite 10 Mal aktualisiert habe, werde ich 10 Nachrichten mit denselben Daten in meine Datenbank einfügen.

Dies ist der Code, den ich jetzt habe, würde jede mögliche Hilfe groß sein.

SocketServer.js

var express = require('express'); 
var app = express(); 
var http = require('http').Server(app); 
var io = require('socket.io')(http); 

//websockets 
var messages = 'Recibido'; 
var Usuarios = 0; 
var storeUsers = []; 

app.use(express.static('public')); 

io.sockets.on('connection', function(socket) { 
    Usuarios++; 

    console.log('Usuarios totales: ' + Usuarios); 
    io.sockets.emit('users-connected', Usuarios); 

    var clients = io.sockets.clients(); 
    var conectados = clients.connected; 

    console.log('------------------ROOM-------------------------'); 
    for (client in conectados) { 
    var color = '\x1b[32m' + client; 
    console.log('id: ' + color, '\x1b[0m'); 
    } 
    console.log('\x1b[0m', '-----------------------------------------------'); 

    socket.on('disconnect', function() { 
    Usuarios--; 
    var desconectao = '\x1b[31m' + socket.id 
    console.log('Socket desconectado: ' + desconectao, '\x1b[0m'); 
    io.sockets.emit('users-connected', Usuarios); 
    socket.removeAllListeners(); 
    }); 

    socket.on('new-publication', function(data){ 
    console.log('Mensaje del usuario: ' + data.pub); 
    io.sockets.emit('do-it', data) 
    }) 

    socket.on('do-publication', function(data){ 

    console.log('Info: ' + data.nombre); 
    io.sockets.emit('do-publication', data) 
    }) 

}); 

http.listen(8081, function() { 
    console.log("websockets corriendo en el puerto 8081"); 
}); 

Controller.js

var mysql = require('mysql'); 
var io = require('socket.io-client'); 
var socket = io.connect('http://localhost:8081', {transports: ['websocket'], upgrade: false}); 


module.exports = { 

    index: function(req,res,next){ 

     if (req.isAuthenticated()) { 

      var config =require('.././database/config'); 
      var db = mysql.createConnection(config); 

      db.query('SELECT publicaciones.publicacion, publicaciones.fecha_pub, publicaciones.imagen ,users.nombre AS nombre, users.image AS image FROM publicaciones JOIN users ON publicaciones.id_user = users.id ORDER BY fecha_pub DESC', function(err, rows, fields){ 

       resultado = rows; 

       var message = { 
        isAuthenticated : req.isAuthenticated(), 
        items: resultado, 
        user: req.user, 
       }; 

       res.render('users/panel',message); 

      }); 

      socket.on('users-connected', function(data){ 
       console.log('Conectado al servidor Websockets'); 
       console.log('Usuarios conectados: ' + data); 
      }); 

      socket.on('do-it', function(data){ 
       var datos_pub; 
       console.log(data.pub); 
       var currentdate = new Date(); 
       var datetime = currentdate.getFullYear() + "-" 
       + (currentdate.getMonth()+1) + "-" 
       + currentdate.getDate() + " " 
       + currentdate.getHours() + ":" 
       + currentdate.getMinutes() + ":" 
       + currentdate.getSeconds(); 

       var publicacion = { 
        id_user : req.user.id, 
        publicacion : data.pub, 
        imagen : null, 
        fecha_pub : datetime 
       }; 

       function loadSelect(id) { 

        var resultado = {}; 
        db.query('SELECT publicaciones.publicacion, publicaciones.fecha_pub, users.nombre AS nombre, users.image AS image FROM publicaciones JOIN users ON publicaciones.id_user = users.id where id_publicacion=' + id, function(err, rows, fields){ 


         socket.emit('do-publication', { 
          nombre: rows[0].nombre, 
          publicacion: rows[0].publicacion, 
          fecha: rows[0].fecha_pub, 
          image: rows[0].image 
         }); 
        }); 
       } 

       db.query('INSERT INTO publicaciones SET ?', publicacion, function(err, rows, fields){ 
        if(err) throw err; 
        //db.end(); 
        datos_pub = rows.insertId; 
        loadSelect(datos_pub); 

       }); 
      }); 

     }else{ 

       res.render('users/signin',{ 
        isAuthenticated : req.isAuthenticated(), 
        user : req.user, 
        publicacion : req.publicacion, 
        messages : req.flash('info') 
       }); 
     } 
    } 
} 

JQuery Script (Client-Seite)

$(document).ready(function(){ 

    var socket = io.connect('http://localhost:8081', {transports: ['websocket'], upgrade: false}); 

    socket.on('do-publication', function(data){ 
    console.log(data.image); 
    var imageprofile = "http://localhost:3000/images/upload_images/"+data.image; 
    var $items = $('<div id="card-container" class="grid-item"><div class="card"><img class="avatar" src="'+imageprofile+'"><div class="name">'+data.nombre+'</div><div class="date">'+data.fecha+ '</div><p class="card">'+data.publicacion+'</p></div></div>'); 
    $grid.prepend($items) 
    .masonry('prepended', $items); 
    }) 

    socket.on('users-connected', function(data){ 
    console.log('Usuarios conectados: ' + data); 
    }) 

    $('#Button-Post-Publication').click(function(e){ 
    e.preventDefault(); 
    var publication = $('#Text-Area-Publication').val();  
    socket.emit('new-publication', {pub: publication}) 


    }) 
}) 

Aktualisiert mit Pass- und Middleware

Passport.js

var LocalStrategy = require('passport-local').Strategy; 
var mysql= require('mysql'); 
var bcrypt = require('bcryptjs'); 

module.exports = function(passport){ 

    passport.serializeUser(function(user, done){ 
     done(null, user); 
    }); 

    passport.deserializeUser(function(obj,done){ 
     done(null,obj); 
    }); 

    passport.use(new LocalStrategy({ 
     passReqToCallback: true 

    }, function(req,email,password,done){ 

     var config = require('.././database/config'); 

     var db = mysql.createConnection(config); 
     db.connect(); 

     db.query('SELECT * FROM users WHERE email = ?',email, function(err,rows,fields){ 
      if(err) throw err; 
      db.end(); 
      if(rows.length > 0){ 

       var user = rows[0]; 
       if (bcrypt.compareSync(password,user.password)) { 
        return done (null,{ 
         id: user.id, 
         nombre: user.nombre, 
         email: user.email, 
         image : user.image 
        }); 
       } 
      } 

      return done(null,false, req.flash('authmessage','Email o Password incorrecto')); 
     }); 


    } 
    )); 

}; 

Middleware

module.exports ={ 
    isLogged:function(req,res,next){ 
     // si esta autentificado continua en caso contrario ira a la página de registro 
     if(req.isAuthenticated()){ 
      next(); 
     }else{ 
      res.redirect('/'); 
     } 
    } 
} 

Antwort

0

Eine Aktualisierung der Seite tötet die Socket-Verbindung und ein neues erstellt. Dies geschieht bei Netzwerkausfällen oder anderen Problemen, die die Verbindung unterbrechen.

+0

Vielen Dank für Ihre Antwort. Ja, aber ich kann nicht verstehen, warum, wenn der Socket disconnected ist, die Informationen mehrere Male gesendet werden, wenn ich die Seite aktualisiere und eine neue Nachricht sende. –

0

Sie zeigen nicht genug von Ihrem Code, um den gesamten Fluss zu folgen, aber es sieht für mich aus, als ob Sie möglicherweise doppelte Ereignishandler für die do-it Nachricht in Ihrer controllers.js-Datei haben.

Jedes Mal, wenn die .index() Methode in controllers.js mit einem authentifizierten Anforderung aufgerufen wird, werden Sie einen anderen Ereignishandler für die do-it Nachricht in dieser Codezeile hinzu:

socket.on('do-it', function(data){...}); 

, die Sie verarbeiten verursachen wird, dass Nachricht mehrmals, jedes Mal, wenn es ankommt, was zu doppelten Datenbankeinfügungen führt. So

, Sie sind nicht eigentlich immer doppelte Nachrichten, die Sie gerade die Nachricht bekommen, wenn für einen bestimmten Teil der Daten, wie beabsichtigt, aber Sie haben doppelte Event-Handler installiert, die jeweils die Nachricht verarbeitet.

Üblicherweise ist die Antwort auf ein Problem wie dieses ist die Event-Handler aus dem Code bewegen, die mehr als einmal passiert, so dass die Event-Handler werden immer nur einmal während der Code Initialisierung hinzugefügt. Es sieht nicht so aus, als könnten Sie das hier tun, weil Sie auch versuchen, req im selben Code zu verwenden. Ich müsste einen größeren Code-Kontext für Controller sehen.js zu verstehen, was Sie eigentlich tun wollen und was eine gute Lösung wäre.

FYI, was Sie hier getan haben, ist gemischte Socket Event Handler mit http Event Handler (setzen Sie einen Event-Handler in den anderen Event-Handler). Das funktioniert so gut wie nie, da die beiden Ereignisse zu unterschiedlichen Zeiten auftreten und Sie mit doppelten Handlern enden.

+0

Danke für Ihre Antwort. Das Problem, das ich habe, ist, weil alle Handler mit meiner Authentifizierungsmethode verbunden sind? –

+0

@EbenizerPinedo - Nun, das Problem ist, dass Sie doppelte Event-Handler erstellen. Dies liegt daran, dass Sie die Ereignisbehandlungsroutinen (in Code, der mehrmals aufgerufen werden kann) initialisiert haben, der mit Ihrer Authentifizierung in Zusammenhang zu stehen scheint. – jfriend00

+0

Ja Ich habe ein Authentifizierungssystem in meiner App. Was würdest du mir empfehlen, das zu beheben? Ich bin ein Anfänger mit socket.io. –

Verwandte Themen