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

不使用MongoDB时如何通过Meteor发布订阅获取同步数据

解决方案

你服务端发布时用的集合名是rooms,Meteor的DDP订阅机制会自动把服务端推送的added/changed事件同步到客户端本地缓存,你只需要在客户端声明一个同名的本地集合接收数据即可,不需要服务端有对应的Mongo持久化集合。


第一步:先修复现有代码的三处明显错误

  • 服务端_cache.add是错误写法,Map的新增元素方法是set,同时observers应该用Set类型方便增删,对应初始化代码改为:
if (!_cache.has(roomHash)) {
  _cache.set(roomHash, { messages:[], observers: new Set() });
}
  • 服务端pushMessage方法里room.messags拼写错误,改为room.messages
  • 客户端hook里useTracker的依赖项orderHash是笔误,改为roomHash

第二步:客户端获取数据的实现

你提到的Meteor.Collection已在新版本Meteor中废弃,统一用Mongo.Collection,客户端声明的集合默认就是本地内存集合,不需要和后端Mongo绑定,直接用即可:

// 客户端全局声明同名集合,只在内存中存在,无需后端Mongo支持
const Rooms = new Mongo.Collection('rooms');

const useChatMessages = roomHash => {
  const { loading, messages } = useTracker(() => {
    const handle = Meteor.subscribe("chatroom", roomHash);
    const loading = !handle.ready();
    // 从本地集合取对应房间的消息
    const roomDoc = Rooms.findOne(roomHash);
    const messages = roomDoc ? roomDoc.messages : [];
    return { loading, messages };
  }, [roomHash]);

  const pushMessage = useCallback(message => {
    Meteor.call('pushMessage', roomHash, message);
  }, [roomHash]);

  return { loading, messages, pushMessage };
};

如果你确实不想引入Mongo相关包

可以直接监听DDP消息自行维护状态,实现如下:

const useChatMessages = roomHash => {
  const [loading, setLoading] = useState(true);
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    const handle = Meteor.subscribe("chatroom", roomHash, {
      onReady: () => setLoading(false)
    });

    // 监听服务端推送的变更事件
    const addedListener = (collection, id, fields) => {
      if (collection === 'rooms' && id === roomHash) {
        setMessages(fields.messages || []);
      }
    };
    const changedListener = (collection, id, fields) => {
      if (collection === 'rooms' && id === roomHash && fields.messages) {
        setMessages(fields.messages);
      }
    };

    Meteor.connection.on('added', addedListener);
    Meteor.connection.on('changed', changedListener);

    return () => {
      handle.stop();
      Meteor.connection.off('added', addedListener);
      Meteor.connection.off('changed', changedListener);
    };
  }, [roomHash]);

  const pushMessage = useCallback(message => {
    Meteor.call('pushMessage', roomHash, message);
  }, [roomHash]);

  return { loading, messages, pushMessage };
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 10:06:03