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

Yjs文档通过WebSocket同步异常,客户端与服务端内容不一致求助

Fixing Y.Doc and WebSocket Sync Between Next.js Client and Server

Here are the key issues and fixes to get your document sync working:

1. Mismatched Document/Room Names (Critical)

Your client connects using table-${tableId} as the room name, but the server hardcodes not_untitled. This means client and server are operating on completely separate documents.

Server Fix: Extract Room Name from Client Request

Update your server connection handler to pull the room name from the client's WebSocket request URL (Yjs sends this as a query parameter):

wss.on('connection', (ws, req) => {
  // Parse the room name from the request URL
  const url = new URL(req.url, 'http://localhost:3010');
  const docName = url.searchParams.get('room');

  if (!docName) {
    console.error('No room name provided by client');
    ws.close();
    return;
  }

  loadDocument(docName).then((doc) => {
    console.log(`Document loaded: ${docName} - ${doc.getText('shared-text').toString()}`);
    const awareness = new Awareness(doc);
    setupWSConnection(ws, doc, { awareness });

    doc.on('update', async () => {
      await saveDocument(docName, doc);
    });

    ws.on('close', () => {
      awareness.setLocalState(null);
      console.log(`Client disconnected from room: ${docName}`);
    });

  }).catch((err) => {
    console.error('Failed to load document:', err);
    ws.close();
  });
});

2. Verify Package Version Compatibility

Ensure your client and server use the same major version of:

  • yjs
  • y-websocket
  • y-protocols

Mismatched versions can silently break sync logic.

3. Validate Client Sync Status

Check your client console for the Synced with server: true log. If this never appears, confirm:

  • The room name passed to WebsocketProvider matches what the server extracts
  • Your WebSocket server is reachable at ws://localhost:3010
  • No CORS or firewall rules are blocking the connection

4. Optimize Client State Updates

Your client's ydoc.on('update') handler sets the same ydoc reference to state, which won't trigger React re-renders. Instead, derive the text content directly from the doc when rendering:

// In your component render logic
const textContent = doc ? doc.getText("shared-text").toString() : "";

5. Confirm Document Loading/Saving Logic

Double-check that your loadDocument function correctly applies stored updates to a new Y.Doc:

async function loadDocument(docName) {
  const doc = new Y.Doc();
  const storedUpdate = await db.get(docName); // Fetch binary update from DB
  if (storedUpdate) {
    Y.applyUpdate(doc, new Uint8Array(storedUpdate));
  }
  return doc;
}

And saveDocument correctly encodes the doc state:

async function saveDocument(docName, doc) {
  const update = Y.encodeStateAsUpdate(doc);
  await db.put(docName, update);
}

Once these fixes are applied, your client and server should sync the shared-text content correctly.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 19:19:53