带有socket.io和postgres LISTEN的NodeJS



每当postgres数据库上的某个表发生更改时,我都试图让前端监视事件。

Postgres事件完美启动,我可以通过Socker.io连接将它们中继到,但我遇到了可靠性问题。我的服务器上出现了(node:26) UnhandledPromiseRejectionWarning: Error: Client was closed and is not queryable错误,Socket通常不会发出和捕获事件。我想这与我连接Socket/db客户端的方式有关。

pg配置:

const {Pool} = require('pg');
const production = process.env.NODE_ENV === 'production';
const connectionString = `postgresql://${process.env.DB_USER}:${process.env.DB_PASSWORD}@${process.env.DB_HOST}:${process.env.DB_PORT}/${process.env.DB_DATABASE}`
const pool = new Pool({
connectionString: process.env.CONNECTION_STRING ? process.env.CONNECTION_STRING : connectionString,
ssl: production,
connectionTimeoutMillis : 5000,
idleTimeoutMillis : 30000
});

index.js

io.of("/marketDetails").on('connect', (socket) => {
pool.connect((err, client, release) => {
if (err) { 
console.log(err);
return;
}

client.query('LISTEN update_table');

client.on('notification', async(data) => {
console.log("notified of table change")
handleDBEvent(socket, data);
})
socket.on("disconnect", () => {
client.query('UNLISTEN update_table');
})

release();
})
});

我收到了某些表格更改的通知,但非常不一致。

在发生任何通知之前,您将立即对所获取的数据库客户端执行release操作,并且每次套接字断开连接时都会收到错误消息,并且您尝试在30秒后关闭连接的已发布客户端上运行UNLISTEN命令。

相反,使用

socket.on("disconnect", async () => {
try {
await client.query('UNLISTEN update_table');
} finally {
release();
}
});

顺便说一句,我建议不要为每个socket.io客户端获取新的数据库连接,因为数据库太有价值了。相反,为您的应用程序创建一个客户端(您甚至可能不需要池(,让它侦听update_table事件(可能仅在连接了套接字时(,然后将每个事件广播到所有当前连接的套接字。

最新更新