WebSocket Provider for Yjs
The Websocket Provider implements a classical client server model. Clients connect to a single endpoint over Websocket. The server distributes awareness information and document updates among clients.
This repository contains a simple in-memory backend that can persist to databases, but it can't be scaled easily. The @y/hub repository contains an alternative backend that is scalable, provides auth*, and can persist to different backends.
The Websocket Provider is a solid choice if you want a central source that handles authentication and authorization. Websockets also send header information and cookies, so you can use existing authentication mechanisms with this server.
This README primarily documents the currently stable y-websocket release and
its usage with yjs v13.
The main branch of this repository is the development branch for the unstable
@y/websocket release, which adds support for Yjs v14 (@y/y). Most users
should continue to use the stable y-websocket package with Yjs v13 for now.
- Supports cross-tab communication. When you open the same document in the same browser, changes on the document are exchanged via cross-tab communication (Broadcast Channel and localStorage as fallback).
- Supports exchange of awareness information (e.g. cursors).
# stable release (recommended)
npm i y-websocket
# main branch / unstable release
npm i @y/websocketThere are multiple y-websocket compatible backends for y-websocket:
- @y/websocket-server
- hocuspocus
The fastest way to get started is to run the @y/websocket-server backend. This package was previously included in y-websocket and now lives in a forkable repository.
Install and start y-websocket-server:
npm install @y/websocket-server
HOST=localhost PORT=1234 npx y-websocketimport * as Y from '@y/y'
import { WebsocketProvider } from 'y-websocket'
const doc = new Y.Doc()
const wsProvider = new WebsocketProvider('ws://localhost:1234', 'my-roomname', doc)
wsProvider.on('status', event => {
console.log(event.status) // logs "connected" or "disconnected"
})The WebSocket provider requires a WebSocket object to create connection to a server. You can polyfill WebSocket support in Node.js using the ws package.
const wsProvider = new WebsocketProvider('ws://localhost:1234', 'my-roomname', doc, { WebSocketPolyfill: require('ws') })import { WebsocketProvider } from 'y-websocket'- Create a new websocket-provider instance. As long as this provider, or the connected ydoc, is not destroyed, the changes will be synced to other clients via the connected server. Optionally, you may specify a configuration object. The following default values of wsOpts can be overwritten.
wsProvider = new WebsocketProvider(serverUrl: string, room: string, ydoc: Y.Doc [, wsOpts: WsOpts])
wsOpts = {
// Set this to `false` if you want to connect manually using wsProvider.connect()
connect: true,
// Specify a query-string / url parameters that will be url-encoded and attached to the `serverUrl`
// I.e. params = { auth: "bearer" } will be transformed to "?auth=bearer"
params: {}, // Object<string,string>
// You may polyill the Websocket object (https://developer.mozilla.org/en-US/docs/Web/API/WebSocket).
// E.g. In nodejs, you could specify WebsocketPolyfill = require('ws')
WebsocketPolyfill: Websocket,
// Specify an existing Awareness instance - see https://github.com/yjs/y-protocols
awareness: new awarenessProtocol.Awareness(ydoc),
// Specify the maximum amount to wait between reconnects (we use exponential backoff).
maxBackoffTime: 2500
}- True if this instance is currently connected to the server.
- True if this instance is currently connecting to the server.
- If false, the client will not try to reconnect.
- True if this instance is currently communicating to other browser-windows via BroadcastChannel.
- True if this instance is currently connected and synced with the server.
- The current sync status object containing
connected,receivedInitialSync,localUpdatesSynced,localUpdatesAge,lastMessageAge, andstatus('green','yellow', or'red'). See the'sync-status'event for details. Only works with certain backends (e.g. yhub). - The specified url parameters. This can be safely updated, the new values will be used when a new connction is established. If this contains an auth token, it should be updated regularly.
- Disconnect from the server and don't try to reconnect.
- Establish a websocket connection to the websocket-server. Call this if you recently disconnected or if you set wsOpts.connect = false.
- Destroy this wsProvider instance. Disconnects from the server and removes all event handlers.
- Add an event listener for the sync event that is fired when the client received content from the server.
- Receive updates about the current connection status.
- Fires when the underlying websocket connection is closed. It forwards the websocket event to this event handler.
- Fires when the underlying websocket connection closes with an error. It forwards the websocket event to this event handler.
-
Receive detailed sync status updates. This event fires when the sync status changes, providing a distilled view of the connection and synchronization state. Only works with certain backends (e.g. yhub).
ThesyncStatusobject has the following properties:connected: boolean– Whether the provider is currently connected to the server.receivedInitialSync: boolean– Whether the initial sync with the server has completed.localUpdatesSynced: boolean– Whether all local updates have been confirmed by the server.localUpdatesAge: number– Age in milliseconds of the oldest unconfirmed local update (0 if all synced).lastMessageAge: number– Time in milliseconds since the last message was received from the server.status: 'green' | 'yellow' | 'red'– Distilled sync status:'green'– Connected, synced, and no unconfirmed local updates.'yellow'– Connected but has unconfirmed local updates younger than 8 seconds.'red'– Disconnected, not synced, or unconfirmed local updates older than 8 seconds.
wsProvider.syncStatus.
wsProvider.wsconnected: boolean
wsProvider.wsconnecting: boolean
wsProvider.shouldConnect: boolean
wsProvider.bcconnected: boolean
wsProvider.synced: boolean
wsProvider.syncStatus: SyncStatus
wsProvider.params : boolean
wsProvider.disconnect()
wsProvider.connect()
wsProvider.destroy()
wsProvider.on('sync', function(isSynced: boolean))
wsProvider.on('status', function({ status: 'disconnected' | 'connecting' | 'connected' }))
wsProvider.on('connection-close', function(WSClosedEvent))
wsProvider.on('connection-error', function(WSErrorEvent))
wsProvider.on('sync-status', function(syncStatus: SyncStatus))
The MIT License © Kevin Jahns