我的socket.io实现遇到问题,不知道如何解决。我在LISTEN中使用pg_notify,因此在数据库中修改某个值时,它将向某个客户端发出“ is_logged_in”。
本身运行良好-我的问题是当我刷新页面时,socket.io断开当前的socket_id,照常创建一个新的socket_id,但是发生这种情况时,它正在创建第二个pgsql客户端实例并复制请求-触发“ logged_in”事件2x。
如果我再次刷新页面,然后手动触发pg“ logged_in”触发器,则它将发出3次,等等。我有泄漏。
const io = require('socket.io')();
const pg = require('pg');
io.on('connection', (socket) => {
const pgsql = new pg.Client({
(host, port, user, pass, db)
})
pgsql.connect()
pgsql.query("LISTEN logged_in");
pgsql.on('notification', function (data) {
socket.to(json.socket_id).emit('is_logged_in', { status:'Y' });
});
socket.on('disconnect', () => {
//pgsql.end();
});
});
我试图杀死pgsql实例(在socket.on断开连接中),但是由于某些原因,当我这样做时LISTEN停止工作。
我也尝试将新的pg.Client移到io.on连接之外,但是当我刷新页面时,旧的socket_id断开连接,新的socket_id连接,并且它从不执行代码来重新创建pg客户端。
有什么想法吗?
答案 0 :(得分:2)
这些可能会造成问题:
pgsql
实例是在每个套接字连接请求上创建的,并且在断开连接时不会被破坏notification
处理程序不会在断开连接时被删除我对postgres不太熟悉,但是我在socket方面做了大量的工作。因此,类似这样的方法应该可以解决您的问题:
const io = require('socket.io')();
const pg = require('pg');
const pgsql = new pg.Client({
(host, port, user, pass, db)
})
pgsql.connect();
io.on('connection', (socket) => {
pgsql.query("LISTEN logged_in");
const handler = function (data) {
socket.to(json.socket_id).emit('is_logged_in', { status:'Y' });
// You could also do pgsql.off('notification', handler) here probably
// or check if pgsql.once method is available as we need to call this handler only once?
}
pgsql.on('notification', handler);
socket.on('disconnect', () => {
pgsql.off('notification', handler);
//pgsql.end(); // Call it in server termination logic
});
});