我想知道是否有人可以帮助弄清楚我做错了什么:
我的客户端网页启动与我的服务器的连接,并侦听一个长时间运行的进程,该进程的状态在另一个线程上由工作进程在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();
});
});
});
});
});
答案 0 :(得分:2)
虽然不清楚如何帮助您,但我可以告诉你代码中发生了什么:
app.post('/api/users', function (req, res) {
// some code
io.sockets.on('connection', function (socket) {
// some code
});
});
每当用户向/api/users
发送一些内容时,就会附加一个新的处理程序<{1}}(这就是io.sockets
所做的事情)。但是这些处理程序永远不会被删除,因此每次建立新连接所有附加处理程序时都会触发。这就是你广播的来源。
您必须将.on
与app.post(...)
分开(它们应该是独立的,都在模块级别定义,而不是嵌套)。我确信这不容易(例如,您可能需要对用户进行两次身份验证),但这是唯一合理的方法。
答案 1 :(得分:-1)
您不应将io.sockets.on('connection', function (socket)
放在app.post
范围内。
只需把它放在外面再试一次,它可能会正常工作。
在服务器启动时,应该只听一次连接,而不是每次客户端访问某个URL时都是如此。