DareDev1l DareDev1l - 3 days ago 4
Javascript Question

socket.io send message twice

I am trying to create realtime chat in my SPA app. I got the chat working , but when I move to another page and head back to the chat page , it starts loading messages twice. Here is my server side for socket.io:

var io = require('socket.io').listen(app.listen(config.port));
io.sockets.on('connection', function (socket) {
socket.emit('message', { message: 'You are chatting now !' });
socket.on('send', function (data) {
io.sockets.emit('message', data);
});


I tried using io.sockets.once instead of io.sockets.on but it doesn't show chat 2nd time ..

And here is my client side together with html (jade template engine):

#content(style='width: 500px; height: 300px; margin: 0 0 20px 0; border: solid 1px #999; overflow-y: scroll;')
input#field(style='width:350px;')
input#send(type='button', value='send')
script(src='/socket.io/socket.io.js')
script.
$("#field").keyup(function(e) {
if(e.keyCode == 13) {
sendMessage();
}
});
var messages = [];
var socket = io.connect('localhost:3030/#/chat');
var field = document.getElementById("field");
var sendButton = document.getElementById("send");
var content = document.getElementById("content");
socket.on('message', function (data) {
if(data.message) {
messages.push(data.message);
var html = '';
for(var i=0; i<messages.length; i++) {
html += messages[i] + '<br />';

}
content.innerHTML = html;
content.scrollTop = content.scrollHeight;
} else {
console.log("There is a problem:", data);
}
});
sendButton.onclick = sendMessage = function() {
var text = field.value;
socket.emit('send', { message: text });
field.value = '';
};


I want to fix this , so when I go back 2nd time it doesnt show 2 times , or for 3rd time to show it 3 times and so on ... Help is greatly appreciated :)

Answer

If I understand correctly, you want correct persistence between page refreshes, just add an array on the server to collect the messages and tell new connections all about them.

I really just use the docs to accomplish my goals (link for reference http://socket.io/docs/server-api/)

for the code below to run, it is necessary to do these commands in the working directory

npm install express
npm install socket.io

(server code)

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

//serve up the file, the code for this is below, I translated your jade to html
app.get('/', function(req, res){
  res.sendfile('index.html');
});

//note this will get big eventually with lots of users
var message_past = [];

io.on('connection', function(socket){
  socket.emit('server-message', { message: 'Welcome !' });
  // tell user recent posts
  for (var i = 0; i < 20 && !!message_past[i] ; i ++) socket.emit('user-message',message_past[i]);

  // save the message and update everyone with it
  socket.on('user-message', function (data) {
        message_past.push(data);
        // io.emit will tell everyone <-- I think what you want
        // socket.broadcast.emit will tell everyone but this socket
        // socket.emit will tell just this socket
        io.emit('user-message', data);
  });

});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

and the client code

<input id='field' type="text" style='width:350px;'/>
<input id='send' type='button' value='send'/>
<div id='content' style='width: 500px; height: 300px; margin: 0 0 20px 0; border: solid 1px #999; overflow-y: scroll;'>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src='/socket.io/socket.io.js' ></script>
<script type="text/javascript">
    $("#field").keyup(function(e) {
        if(e.keyCode == 13) {
            sendMessage();
        }
    });
    var socket = io.connect('localhost:3000/#/chat');
    console.log(socket)
    var field = document.getElementById("field");
    var sendButton = document.getElementById("send");
    var content = document.getElementById("content");

    var display_message = function( data ) {
        if(data.message) {
            $(content).append(data.message+'<br/>');
            content.scrollTop = content.scrollHeight;
        } else {
            console.log("There is a problem:", data);
        }
    };

   socket.on('server-message', display_message);
   socket.on('user-message', display_message);
   sendButton.onclick = sendMessage = function() {
        var text = field.value;
        socket.emit('user-message', { message: text });
        field.value = '';
    };
</script>
Comments