Note that there are some explanatory texts on larger screens.

plurals
  1. POInstant messaging in node.js and socket.io : how do I send messages to particular users?
    primarykey
    data
    text
    <p>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 <strong>socket</strong> 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.</p> <p><strong>The problem</strong></p> <p>here's part of the server:</p> <pre><code>//.. //.. 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']}); }); }); </code></pre> <p>when I send a message from one browser who uses one session to another who uses an another one.. the code breaks:</p> <pre><code>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.&lt;anonymous&gt; (C:\Archivos de programa\nodejs\session\data_handler.js:142:20) </code></pre> <p>because If I log in with one account(like charlie), the server holds </p> <pre><code>var users = {}; io.sockets.on('connection', function (socket) { users['charlie'] = socket; &lt;-- charlie's socket resource </code></pre> <p>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: </p> <p><strong>server</strong></p> <pre><code>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 = '&lt;html&gt;\n'+ '&lt;head&gt;\n'+ '&lt;link rel="stylesheet" type="text/css" href="styles/jquery-ui-1.8.18.custom.css"&gt;\n'+ '&lt;link rel="stylesheet" type="text/css" href="styles/styles.css"&gt;\n'+ '&lt;style&gt; \n #onlineUsers{border: 1px solid black; width: 300px;}&lt;/style&gt;\n'+ '&lt;script src="http://127.0.0.1/socket.io/lib/socket.io.js"&gt;&lt;/script&gt;\n'+ '&lt;script src="scripts/jquery.js"&gt;&lt;/script&gt;\n'+ '&lt;script type="text/javascript" src="scripts/jquery-ui-1.8.18.custom.min.js"&gt;&lt;/script&gt;\n'+ '&lt;script src="scripts/chatbox.js"&gt;&lt;/script&gt;\n'+ '&lt;script src="scripts/send.js"&gt;&lt;/script&gt;\n'+ '&lt;script&gt;\n'+ "//receive();\n"+ '$(function(){\n'+ '$("#onlineUsers li").dblclick( function(event){\n '+"createChatbox($.trim($(this).text()), '"+req.session.name+"','');\n"+ '} );'+ '});'+ '&lt;/script&gt;\n'+ '&lt;/head&gt;\n'+ '&lt;body&gt;\n'+ '&lt;h1&gt;Hola '+req.session.name+'. Estos son los usuarios en linea &lt;/h1&gt; \n'+'&lt;div id="onlineUsers"&gt;&lt;ol&gt;\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 += '&lt;li&gt;' + results[index].username + '&lt;/li&gt;'; } html +='&lt;/ol&gt;&lt;/div&gt; \n'+ '&lt;/body&gt;\n'+ '&lt;/html&gt;'; 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); </code></pre> <p><strong>client:</strong></p> <pre><code>function createChatbox(to,from,message){ $('&lt;div id ="chatbox" class='+to+'&gt; &lt;div id="messageOutput" &gt; &lt;textarea class="readOnly" readonly="readonly" rows="4" cols="30"&gt;&lt;/textarea&gt;&lt;/div&gt;&lt;br /&gt; &lt;hr /&gt; &lt;div id="messageInput"&gt; &lt;textarea class ="editable" rows="2" cols="30"&gt; &lt;/textarea&gt; &lt;/div&gt; &lt;/div&gt;').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 &amp;&amp; $(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); } }); </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload