yjs / y-websocket

Websocket Connector for Yjs
https://docs.yjs.dev/ecosystem/connection-provider/y-websocket
MIT License
497 stars 256 forks source link

Websocket events to the client `throw integer out of range` error #130

Closed maksymalist closed 1 year ago

maksymalist commented 1 year ago

Describe the bug

Whenever I try to send a websocket event to my server (https://github.com/yjs/yjs-demos/blob/main/demo-server/demo-server.js) it always throws me an error:

Uncaught Error: Integer out of range!
    at Module.readVarUint (decoding.js:247:1)
    at readMessage (y-websocket.js:73:43)
    at websocket.onmessage (y-websocket.js:97:1)

and that goes both ways so when I try to send an event from my server to the client listeners it sends me the same error but it's happening in the server code

Error: Integer out of range!
    at Object.readVarUint (~/Desktop/yjs-demos/demo-server/node_modules/lib0/dist/buffer-65d3ece5.cjs:1106:13)
    at messageListener (~/Desktop/yjs-demos/demo-server/node_modules/y-websocket/bin/utils.js:167:32)
    at WebSocket.<anonymous> (~/Desktop/yjs-demos/demo-server/node_modules/y-websocket/bin/utils.js:236:69)
    at WebSocket.emit (node:events:390:28)
    at Receiver.receiverOnMessage (~/Desktop/yjs-demos/demo-server/node_modules/ws/lib/websocket.js:825:20)

To Reproduce

Steps to reproduce the server:

  1. git clone https://github.com/yjs/yjs-demos.git
  2. cd demo-server
  3. npm i
  4. In the demo-server.js file replace line 22:
    wss.on('connection', (conn, req) => setupWSConnection(conn, req, { gc: req.url.slice(1) !== 'prosemirror-versions' }))
  5. with this:
    
    wss.on('connection', (conn, req) => setupWSConnection(conn, req, { gc: req.url.slice(1) !== 'prosemirror-versions' }))

setInterval(() => { wss.clients.forEach((client) => { client.send('testing') }) }, 1000)

6. export PORT=1234 && npm start

**Steps to reproduce the client:**

in the root dir of the same /yjs-demos project you just cloned

1. cd prosemirror
2. npm i
3. in the prosemirror.js file replace line 14

const provider = new WebsocketProvider('wss://demos.yjs.dev', 'prosemirror-demo', ydoc)

with this:

const provider = new WebsocketProvider('ws://localhost:1234', 'prosemirror-demo', ydoc)


then add

provider.ws.addEventListener('testing', () => { console.log('testing event received') })


in the ```window.addEventListener('load', () => {...})``` callback (the place where you add the code doesn't matter as long as it is in the callback of the listener)

4. npm start

then you should be getting the same error when you open the dev tools :)

## Expected behavior 
I wanted the server to get all the connected clients and send them an event called "testing" every 1000ms. After the clients had received the event they would ```console.log('testing event received')```

## Environment Information
 - Chrome / NodeJS@16.13.2
 - Yjs versions:

Client:

├─┬ y-prosemirror@1.0.19 │ └── yjs@13.5.36 deduped ├─┬ y-websocket@1.4.3 │ ├─┬ y-leveldb@0.1.1 │ │ └── yjs@13.5.36 deduped │ └── yjs@13.5.36 deduped └── yjs@13.5.36


Server: 

├─┬ y-websocket@1.3.9 │ └─┬ y-leveldb@0.1.0 │ └── yjs@13.4.12 deduped └── yjs@13.4.12

dmonad commented 1 year ago

Hi @maksymalist,

If you want to send custom messages, you can extend the binary protocol. The issue occurs because the client expects a binary message where the first byte indicates the kind of message. If you send a string, the client simply doesn't understand.

Protocol messages that the server uses: https://github.com/yjs/y-protocols

Another approach might be to use Yjs or the Awareness instance to communicate with the clients. Or create another WebSocket connection that implements a protocol you can design yourself.

maksymalist commented 1 year ago

Thanks for helping me out!