I'm currently developing an instant messaging application but I have an issue saving the users that log into the server. I know that I have to store the socket resource of the connection event of each user that connects, however I can't have all those resources available when I access the server on different browsers.
The problem
here's part of the server:
//..
//..
var users = {};
io.sockets.on('connection', function (socket) {
users[req.session.name] = socket;
socket.on('msgToServer', function (data) {
users[data['to']].emit('msgFromServer',{message:data['message'],to:data['from'],from:data['to']});
});
});
when I send a message from one browser who uses one session to another who uses an another one.. the code breaks:
C:\Archivos de programa\nodejs\session\data_handler.js:142
users[data['to']].emit('msgFromServer',{message:data['message'],to:data['from
^
TypeError: Cannot call method 'emit' of undefined at Socket.<anonymous> (C:\Archivos de programa\nodejs\session\data_handler.js:142:20)
because If I log in with one account(like charlie), the server holds
var users = {};
io.sockets.on('connection', function (socket) {
users['charlie'] = socket; <-- charlie's socket resource
users['charlie'] is available if I send a message from the browser that charlie logged in ... only, so like if charlie only can send messages to himself because there are no more socket resources in the user object, so when I try to send a message to the pedros's account, for instance... that resource is not available(undefined) and the server throws that error. What I need is a means of having all users that log in from one user agent... in a container,not necessarily an object, in this case : users. So data['to'] would not be undefined and msgFromServer events could be sent arbitrarily to users:
server
var express = require('express');
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);
app.use(express.static( __dirname));
app.use(express.bodyParser());
app.use(express.cookieParser());
var MemcachedStore = require('connect-memcached')(express);
app.use(express.session({
secret: 'lolz',
store:new MemcachedStore
}));
var connection = function(){
var mysql = require('mysql');
var mysql = mysql.createConnection({
host: 'localhost',
port: 3306,
user: 'root',
password: '',
});
mysql.query('use test');
return mysql;
};
app.post('/data', function(req, res){
var username = req.body.username;
var password = req.body.password;
var mysql = connection();
mysql.query("select username from user where username like '"+ username +"' and password like '"+password +"'",
function(err, result, fields) {
if (err) throw err;
else {
if(result != ''){
req.session.name = username;
mysql.query("update user set online = 1 where id like '"+req.session.name+"' ");
res.redirect("/welcome_user");
}
else{
res.end("You are not registered");
}
}
});
});
app.get("/welcome_user",function(req,res){
var html = '<html>\n'+
'<head>\n'+
'<link rel="stylesheet" type="text/css" href="styles/jquery-ui-1.8.18.custom.css">\n'+
'<link rel="stylesheet" type="text/css" href="styles/styles.css">\n'+
'<style> \n #onlineUsers{border: 1px solid black; width: 300px;}</style>\n'+
'<script src="http://127.0.0.1/socket.io/lib/socket.io.js"></script>\n'+
'<script src="scripts/jquery.js"></script>\n'+
'<script type="text/javascript" src="scripts/jquery-ui-1.8.18.custom.min.js"></script>\n'+
'<script src="scripts/chatbox.js"></script>\n'+
'<script src="scripts/send.js"></script>\n'+
'<script>\n'+
"//receive();\n"+
'$(function(){\n'+
'$("#onlineUsers li").dblclick( function(event){\n '+"createChatbox($.trim($(this).text()), '"+req.session.name+"','');\n"+
'} );'+
'});'+
'</script>\n'+
'</head>\n'+
'<body>\n'+
'<h1>Hola '+req.session.name+'. Estos son los usuarios en linea </h1> \n'+'<div id="onlineUsers"><ol>\n';
mysql = connection();
mysql.query("select username from user where online = 1 and username != '"+req.session.name+"' ",
function(err, results, fields) {
if (err) throw err;
for (var index in results) {
html += '<li>' + results[index].username + '</li>';
}
html +='</ol></div> \n'+
'</body>\n'+
'</html>';
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(html);
}
);
var users = {};
io.sockets.on('connection', function (socket) {
users[req.session.name] = socket;
socket.on('msgToServer', function (data) {
for (var u in users){
console.log("%s | %s",u,users[u]);
/*
this is how I determine that the user that logged in
is not available in the user object
*/
}
users[data['to']].emit('msgFromServer' {message:data['message'],to:data['from'],from:data['to']});
});
});
});
server.listen(80);
client:
function createChatbox(to,from,message){
$('<div id ="chatbox" class='+to+'> <div id="messageOutput" > <textarea class="readOnly" readonly="readonly" rows="4" cols="30"></textarea></div><br /> <hr /> <div id="messageInput"> <textarea class ="editable" rows="2" cols="30"> </textarea> </div> </div>').appendTo("body").dialog({draggable:true, title:to}) ;
if(message !='')
$('#chatbox.'+to+' #messageOutput textarea.readOnly').text(message);
$("textarea.editable").keydown(function(event){
if(event.which == 13 && $(this).val() != ''){
send(to,from,$.trim($(this).val()));
$(this).val('');
return false;
}
});
}
var socket = io.connect('http://localhost');
function send(to, from, message){
socket.emit('msgToServer',{message:message,to:to,from:from});
}
socket.on('msgFromServer', function (data) {
message = data['message'],
from = data['from'],
to = data['to'];
if($('#chatbox.'+from).dialog("isOpen") === true){
$('#chatbox.'+from+' #messageOutput textarea.readOnly').text(message);
}
else if(($('#chatbox.'+from).dialog("isOpen") !== true)){
createChatbox(from,to,message);
}
});