Socket.io connect event not firing

2019-09-13 10:55发布

问题:

This is my first time working with node.js/socket.io and I'm having a little trouble with the 'connect' event firing for all sockets. I followed the chat application example and then tried to add a feature where instead of displaying in the console when a user connects or disconnects, I would display it on-screen.

The disconnect event is firing for all tabs (if I have multiple tabs open to the chat application), but the connect event only seems to fire for the current tab.

Server (index.js)

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

app.get('/', function(req, res){
    res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
    socket.on('connect', function(){
        io.emit('connect', "A user connected");
    });
    socket.on('disconnect', function(){
        io.emit('disconnect', "A user disconnected");
    });
    socket.on('chat message', function(msg){
        io.emit('chat message', msg);
    });
});

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

Client (index.html)

<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
    var socket = io();
    $('form').submit(function(){
        socket.emit('chat message', $('#m').val());
        $('#m').val('');
        return false;
    });
    socket.on('chat message', function(msg){
       $('#messages').append($('<li>').text(msg));
    });
    socket.on('disconnect', function(msg){
       $('#users').text(msg);
    });
    socket.on('connect', function(msg){
       $('#users').text(msg);
    });
</script>

回答1:

You can try this, it may work:

server:

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

app.get('/', function(req, res){
    res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){

    io.emit('new user', "A user connected");  

    socket.on('disconnect', function(){
        io.emit('disconnect', "A user disconnected");
    });

    socket.on('chat message', function(msg){
        io.emit('chat message', msg);
    });
});

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

client:

<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
    var socket = io();
    $('form').submit(function(){
        socket.emit('chat message', $('#m').val());
        $('#m').val('');
        return false;
    });
    socket.on('connect', function() {
      $('#users').text('I am connected!');
    });
    socket.on('chat message', function(msg){
       $('#messages').append($('<li>').text(msg));
    });
    socket.on('disconnect', function(msg){
       $('#users').text(msg);
    });
    socket.on('new user', function(msg){
       $('#users').text(msg);
    });
</script>


回答2:

There are two problems I can see with your code.

One is you don't need a socket "on connect" function. You can just put your code in the io "on connection", and it will fire when the user connects.

io.on("connection", function (socket) {
  // Do connect stuff here
})

The other is that in your socket disconnect function, you emit disconnect which is could cause problems because it shares the name with other functions. Do something like this instead:

//Server:
io.on('connection', function(socket){

    io.emit('set users', "A user connected");  

    socket.on('disconnect', function(){
        io.emit('set users', "A user disconnected");
    });

    socket.on('chat message', function(msg){
        io.emit('chat message', msg);
    });
});

//Client:
var socket = io();
$('form').submit(function(){
    socket.emit('chat message', $('#m').val());
    $('#m').val('');
    return false;
  });

socket.on('chat message', function(msg){
    $('#messages').append($('<li>').text(msg));
  });

//You only need one function to set "#users"
socket.on('set users', function(msg){
    $('#users').text(msg); //this will set the text in #users
  });