带有 socket.io 和 postgres LISTEN 的 NodeJS
NodeJS with socket.io and postgres LISTEN
我试图让我的前端在我的 postgres 数据库上的某个 table 发生更改时监视事件。
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();
})
});
我收到有关某些 table 更改的通知,但非常不一致。
在任何通知发生之前,您立即 release
访问您获得的数据库客户端,并且每次套接字断开连接时您都会收到错误消息,并且您尝试 运行 UNLISTEN
在 30 秒后连接关闭的已释放客户端上的命令。
改为使用
socket.on("disconnect", async () => {
try {
await client.query('UNLISTEN update_table');
} finally {
release();
}
});
顺便说一句,我建议不要为每个 socket.io 客户端获取一个新的数据库连接,数据库对它来说太有价值了。相反,为您的应用程序创建一个客户端(您甚至可能不需要池),让它监听 update_table
事件(可能仅当套接字连接时),然后 broadcast 每个事件都currently-connected 个插座。
我试图让我的前端在我的 postgres 数据库上的某个 table 发生更改时监视事件。
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();
})
});
我收到有关某些 table 更改的通知,但非常不一致。
在任何通知发生之前,您立即 release
访问您获得的数据库客户端,并且每次套接字断开连接时您都会收到错误消息,并且您尝试 运行 UNLISTEN
在 30 秒后连接关闭的已释放客户端上的命令。
改为使用
socket.on("disconnect", async () => {
try {
await client.query('UNLISTEN update_table');
} finally {
release();
}
});
顺便说一句,我建议不要为每个 socket.io 客户端获取一个新的数据库连接,数据库对它来说太有价值了。相反,为您的应用程序创建一个客户端(您甚至可能不需要池),让它监听 update_table
事件(可能仅当套接字连接时),然后 broadcast 每个事件都currently-connected 个插座。