I'm working with Socket.IO, and I've found a big problem. I'm trying to make a real-time chat: an user log in, select another user connected and talk, so(...)
var http = require('http'),
fs = require('fs'),
path = require('path'),
io,
server;
var PORT = 3000,
HOST = '127.0.0.1';
server = http.createServer( function ( request, response ) {
var filePath = '.' + request.url,
extName,
contentType;
if (filePath == './') {
filePath = './index.html';
}
extName = path.extname(filePath);
contentType = 'text/html';
switch ( extName ) {
case '.js':
contentType = 'text/javascript';
break;
case '.css':
contentType = 'text/css';
break;
}
fs.exists( filePath, function ( exists ) {
if ( exists ) {
fs.readFile( filePath, function ( error, content ) {
if ( error ) {
response.writeHead( 500 );
response.end();
}
else {
response.writeHead( 200, { 'Content-Type': contentType });
response.end( content, 'utf-8' );
}
});
}
else {
response.writeHead( 404 );
response.end();
}
});
}).listen( PORT, HOST );
io = require('socket.io').listen( server );
var Users = [ ]; // List of users
io.sockets.on('connection', function ( socket ) {
var user = { }; // The user
socket.on('newUser', function ( data ) {
user.userName = data.name, // Selected name
user.userId = socket.id; // The socket id
Users.push( user );
socket.emit('me', user); // Emit the user object
socket.emit('userList', { users : Users }); // Emit the user list
});
socket.on('disconnect', function () {
Users.remove( user ); // Delete from the user list
socket.emit('userList', { users : Users }); // emit again the user list for refresh
});
socket.on('clientMessage', function ( data ) {
io.sockets.socket(data.to).emit('newMessage', {
// data.to is the socket ID that a message is sent
"from" : data.from,
"message" : data.message,
"date" : new Date()
});
});
});
Here's the problem; some user connects, the server assigns an id, (the socket.id), but if the same user open more tabs in the same navigator, the socket.id will change, so that user will not receive that message in the other tabs.
I want to store the same socket.id for all tabs that some logged user opens; so, if that user receive any message, will be displayed in all the tabs.
¿Solutions?
The only way you can do that is to make an array of all socketID's of each user and send to all of them if there is a specific message to that user ... I've had a similar problem and that's the solution I've used
socket.on('newUser', function ( data ) {
user.userName = data.name, // Selected name
if ( !user.userId ) user.userId = {};
user.userId.push(socket.id);
Users.push( user );
socket.emit('me', user); // Emit the user object
socket.emit('userList', { users : Users }); // Emit the user list
});
socket.on('disconnect', function () {
Users.userId.remove( socket.id );
if ( Users.userId.length === 0 ) Users.remove(user);
socket.emit('userList', { users : Users }); // emit again the user list for refresh
});
socket.on('clientMessage', function ( data ) {
io.sockets.socket(data.to).emit('newMessage', {
// data.to is the socket ID that a message is sent
"from" : data.from,
"message" : data.message,
"date" : new Date()
});
});
});
I haven't run the code. It's actually for an idea how to deal with the multiple socket connections. You can always write that in more elegant way!