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

如何实现PostgreSQL表的实时性?Flutter+Laravel聊天应用开发

让PostgreSQL实现实时性的方案(适配Flutter+Laravel聊天应用)

针对你的场景,这里有几个不用依赖Firebase的靠谱方案,能让PostgreSQL表的变更实时推送给Flutter和Web端:

一、用PostgreSQL原生LISTEN/NOTIFY搞轻量实时

这是最省事儿的方案,直接用PostgreSQL内置的异步消息功能,不需要额外加第三方服务。

1. 数据库加触发器触发通知

给你的聊天消息表(比如messages)加个触发器,当有新消息插入(或更新/删除)时,自动往指定频道发通知:

-- 先写个触发函数,把新消息转成JSON发出去
CREATE OR REPLACE FUNCTION notify_message_change()
RETURNS TRIGGER AS $$
BEGIN
  PERFORM pg_notify('message_updates', row_to_json(NEW)::TEXT);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- 给messages表加INSERT触发器,插入后触发上面的函数
CREATE TRIGGER trigger_message_insert
AFTER INSERT ON messages
FOR EACH ROW EXECUTE FUNCTION notify_message_change();

2. Laravel端监听并转发

Laravel可以开个后台命令,持续监听PostgreSQL的message_updates频道,拿到通知后通过WebSocket推给客户端。比如用beyondcode/laravel-websockets包搭自己的WebSocket服务:

// 写个Artisan命令来监听
Artisan::command('listen:messages', function () {
    $pdo = DB::connection()->getPdo();
    $pdo->exec('LISTEN message_updates');
    
    while (true) {
        if ($notification = $pdo->pgsql_getnotify(PGSQL_CONNECTION_NOTIFY)) {
            // 把消息广播给所有订阅的客户端
            broadcast(new MessageUpdatedEvent(json_decode($notification['message'])));
        }
        usleep(100000); // 避免CPU跑满
    }
})->describe('监听PostgreSQL消息变更');

3. Flutter端订阅WebSocket

用web_socket_channel包连接Laravel的WebSocket服务,实时接收消息:

import 'package:web_socket_channel/web_socket_channel.dart';
import 'dart:convert';

final channel = WebSocketChannel.connect(
  Uri.parse('wss://your-laravel-domain/ws'), // 用WSS加密传输
);

// 监听消息流
channel.stream.listen((rawMessage) {
  final newMessage = jsonDecode(rawMessage);
  // 更新本地聊天列表UI
  _chatMessages.add(newMessage);
});

二、Laravel Echo + 自研WebSocket服务(功能更全)

如果需要私有频道、在线状态这类进阶功能,用Laravel Echo配合自己搭的WebSocket服务更合适:

  1. 安装beyondcode/laravel-websockets和laravel/echo,按文档配置WebSocket服务器。
  2. 给Message模型加观察者,创建消息时自动广播事件:
// app/Observers/MessageObserver.php
public function created(Message $message)
{
    // 广播给其他客户端,自己发的消息本地直接处理就行
    broadcast(new MessageCreatedEvent($message))->toOthers();
}
  1. Flutter端用laravel_echo包订阅事件:
import 'package:laravel_echo/laravel_echo.dart';
import 'package:socket_io_client/socket_io_client.dart' as IO;

Echo echo = Echo({
  'broadcaster': 'socket.io',
  'client': IO.io,
  'host': 'wss://your-laravel-domain:6001',
});

// 订阅公共频道的消息创建事件
echo.channel('messages')
  .listen('.MessageCreated', (event) {
    // 处理新消息
    _handleNewMessage(event['message']);
  });

三、逻辑复制(高并发场景用)

如果你的应用用户量很大,并发高,用PostgreSQL的逻辑复制更稳定:

  • 先把PostgreSQL的wal_level改成logical(在postgresql.conf里配置)。
  • 创建复制槽,捕获messages表的所有变更。
  • 写个独立服务(比如用Go或Node.js)监听复制槽,解析变更后通过WebSocket推给客户端。
  • Laravel和这个服务对接,统一管理实时推送逻辑。

几个注意点

  • 用WSS协议加密WebSocket传输,避免聊天数据泄露。
  • Flutter端要处理WebSocket重连逻辑,比如断网后自动重新连接。
  • LISTEN/NOTIFY不用改wal_level,但逻辑复制必须开logical。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:40:22