Hello,
I want users to collaborate on different documents via peer-to-peer communication (y-webrtc).
My understanding is that I need to create a different room for each document. In this setup, when a user switches from one document to another, they would to have to change the room.
I couldn’t find an option to change the room in the WebrtcProvider. So, I figured that I might have to create a new WebrtcProvider whenever the user switches to another document (webrtc = webrtcProvider(documentId, new Doc());).
Yet, when I do this, I receive these errors:
Error: A Yjs Doc connected to room "document1" already exists!
at Module.create (error.js:12)
at openRoom (y-webrtc.js:437)
at y-webrtc.js:574
Looking through the code, I see that y-webrtc remembers the room, and prevent to subscribe multiple times to the same room. Yet, I don’t really understand how to switch the room (or how to subscribe to multiple room and figure out for which room data in a change event is).
I’d highly appreciate a pointer on how to handle this?
You are right, when using y-webrtc you can only subscribe to a room at most once. With the other providers, you can subscribe to the same room several times at the same time. Ideally though, you subscribe to a room only once and reuse subscribed documents.
y-webrtc reuses signaling connections for all rooms. It is pretty hard to manage multiple connections over a shared signaling server, so I simply forbid that case to make it easier for me. Note that while the provider is active, you still listen to document updates and keep the document state in-memory. So when you are done with a connection (e.g. the user switches to a different document), you can simply destroy the connection webrtcProvider.destroy(). After you destroyed the connection, you can reconnect to the same room again.
I have problem with y-webrtc change room, too. But my problem is after changing the room, the collaboration cursor is not shown in peers’ codemirror 6 editors.
My project is very simple, just using JS. Here is generally what I did.
import * as Y from 'yjs';
// @ts-ignore
import { yCollab, yUndoManagerKeymap } from 'y-codemirror.next';
import { WebrtcProvider } from 'y-webrtc';
...
// Create a codemirrow 6 editor
const collabConfig = new Compartment();
const ydoc = new Y.Doc();
let provider = new WebrtcProvider('codemirror6-room-' + random.uint32(), ydoc, { signaling: [signalingServerUri]}); // Each user starts in a separate room at beginning
let ytext = ydoc.getText();
provider.awareness.setLocalStateField('user', {
name: username + ' ' + Math.floor(Math.random() * 100),
color: userColor.color,
colorLight: userColor.light
});
let extensions = [
...
collabConfig.of(yCollab(ytext, provider.awareness))
];
let state = EditorState.create({ "doc": ytext.toString(), "extensions": extensions });
let editor = new EditorView({ state, parent: document.querySelector("#editor") });
// I put a link in the web page. If user clicks that link, the user will change to a fixed room
document.querySelectorAll("a.editable").forEach((file) => {
file.addEventListener("click", function(event){
event.preventDefault();
// The room could be changed with some lines of code commented out.
// The only problem I have is I could not see coloured cursors in peers' editor
// ydoc = new Y.Doc(); // Uncomment this line, the collaboration won't work
// ytext = ydoc.getText();
provider.disconnect(); // Have to destroy the existing connection, then the connection could be rebuilt.
provider = new WebrtcProvider(filePath.replace(/\//g, '').replace('.', ''), ydoc, { signaling: [signalingServerUri]});
provider.awareness.setLocalStateField('user', {
name: username + ' ' + Math.floor(Math.random() * 100),
color: userColor.color,
colorLight: userColor.light
});
// editor.dispatch({
// annotations: [collabConfig.reconfigure(yCollab(ytext, provider.awareness))]
// });
});
});