webpack-hot-client icon indicating copy to clipboard operation
webpack-hot-client copied to clipboard

hot doesn't work when you have two or more websocket clients

Open alexander-akait opened this issue 6 years ago • 11 comments

  • Operating System: Ubuntu 18.04
  • Node Version: v8.11.3
  • NPM Version: 6.2.0
  • webpack Version: 4.16.1
  • webpack-hot-client Version: 4.1.1

Expected Behavior

When two/more websocket clients connected all should get messages (hash, ok and etc).

Actual Behavior

When you have two websocket clients, only first connected get information, second don't get nothing (i.e. hot doesn't work es expected) on connection.

Now

Code

Example from webpack-serve https://github.com/webpack-contrib/webpack-serve/blob/master/docs/addons/watch-content.config.js

How Do We Reproduce?

  1. Clone repo from example
  2. Look on WS messages in dev tools.

Why?

After run example above websocket client from example (https://github.com/webpack-contrib/webpack-serve/blob/master/docs/addons/watch-content.config.js#L25) connected first and websocket server send messages, when i open development site, websocket client from hot client (https://github.com/webpack-contrib/webpack-hot-client/blob/master/lib/client/socket.js#L18) connected to websocket server, but don't get messages due in server.clients.size === 1 (https://github.com/webpack-contrib/webpack-hot-client/blob/master/lib/socket-server.js#L71) and hot doesn't work as expected.

It is regression, because in webpack-hot-client@3 all works fine:

  • webpack-hot-client@3 (https://github.com/webpack-contrib/webpack-hot-client/blob/v3.0.0/index.js#L186)
  • webpack-hot-client@4 (https://github.com/webpack-contrib/webpack-hot-client/blob/master/lib/socket-server.js#L71)

Solution:

  1. Return behavior from webpack-hot-client@3
  2. net.Server from (https://github.com/webpack-contrib/webpack-serve#listening) should contain websocker server (server.wss property) to allow send messages without additional websocket clients (in some cases developers can use more when one websocket client, looks it is bad solution)

alexander-akait avatar Jul 18 '18 11:07 alexander-akait

/cc @shellscape

alexander-akait avatar Jul 19 '18 10:07 alexander-akait

I've been struggling with this all day long but I was able to fix the issue by removing these lines. From this PR it looks like these lines were added as part of a fix to prevent logging multiple times. With allEntries enabled and if there are multiple entries on the same page, then only the first bundle will connect to a socket.

Seems like a fix might be to delete the aforementioned lines and have socket.js memoize a single WebSocket on the global scope? And then successive bundles can reuse the same Websocket where some wrapper would handle all of the logging in a single instance. I can complete this work if this seems like an appropriate fix to you, @shellscape!

garbles avatar Jul 20 '18 01:07 garbles

I had a look to see how webpack-hot-middleware handles this scenario, as @garbles suggested in https://github.com/webpack-contrib/webpack-hot-client/issues/93#issuecomment-406459576 the global sentinel value is used to share the socket instance across all entries, and each one subscribes to the message independently.

glenjamin avatar Nov 07 '18 17:11 glenjamin

@glenjamin webpack-dev-server is not handle this use case, he always send data to all clients, i think original issue with iframe with HMR is edge case where maybe doesn't exist good solution

alexander-akait avatar Nov 07 '18 17:11 alexander-akait

I've just had a look, it looks like webpack-dev-server will produce one socket connection per entry, which will also mostly work, although I recall it also uses postMessage on the current window object to broadcast the fact that there's an update - so this may be relevant too.

The reason I stopped doing this in hot-middleware is because it was chewing up the allowed number of HTTP connections, but I don't think the same limit applies to websocket connections.

glenjamin avatar Nov 07 '18 17:11 glenjamin

Ok, I've now gone and read up on all the issues related to #47 and it turns out this is pretty complicated because there's a bunch of different ways that webpack bundles and chunks interact.

Will need a bit more thinking and trying stuff out to be sure what can be done to resolve all the different scenarios.

glenjamin avatar Nov 07 '18 17:11 glenjamin

@glenjamin :+1:

alexander-akait avatar Nov 07 '18 17:11 alexander-akait

This issue is fixed in https://github.com/hedgepigdaniel/webpack-hmr-client

hedgepigdaniel avatar Oct 03 '19 07:10 hedgepigdaniel

@hedgepigdaniel oh cool, that looks neat - but I’m getting a 404 on the link with an explanation of the differnces

glenjamin avatar Oct 03 '19 07:10 glenjamin

thanks @glenjamin should be fixed now

hedgepigdaniel avatar Oct 03 '19 08:10 hedgepigdaniel

Oh right! I hadn’t realised it was a fork of hot client. I think contrib might be open to offers if someone maintaining it.

I haven’t caught up with the people organising contrib recently, but it’s worth asking them

glenjamin avatar Oct 03 '19 08:10 glenjamin