How it works
Yjs clients connect via WebSockets to a Channels WebSocket Consumer which can perform e.g. authentication and then forwards messages via channel layer to a central worker. This worker runs in a separate process and keeps a Yjs document + awareness information for each 'room', processes synchronization and awareness updates and sends responses (single and broadcast to room) to the WebSocket consumers.
Under the hood, this project uses yroom
which is a high-level Python binding to a Yjs synchronization and awareness implementation in Rust based on the official Yjs Rust port.
Example flow
sequenceDiagram
participant Alice
participant WebsocketConsumerA
participant Yroom Worker
participant WebsocketConsumerB
participant Bob
Alice->>+WebsocketConsumerA: connect
WebsocketConsumerA->>+Yroom Worker: connect
Yroom Worker->>+WebsocketConsumerA: sync1
WebsocketConsumerA->>+Alice: forward sync1
Alice->>+WebsocketConsumerA: sync2
WebsocketConsumerA->>+Yroom Worker: forward sync2
Bob->>WebsocketConsumerB: connect
WebsocketConsumerB->>+Yroom Worker: connect
Yroom Worker->>+WebsocketConsumerB: sync1
WebsocketConsumerB->>+Bob: forward sync1
Bob->>+WebsocketConsumerB: sync2
WebsocketConsumerB->>+Yroom Worker: forward sync2
Bob->>+WebsocketConsumerB: update from Bob
WebsocketConsumerB->>+Yroom Worker: forward update from Bob
par
Yroom Worker->>WebsocketConsumerA: broadcast update
WebsocketConsumerA->>Alice: forward update
and
Yroom Worker->>WebsocketConsumerB: broadcast update
WebsocketConsumerB->>Bob: forward update
end