Reputation: 155
This question has already been answered, but I can't understand it at all. You can find it at this link.
socket.on calls its callback too many times
I have the same problem as this fellow. I'm attempting to make a chat program with socket.io, but when more than one user joins, each message outputs the number of times of how many users have been connected.
For example, when one user is connected, and he submits a message. It outputs once. When two users are connected, each of their messages output twice. When three users are connected, each of their messages output three times.
Here is my client side code:
$('document').ready(function() {
var server = io.connect('http://localhost:8888');
$('.chat').keydown(function(event){
var save = this;
if(event.which == 13){
server.emit('message', $(save).val());
$(save).val('');
return false;
}
});
server.on('incoming', function(message){
$('#textfield').append("<p>" + message + "</p>");
});
});
Here is my server side code:
var socket_io = require('socket.io').listen(8888).sockets;
socket_io.on('connection', function(socket){
socket.on('message', function(message){
socket_io.emit('incoming', message)
});
});
Thank you!
Upvotes: 1
Views: 2812
Reputation: 51
I also faced it, like multiple socket calls in network tab and i just add this "transports" key object to socket instance, both on client and backend.
socket = io("http://localhost:3002", {
transports: ['websocket']
})
React, Node, AWS EB
Upvotes: 0
Reputation: 155
Okay, I've finally figured out the problem.
I'm using Express 4.0. That means, I'm using routes to run the server, and I had the socket io code running inside the route. Each time a user connects, it has to go through the route first, and it's all binding onto the same socket_io.
Thanks to everybody who helped!
Upvotes: 0
Reputation: 106756
You can use socket.broadcast.emit()
to send to everyone except that socket:
var io = require('socket.io')(8888);
io.on('connection', function(socket) {
socket.on('message', function(message) {
socket.broadcast.emit('incoming', message);
});
});
UPDATE: The following example works just fine for me:
server.js
:
var app = require('http').createServer(handler);
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.on('connection', function(socket) {
socket.on('message', function(message) {
socket.broadcast.emit('incoming', message);
});
});
index.html
:
<html>
<head>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
$('document').ready(function() {
var server = io.connect('http://localhost');
$('.chat').keydown(function(event) {
if (event.which == 13) {
var $save = $(this);
server.emit('message', $save.val());
$save.val('');
return false;
}
});
server.on('incoming', function(message){
$('#textfield').append("<p>" + message + "</p>");
});
});
</script>
</head>
<body>
<input type="text" class="chat">
<div id="textfield"></div>
</body>
</html>
When pressing enter, the message in the input box is only displayed once to all other connected socket.io users.
Upvotes: 1