Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Loro synchronization using Websockets #572

Unanswered
zolero asked this question in Q&A
Discussion options

Thank you for creating such an amazing CRDT library! Loro's stable data format, excellent performance, and cross-platform support make it truly impressive.

I was wondering if you could provide an example or guide for implementing real-time synchronization with WebSockets? Specifically:

  • Exporting changes from a Loro document.
  • Transmitting those changes via WebSockets.
  • Importing and merging updates into remote documents.

Right now, it’s quite hard to figure out the best practices for implementing these kinds of synchronizations. An example or guide would greatly help developers like me integrate Loro into real-time collaborative applications and showcase its full potential. I hope to see something similar to what Hocuspocus offers, as it provides a great reference for WebSocket-based synchronization.

Thank you again for your amazing work!

You must be logged in to vote

Replies: 2 comments 1 reply

Comment options

Thanks! We're working on that

You must be logged in to vote
1 reply
Comment options

If you can at least describe:

  • Exporting changes from a Loro document (these could be sent to somewhere centralized, could be via WebSockets or anything else)
  • how you would track this change in a centralized place (assume JavaScript, f.e. Node.js, and no matter how it got there, could be WebSockets or anything else really)
  • Merging an update into a doc (f.e. sent in any matter, could be WebSockets, doesn't matter)

Basically, what's the best practice for managing multiple documents around a centralized process (around a centralized state).

For sake of example, a reference example can be implemented inside a single JavaScript file that runs in a browser, something like this:

// Example: 3 clients will be in a "room" editing the same "document"
const doc1 = new LoroDoc()
const doc2 = new LoroDoc()
const doc3 = new LoroDoc()
// Example: the centralized location (it could be on a remote server, but that's no matter to the example).
// Is a LoroDoc even what we want here? I don't know (that's why I landed here)
const centralizedDoc = new LoroDoc()
// ...Example: doc1 is modified at any time ...
setTimeout(function client1UpdatesDoc1() {
 // send update for doc1
 sendUpdate(doc1.export(...))
 setTimeout(client1UpdatesDoc1, Math.round(500 + Math.random() * 1000))
}, Math.round(500 + Math.random() * 1000))
// ...Example: doc2 is modified at any time ...
setTimeout(function client2UpdatesDoc2() {
 // send update for doc2
 sendUpdate(doc2.export(...))
 setTimeout(client2UpdatesDoc2, Math.round(500 + Math.random() * 1000))
}, Math.round(500 + Math.random() * 1000))
// ...Example: doc3 is modified at any time ...
setTimeout(function client3UpdatesDoc3() {
 // send update for doc3
 sendUpdate(doc3.export(...))
 setTimeout(client3UpdatesDoc3, Math.round(500 + Math.random() * 1000))
}, Math.round(500 + Math.random() * 1000))
async function sendUpdate(update) {
 // pretend this function receives a "payload" (a network app could be sending it over WebSockets or anything else)
 await new Promise(r => setTimeout(r, 200 + Math.round(Math.random() * 100))) // emulate network delay
 const updateToSync = // ...update centralizedDoc ... centralizedDoc.import(...), or something
 syncClients(updateToSync)
}
function syncClients(update) {
 // update all clients (doc1, doc2, doc3), they might be updated in differing order depending on network conditions.
 // Maybe this also needs to skip updates from the original client that sent the update.
 new Promise(r => setTimeout(r, 200 + Math.round(Math.random() * 100))).then(() => { // emulate network delay
 doc1.import(...) // or similar
 })
 new Promise(r => setTimeout(r, 200 + Math.round(Math.random() * 100))).then(() => { // emulate network delay
 doc2.import(...) // or similar
 })
 new Promise(r => setTimeout(r, 200 + Math.round(Math.random() * 100))).then(() => { // emulate network delay
 doc3.import(...) // or similar
 })
}

What would this reference example look like?

After having a working version of a reference example like that, we can easily extrapolate the non-Loro parts (such as sending data via WebSockets instead of merely emulating something with async functions).

Comment options

Is there any new developments on this? I was just searching for an alternative for yjs+hocuspocus and this is the only conversation about this that i have found.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /