You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中检测PostgreSQL表新增数据(规避Cron,Socket.io可行吗?)

在Node.js中实时检测PostgreSQL表新增数据并通过Socket.io推送

完全可以不用Cron定时任务,核心是利用PostgreSQL原生的LISTEN/NOTIFY机制实现数据库端的事件触发,再结合Node.js的PostgreSQL客户端库和Socket.io完成实时推送,以下是具体实现步骤:

1. 配置PostgreSQL的触发器与通知

首先在PostgreSQL中创建触发器,当目标表有新数据插入时,自动发送通知到指定频道:

-- 创建触发器函数:插入新数据时发送JSON格式的通知
CREATE OR REPLACE FUNCTION notify_new_record()
RETURNS TRIGGER AS $$
BEGIN
  -- 将新增行转为JSON,发送到"new_record_event"频道
  PERFORM pg_notify('new_record_event', row_to_json(NEW)::TEXT);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- 给目标表绑定触发器(示例为users表,替换为你的表名)
CREATE TRIGGER trigger_new_record
AFTER INSERT ON users
FOR EACH ROW EXECUTE FUNCTION notify_new_record();

这段SQL会在users表每次插入数据后,把新行数据以JSON形式推送到new_record_event频道。

2. Node.js端监听PostgreSQL通知

使用pg库连接数据库并监听指定频道的通知,收到通知后通过Socket.io推送给客户端:

const { Pool } = require('pg');
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

// 初始化Express和Socket.io
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
  cors: { origin: '*' } // 根据实际业务配置跨域规则
});

// PostgreSQL连接配置
const pool = new Pool({
  user: 'your_db_user',
  host: 'localhost',
  database: 'your_db_name',
  password: 'your_db_password',
  port: 5432
});

// 监听PostgreSQL通知频道
async function startPostgresListener() {
  const client = await pool.connect();
  await client.query('LISTEN new_record_event');

  // 接收数据库通知
  client.on('notification', (msg) => {
    const newRecord = JSON.parse(msg.payload);
    console.log('收到新增数据:', newRecord);
    // 通过Socket.io推送给所有连接的客户端
    io.emit('new_record', newRecord);
  });

  console.log('已开始监听PostgreSQL新增数据通知');
}

// 处理Socket.io客户端连接
io.on('connection', (socket) => {
  console.log('客户端已连接:', socket.id);
  socket.on('disconnect', () => {
    console.log('客户端断开连接:', socket.id);
  });
});

// 启动服务
server.listen(3000, () => {
  console.log('服务运行在 http://localhost:3000');
  startPostgresListener().catch(err => console.error('监听初始化失败:', err));
});

3. 客户端接收实时推送

前端通过Socket.io客户端库接收推送并更新UI:

<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
<script>
  const socket = io('http://localhost:3000');
  
  // 监听新增数据事件
  socket.on('new_record', (record) => {
    console.log('收到新增数据:', record);
    // 示例:将数据添加到页面列表
    const listItem = document.createElement('li');
    listItem.textContent = `新增用户:${record.username}`;
    document.getElementById('records-list').appendChild(listItem);
  });
</script>
<ul id="records-list"></ul>

为什么不用Cron?

这种基于事件驱动的方案相比Cron轮询有两个核心优势:

  • 实时性:数据插入后立即触发通知,没有轮询延迟
  • 资源高效:只有当数据变化时才会产生交互,避免了无意义的定时查询消耗数据库和服务器资源

内容的提问来源于stack exchange,提问作者eboi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:19:21