I'm working in a real-time app, and I'm using Socket.io to get this feature.
What I have so far is, when a user post something (text), my sockets server receive this message and then it sends to my controller to save this data on a DB (MySQL). Then the same message is returned to the client through the same socket server.
Actually this works well, but when I refresh my browser and post a new message, the data is inserted twice in the database, so I receive the same two messages in my client. This happens everytime that I refresh the page, so if I've refreshed the page 10 times, I will insert 10 messages with the same data on my DB.
This is the code I have right now, any help would be great.
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 Side)
$(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})
})
})
Updated with Passport and 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('/');
}
}
}