WebSocket setup using Amazon

Good day,

Based on the documentation shared in the link below:

The tool is using a WebSocket to sync the client’s messages and the server by allowing multiple users to contribute in the same time (collaboration editing).

The WebSocket server as illustrated is wss://demos.yjs.dev, allowing streaming data in a specific room.

The question is about the mechanism to set up a new WS server using a third party like AWS and GCP to allow real-time editing.

Thank you.

Hi @Moe,

You can use any provider with the prosemirror binding. E.g. y-websocket for websocket connection to a server, or something else like y-webrtc.You’ll find a bunch of providers for Yjs in the documentation.

⇐ Explains how to setup your own server. I’ll not dig into AWS hosting or GCP toolchain to write documentation. However, I’d be happy to accept a PR for documentation once you figure it out.

Hi @dmonad ,

Thank you for your message.

I am concerned about the configuration behind the WebSocket server build to respond precisely to the YJS binding editor. Each WebSocket has its own connections and keys, It seems that ProseMiror and YJS extensions use a channel Websocket with a customized solution.

My question was about if it would be possible to use any cloud server, like EC2, from any provider to set up such as connection that can respond to the tool? And what’s the technology behind it? It’s a NodeJS only?

Thank you.

The ProseMirror binding synchronizes a Yjs instance with an editor. The provider is responsible for syncing the Yjs document with other peers.

You can use GitHub - yjs/y-websocket: Websocket Connector for Yjs that uses a “custom” binary protocol defined in GitHub - yjs/y-protocols: Yjs encoding protocols. You can implement your own protocol if that is something you are interested in (see https://docs.yjs.dev/api/document-updates).

You can implement your own backend if that is something you are interested in. y-websocket ships with a nodejs server. You find also information about this in the documentation.

EC2 hosts server instances. You can set up a NodeJS server as well on EC2, for example through docker.

@dmonad Thank you for the useful feedback. I appreciate it.

Are the inputs (data added in collaboration) saved/can be saved to an external DB or storage using the same library? YJS/y-websocket? I assume this can be handled from the backend (server side of the websocket).

The other question is would be possible (can be I assume) to secure the WebSocket (“wss” rather than “ws” protocol), using the environment configuration or the library tool?

Lastly, How can we restrict access to the WebSocket (y-WebSocket) by adding an authorization header key or something like that to limit the connections using a specific key?

Thank you.

Good day,

Any feedback regarding the header authentication for the Y-WebSocket, to allow broadcasting with a header authorization?

Thank you.

@Moe The source code is open-source, you can implement whatever you want. There are existing database providers that you can plugin into y-websocket server (or hocuspocus.dev). Auth is something that you need to implement yourself. Headers in Websockets are problematic, but you will find that out once you start working on this. Most people set the auth bearer in a URL parameter. However, you can implement a custom message as well. Btw, these questions have been answered before.

The other question is would be possible (can be I assume) to secure the WebSocket (“wss” rather than “ws” protocol), using the environment configuration or the library tool?

Sure. Usually, you put any nodejs server behind a proxy that handles encryption. AWS does that for you.

@dmonad Thank you for the feedback.

Using a request parameter from the URL (token parameter or so) is not a bad idea, Just thinking about the header payload like adding an apiKey or tokenSecret to the WebSocket server request, Is this available using Y-Websocket library, also from the WebSocketProvider object, can we append a header from the request?

Thank you.

Using a request parameter from the URL (token parameter or so) is not a bad idea, Just thinking about the header payload like adding an apiKey or tokenSecret to the WebSocket server request, Is this available using Y-Websocket library, also from the WebSocketProvider object, can we append a header from the request?

Sure, this is documented: GitHub - yjs/y-websocket: Websocket Connector for Yjs

@dmonad Thank you.

From the server side, putting the code below inside the ‘upgrade’ event, the socket still sends messages.

     const queryObject = url.parse(request.url, true).query;

     if(Object.keys(queryObject).length === 0){
         console.log('no');
        socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
        socket.destroy();
        return;         
     }else{
         console.log("ok");
     }```

@dmonad Also, When adding the below, it gives an error from the console:

const wsProvider = new WebsocketProvider('ws://localhost:1234', 'my-roomname', doc, { WebSocketPolyfill: require('ws') })
browser.js:4 Uncaught Error: ws does not work in the browser. Browser clients must use the native WebSocket object
    at new ./node_modules/ws/browser.js.module.exports (browser.js:4:1)
    at setupWS (y-websocket.js:88:1)
    at WebsocketProvider.connect (y-websocket.js:393:1)
    at new WebsocketProvider (y-websocket.js:305:1)
    at prosemirror.js:15:1
|   const ydoc = new Y.Doc()
>   const provider = new WebsocketProvider('ws://localhost:1234', 'prosemirror', ydoc, { params = { auth: "bearer" }} );
| 
log.js:59 Uncaught Error: Module parse failed: Shorthand property assignments are valid only in destructuring patterns (17:13)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|   const provider = new WebsocketProvider('ws://localhost:1234', 'prosemirror', ydoc, { 
|       WebSocketPolyfill: require('ws'),
>       params = { auth: "bearer" }
|   });
| 
    at ./prosemirror.js (log.js:59:1)
    at __webpack_require__ (bootstrap:19:1)
    at 0 (log.js:59:1)
    at __webpack_require__ (bootstrap:19:1)
    at bootstrap:83:1
    at bootstrap:83:1

@dmonad

The error below has been resolved.

browser.js:4 Uncaught Error: ws does not work in the browser. Browser clients must use the native WebSocket object
    at new ./node_modules/ws/browser.js.module.exports (browser.js:4:1)
    at setupWS (y-websocket.js:88:1)
    at WebsocketProvider.connect (y-websocket.js:393:1)
    at new WebsocketProvider (y-websocket.js:305:1)
    at prosemirror.js:15:1
|   const ydoc = new Y.Doc()
>   const provider = new WebsocketProvider('ws://localhost:1234', 'prosemirror', ydoc, { params = { auth: "bearer" }} );
| 

Just to know how to read and validate the request parameter token from the server (Always NodeJS).

Read the error message, it explains the problem. I’m very happy to help out. However, I expect you to invest some time in finding the issue yourself. That includes reading documentation and debugging. I’m closing this topic now.