nodejs 和 socket io 同步问题

nodejs and socket io sync issues

我是 nodejs 和 socket io 的新手,但我真的很想了解它是如何工作的。我已经完成了来自 socket io 网站的 "chat tutorial"。但是,我正在尝试在这里做一些事情 "new"。每次建立新连接时,我想通过附加一个带有随机数的新选项卡向所有客户端广播一个事件。但是,唯一发生的事情是它附加一次(在我自己的连接上)但没有附加到其他人?这是不可能的,还是我做错了?

服务器,

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

app.use("/assets/stylesheets", express.static(__dirname + '/assets/stylesheets'));
app.use("/assets/javascripts", express.static(__dirname + '/assets/javascripts'));
app.use("/assets/demo/avatars", express.static(__dirname + '/assets/demo/avatars'));
app.use("/assets/fonts/font-awesome/", express.static(__dirname + '/assets/fonts/font-awesome/'));

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

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

    socket.on('new user', function(username) {
        socket.emit('new connection', { nickname: username });
        console.log('new connection ' + username);
    });

});

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

客户,

<script type="text/javascript">

    var randomNumber = Math.floor((Math.random() * 10) + 1);

    var socket = io();

    socket.on('connect', function() {
        socket.emit('new user', randomNumber);
    });

    socket.on('new connection', function(data) {
        var nickname = data.nickname;
        $('<li class="active"> <a href="#' + nickname + '" data-toggle="tab">' + nickname + '<span class="label label-success">12</span></a> </li>').appendTo("#uidemo-tabs-default-demo");
    });

</script>

您必须使用 socket.broadcast.emit 进行广播..

socket.on('new user', function(username) {
    socket.broadcast.emit('new connection', { nickname: username });
    console.log('new connection ' + username);
});

但是,这不会将消息发送到您自己的连接,而是发送到所有其他连接。如果您想将消息发送给包括您自己在内的所有连接,

socket.on('new user', function(username) {
    socket.emit('new connection', { nickname: username });
    socket.broadcast.emit('new connection', { nickname: username });
    console.log('new connection ' + username);
});

您需要保留服务器上所有打开的连接的列表,然后在出现新连接时向所有其他连接发送消息。

修改后的代码

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

app.use("/assets/stylesheets", express.static(__dirname + '/assets/stylesheets'));
app.use("/assets/javascripts", express.static(__dirname + '/assets/javascripts'));
app.use("/assets/demo/avatars", express.static(__dirname + '/assets/demo/avatars'));
app.use("/assets/fonts/font-awesome/", express.static(__dirname + '/assets/fonts/font-awesome/'));

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

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

    socket.on('new user', function(username) {
        connections.forEach(function (socket) {
            try {
                socket.emit('new connection', { nickname: username });
            } catch (err) {
                console.log('connection probably closed: ', err);
            }
        });
        console.log('new connection ' + username);
        connections.push(socket);
    });

});

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

但是,请注意,这仅在您的 Node.js 服务器只有一个实例(即您没有使用 cluster 模块)时才有效,需要做更多的工作才能将其连接到在集群中工作,如果它必须在冗余基础设施中工作,甚至更多。