Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot set property 'readyState' of undefined #600

Closed
1 of 2 tasks
p493z3r0 opened this issue Apr 13, 2020 · 18 comments
Closed
1 of 2 tasks

Cannot set property 'readyState' of undefined #600

p493z3r0 opened this issue Apr 13, 2020 · 18 comments
Labels
bug Something isn't working

Comments

@p493z3r0
Copy link

Note: for support questions, please use one of these channels: stackoverflow or slack

You want to:

  • report a bug
  • request a feature

Current behaviour

NodeJS Server crashes on tab refresh.

Steps to reproduce (if the current behaviour is a bug)

Use transports: ['websocket'] on your client. I'm using this library with socket-controller, which itself uses Socket-IO. But i'm quite sure, that the error tracks down to this library.

Expected behaviour

Should not crash.

Setup

  • OS: Darwin MacBook-Pro.local 19.3.0 Darwin Kernel Version 19.3.0: Thu Jan 9 20:58:23 PST 2020; root:xnu-6153.81.5~1/RELEASE_X86_64 x86_64
  • browser: All
  • engine.io version: 3.4.0

Other information (e.g. stacktraces, related issues, suggestions how to fix)

Stacktrace

with this StackTrace.
error: uncaughtException: Cannot set property 'readyState' of undefined
TypeError: Cannot set property 'readyState' of undefined
at Socket.socketOnClose (backend/node_modules/ws/lib/websocket.js:838:24)
at Socket.emit (events.js:203:15)
at Socket.EventEmitter.emit (domain.js:448:20)
at TCP._handle.close (net.js:607:12) {"error":{},"stack":"TypeError: Cannot set property 'readyState' of undefined\n at Socket.socketOnClose (backend/node_modules/ws/lib/websocket.js:838:24)\n at Socket.emit (events.js:203:15)\n at Socket.EventEmitter.emit (domain.js:448:20)\n at TCP._handle.close (net.js:607:12)","exception":true,"date":"Mon Apr 13 2020 11:18:39 GMT+0200 (Central European Summer Time)","process":{"pid":48795,"uid":501,"gid":20,"cwd":"backend","execPath":"/usr/local/Cellar/node@10/10.18.1/bin/node","version":"v10.18.1","argv":["/usr/local/Cellar/node@10/10.18.1/bin/node","^backend/src/app.ts"],"memoryUsage":{"rss":146661376,"heapTotal":79376384,"heapUsed":63015720,"external":1091116}},"os":{"loadavg":[3.15966796875,3.02978515625,2.65869140625],"uptime":95890},"trace":[{"column":24,"file":"backend/node_modules/ws/lib/websocket.js","function":"Socket.socketOnClose","line":838,"method":"socketOnClose","native":false},{"column":15,"file":"events.js","function":"Socket.emit","line":203,"method":"emit","native":false},{"column":20,"file":"domain.js","function":"Socket.EventEmitter.emit","line":448,"method":"emit","native":false},{"column":12,"file":"net.js","function":"TCP._handle.close","line":607,"method":"close","native":false}]}

@darrachequesne
Copy link
Member

Hi @dominic12 ! Do you know which version of ws you are using? engine.io#3.4.0 includes ws^7.1.2, and there are several occurences of your issue there: https://github.com/websockets/ws/search?q=Cannot+set+property+%27readyState%27+of+undefined&type=Issues

@p493z3r0
Copy link
Author

p493z3r0 commented Apr 14, 2020

Hi @darrachequesne, i'm using ws@7.2.3. I know that these issues exist, but it was always a wrong usage of WS.

@darrachequesne
Copy link
Member

That's weird. It might be due to the socketOnClose method being called twice, so the this[kWebSocket] gets set to undefined in the first call, but it should be prevented by:

// https://github.com/websockets/ws/blob/7.2.4/lib/websocket.js#L834
this.removeListener('close', socketOnClose);

Maybe:

-- socket.on('close', socketOnClose);
++ socket.once('close', socketOnClose);

Could fix your issue? Could you please open an issue in the ws repository?

@p493z3r0
Copy link
Author

I can confirm, that the method is called twice. Sometimes, i also get an "failed: Invalid frame header" error back. However, additionally to this issue, i will create an issue in the WS Repo too.

@p493z3r0
Copy link
Author

If i remove transports: ['websocket'] from my client, all seems to work perfectly. But i need to have that set, because of Google Flex Env restrictions. Maybe this helps in some way?

@lpinca
Copy link
Contributor

lpinca commented Apr 14, 2020

You can reproduce with the following code:

const eio = require('engine.io');
const eioc = require('engine.io-client');
const http = require('http');

const server = http.createServer();
const engineioServer1 = eio.attach(server);
const engineioServer2 = eio.attach(server);

server.listen(function () {
  const socket = eioc(`ws://localhost:${server.address().port}`, {
    transports: ['websocket']
  });
});

or

const eio = require('engine.io');
const eioc = require('engine.io-client');
const http = require('http');

const engineioServer = new eio.Server();
const server = http.createServer();

server.on('upgrade', function (request, socket, head) {
  engineioServer.handleUpgrade(request, socket, head);
  engineioServer.handleUpgrade(request, socket, head);
});

server.listen(function () {
  const socket = eioc(`ws://localhost:${server.address().port}`, {
    transports: ['websocket']
  });
});

This is invalid usage of ws. There must be a 1 on 1 correspondence between a net.Socket and a WebSocket. The above code creates 2 WebSocket from the same net.Socket.

@lpinca
Copy link
Contributor

lpinca commented Apr 14, 2020

Try to monkey patch this line https://github.com/websockets/ws/blob/7.2.4/lib/websocket.js#L153 and change it like this:

if (socket[kWebSocket]) {
  throw new Error('Invalid usage');
} else {
  socket[kWebSocket] = this;
}

Your server process should crash with that error.

@p493z3r0
Copy link
Author

It crashed with that error. I'll try to examine where the faulty code is. Most likely socket.io or socket-controller.

@nxz91
Copy link

nxz91 commented Apr 23, 2020

Hi Dominic, did you get to the root of this already? Really scratching my head here...

@p493z3r0
Copy link
Author

Had no luck yet. How do you use socket.io? I'm using it with socket-controller.

@nxz91
Copy link

nxz91 commented Apr 23, 2020

I need to use transports: ['websocket'] as you do because Heroku is failing to provide session affinity between different server instances otherwise.

@nxz91
Copy link

nxz91 commented Apr 23, 2020

I'm just using default socket.io-client and socket.io without any tooling

@p493z3r0
Copy link
Author

I see. So it's not just me. @darrachequesne do you have an Idea where this originates? I had no luck so far..

@p493z3r0
Copy link
Author

@nxz91 Did you find a solution to your problem?

@nxz91
Copy link

nxz91 commented Apr 27, 2020

Yes and no: I decided to start by scaling vertically using the sticky-cluster package. This will suffice for now (moving from a single processor to at least multiple processors). We moved from Heroku to Digitalocean in the process which made server costs drop substantially. Once we need to scale horizontally, we'll probably make the switch to pure Websockets (and maybe even a Kubernetes deployment).

@p493z3r0
Copy link
Author

p493z3r0 commented Apr 29, 2020

@nxz91 Thanks for your response. I found the mistake. express-status-monitor spawned a second instance of socket.io and that caused the problems. BTW: We have also switched to Digitalocean, as it seems to be way cheaper than GCP or Heroku. I'm closing this issue now.

@nxz91
Copy link

nxz91 commented Apr 29, 2020 via email

@darrachequesne
Copy link
Member

Closed due to inactivity, please reopen if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants