Socket.io向节点/快递应用程序中的每个人广播所有内容

时间:2013-08-06 03:48:29

标签: node.js socket.io

我想知道是否有人可以帮助弄清楚我做错了什么:

我的客户端网页启动与我的服务器的连接,并侦听一个长时间运行的进程,该进程的状态在另一个线程上由工作进程在db中更新,并将更新发送回浏览器。我在app.post()方法中定义了一个socket.io连接。这由下面的poll()函数处理(向下滚动一点,超过邀请检查代码)

但是,当新的Web客户端连接时,它的消息会被添加到以前的客户端,就好像只有一个通道一样。为什么每个浏览器都没有单独的唯一通道?

//Create server
var express = require('express'),
    app = express(),
    http = require('http'),
    server = http.createServer(app),
    io = require('socket.io').listen(server);

io.set('log level', 1); // reduce logging
io.configure(function () {
    io.set("transports", ["xhr-polling"]);
    io.set("polling duration", 10);
});

app.post('/api/users', function (req, res) {
    if (!req.body.auth.accessToken) {
        req.body.auth.accessToken = req.body.auth.authResponse.accessToken;
    } //fb return object is different depending on whether it is a first login or subsequent
    logger.log('debug', '/api/users:POST', req.body);
    io.sockets.on('connection', function (socket) {
        socket = socket;
        socket.emit('update', {
            status: 200 //send initialization ping
        });


        //check if user has valid invite, if not try to invite
        db.getTotalUserInvites(function (err_inv, res_total) {

            db.getUserInvite(req.body.fid, function (err_check, res_check) {
                logger.log('debug', 'Total invites issued=' + res_total);

                    //process report - all we need is accesToken, processReport will do the rest
                    mine_fb.processUser(req.body.auth.accessToken, socket, function (User,socket) { //pass channel properly
                        db.getReportStatus(User.fid,socket, function (result,socket) {
                            logger.log('debug', 'report status', result);
                            if (result) {
                                if (socket && (result.report_status == -1)) {
                                    logger.log('debug', 'report already processed. retrieving uniq_id ' + result.uniq_id);
                                    socket.emit('update', {
                                        status: -1,
                                        uniq_id: result.uniq_id
                                    });
                                    return true;
                                } else {
                                    if (socket && (result.report_status >= 0)) {
                                        logger.log('debug', 'we are in the middle of processing report ' + result.uniq_id);
                                        //in this case we become a listener and not a speaker

                                        function poll(socket) {
                                            db.getReportStatus(User.fid, socket,function (r,socket) {
                                                socket.emit('update', { //!!!! THIS EMITS TO ALL CONNECTED BROWSERS
                                                    status: r.report_status,
                                                    uniq_id: r.uniq_id
                                                }); //...socket
                                                if ((r.report_status >= 0) && (socket)) { 
                                                    logger.log('debug', 'polling...');
                                                    _.delay(poll, 2000, socket);
                                                }

                                            }); //get rerpot
                                        }; //end poll
                                        socket.on('disconnect', function () {
                                            socket=null;
                                        });
                                        poll(socket);

                                    } // else we're in the middle
                                } //done checking status
                            } //end of seq
                        });
                    return res.send();
                });
            });

        });
    });
});

2 个答案:

答案 0 :(得分:2)

虽然不清楚如何帮助您,但我可以告诉你代码中发生了什么:

app.post('/api/users', function (req, res) {
  // some code
  io.sockets.on('connection', function (socket) {
    // some code
  });
});

每当用户向/api/users 发送一些内容时,就会附加一个新的处理程序<{1}}(这就是io.sockets所做的事情)。但是这些处理程序永远不会被删除,因此每次建立新连接所有附加处理程序时都会触发。这就是你广播的来源。

您必须将.onapp.post(...)分开(它们应该是独立的,都在模块级别定义,而不是嵌套)。我确信这不容易(例如,您可能需要对用户进行两次身份验证),但这是唯一合理的方法。

答案 1 :(得分:-1)

您不应将io.sockets.on('connection', function (socket)放在app.post范围内。

只需把它放在外面再试一次,它可能会正常工作。

在服务器启动时,应该只听一次连接,而不是每次客户端访问某个URL时都是如此。