我在node.js的server.js文件中有这段代码:
var app = require('http').createServer(handler), io = require('socket.io').listen(app);
var xml2js = require('xml2js'), parser = new xml2js.Parser(), fs = require('fs');
// creating the server ( localhost:8000 )
app.listen(8000);
/**
* Esta función es la que envía el archivo js necesario para la comunicación
* push con sockets
*
* @param req
* @param res
*/
function handler(req, res) {
Request = require('url').parse(req.url, true);
site = Request.query.site;
entity = Request.query.entity;
id = Request.query.id;
fs.readFile(__dirname + '/client.js', 'utf8', function(err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('Error loading client.js');
}
var dataString = data.toString();
dataString = dataString.replace('confSite', site);
dataString = dataString.replace('confEntity', entity);
dataString = dataString.replace('confId', id);
res.writeHead(200, {
'Content-Type' : 'text/javascript;charset=UTF-8'
});
res.end(dataString);
});
};
var listeners = {};
var parsers = {};
var listenersAndSockets = {};
var socketsOnListeners = {};
var watchers = {};
/**
* Esta función es la que enviará la información que se actualice a los
* clientes. Escuchará un archivo xml el cual envará al cliente una vez que este
* haya cambiado
*/
io.sockets.on('connection', function(socket) {
socket.on ('connect', function() {
console.log('conectado');
});
socket.on('setup', function(config) {
console.log('setup');
var site = config.site;
var entity = config.entity;
var id = config.id;
var listenerName = '' + site + entity + id + '';
watchers[listenerName] = site + '/' + '/' + entity + '/' + id + '.xml';
socketsOnListeners[socket.id] = listenerName;
if (typeof socketsOnListeners[listenerName] == 'undefined') {
socketsOnListeners[listenerName] = {};
}
socketsOnListeners[listenerName][socket.id] = socket.id;
if (typeof listeners[listenerName] == 'undefined') {
parsers[listenerName] = new xml2js.Parser();
fs.stat(watchers[listenerName], function(err, stats) {
if (err) {
fs.writeFile(watchers[listenerName], '');
}
});
listeners[listenerName] = function(curr, prev) {
fs.readFile(watchers[listenerName], function(err, data) {
parsers[listenerName].parseString(data);
});
};
fs.watch(watchers[listenerName], listeners[listenerName]);
}
parsers[listenerName].addListener('end', function(result,a) {
socket.volatile.emit('notification', result);
});
});
socket.on('disconnect', function() {
delete socketsOnListeners[socketsOnListeners[socket.id]][socket.id];
if (socketsOnListeners[socketsOnListeners[socket.id]].lenght == 0) {
fs.unwatch(watchers[socketsOnListeners[socket.id]]);
delete watchers[socketsOnListeners[socket.id]];
}
delete socketsOnListeners[socket.id];
});
});
在我的test.html中,我有这个:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Prueba de Push</title>
</head>
<body>
<div id="div1">Este es un texto de prueba</div>
<script src="http://10.0.0.113:8000/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://10.0.0.113:8000/?site=levelup&entity=noticia&id=1"></script>
<script>
function test(data) {
console.log(data);
jQuery('#' + data.id).html(data.content);
}
</script>
</body>
</html>
Client.js是这样的:
var socket = io.connect('http://10.0.0.113:8000');
var config = {
site : 'confSite',
entity : 'confEntity',
id : 'confId'
};
socket.emit("setup", config);
socket.on('reconnect', function() {
socket.emit("setup", config);
});
// on every message recived we print the new datas inside the #container div
socket.on('notification', function(data) {
_efbn(data.callback, window, data.response, data);
});
/**
* Función que ejecuta una función por nombre. Puede usar namespaces
* (algo.algo.algo.funct)
*
* @see http://stackoverflow.com/questions/359788/javascript-function-name-as-a-string/359910#359910
*/
function _efbn(functionName, context) {
var args = Array.prototype.slice.call(arguments);
args = [ args[2], args[3] ]; // Fix para IE.
var namespaces = functionName.split(".");
var func = namespaces.pop();
for ( var i = 0; i < namespaces.length; i++) {
context = context[namespaces[i]];
}
try {
if (typeof context[func] == 'function') {
return context[func].apply(this, args);
}
} catch (e) {
console.log(e);
}
return null;
}
在firefox中,当我修改服务器上的文件时,我收到两次或更多通知。有什么方法可以防止这种情况吗?我在node.js上读过一些关于群组的内容......这会对我有帮助吗?
答案 0 :(得分:2)
您开始在setup
事件中观看文件。在客户端setup
可能会多次发生事件(reconnect
事件)。对于每个watch
调用,新的侦听器将添加到文件中。在设置之前,您需要检查文件中是否存在watch
侦听器(对于此套接字)。在关闭套接字后,您还需要unwatch
文件。否则你会得到内存泄漏。
<强>更新强>
您还需要移动
parser.addListener('end', function(result) {
socket.volatile.emit('notification', result);
});
在setup
事件之外。