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

Fix #268/#71: HMR support for web sockets #270

Merged
merged 1 commit into from
Mar 15, 2023

Conversation

melloware
Copy link
Contributor

Fix #268 Netx JS support
Fix #71 Handle websockets in Dev Mode

@melloware melloware force-pushed the nextjs-268 branch 3 times, most recently from a7f581d to d9ef025 Compare March 11, 2023 14:39
@melloware
Copy link
Contributor Author

Tested with both Vite and NextJS successfully.

@melloware melloware force-pushed the nextjs-268 branch 2 times, most recently from 0fa9401 to 9129166 Compare March 11, 2023 14:50
@melloware
Copy link
Contributor Author

melloware commented Mar 11, 2023

Any websocket you want ignored you can still use the ignored paths property to skip!

@melloware melloware force-pushed the nextjs-268 branch 2 times, most recently from 5b8774a to 1540b6e Compare March 11, 2023 21:31
@melloware melloware changed the title Fix #268: HMR support for web sockets Fix #268/#71: HMR support for web sockets Mar 12, 2023
Copy link
Collaborator

@ia3andy ia3andy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that's very cool, I've just added a few comments.. I will give it a try later 👍

@melloware
Copy link
Contributor Author

Very happy with this version now, more graceful and removes Vite hack

@melloware melloware requested a review from ia3andy March 13, 2023 18:04
@ia3andy
Copy link
Collaborator

ia3andy commented Mar 14, 2023

I've test vite+svelte and get this error:

2023-03-14 10:13:37,160 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2023-03-14 10:13:37,161 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, quinoa, resteasy-reactive, smallrye-context-propagation, vertx]
2023-03-14 10:13:42,405 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Sec-WebSocket-Protocol: vite-hmr
2023-03-14 10:13:42,405 ERROR [io.ver.cor.net.imp.ConnectionBase] (vert.x-eventloop-thread-2) Invalid object PooledUnsafeDirectByteBuf(freed)
2023-03-14 10:13:42,406 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Quinoa is forwarding web socket: '/'
2023-03-14 10:13:42,433 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Quinoa client websocket: 127.0.0.1:5173/
2023-03-14 10:13:42,451 WARN  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Server websocket is not ready: WebSocket is closed
2023-03-14 10:13:43,058 ERROR [io.ver.cor.net.imp.ConnectionBase] (vert.x-eventloop-thread-2) Invalid object PooledUnsafeDirectByteBuf(freed)
2023-03-14 10:13:43,060 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-2) Sec-WebSocket-Protocol: vite-hmr
2023-03-14 10:13:43,061 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-2) Quinoa is forwarding web socket: '/'
2023-03-14 10:13:43,063 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-2) Quinoa client websocket: 127.0.0.1:5173/
2023-03-14 10:13:43,071 WARN  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-2) Server websocket is not ready: WebSocket is closed

Here is the project: https://github.com/ia3andy/vite-svelte-quinoa

@melloware
Copy link
Contributor Author

Thanks for the reproducer I will investigate and let you know!

@melloware
Copy link
Contributor Author

Weird your reproducer is working fine for me and HMR is working great!

Microsoft Windows [Version 10.0.22621.1265]

Apache Maven 3.9.0 (9b58d2bad23a66be161c4664ef21ce219c2c8584)
Maven home: C:\Tools\apache-maven-3.9.0
Java version: 17.0.5, vendor: Eclipse Adoptium, runtime: C:\Tools\jdk-17
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"

@melloware
Copy link
Contributor Author

Its also strange yours called the websocket twice and mine only called it once correctly.

2023-03-14 07:30:16,886 INFO  [io.quarkus] (Quarkus Main Thread) vite-svelte-quinoa 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.16.4.Final) started in 16.237s. Listening on: http://localhost:8080

2023-03-14 07:30:16,887 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2023-03-14 07:30:16,888 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, quinoa, resteasy-reactive, smallrye-context-propagation, vertx]
2023-03-14 07:30:30,103 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Sec-WebSocket-Protocol: vite-hmr
2023-03-14 07:30:30,104 ERROR [io.ver.cor.net.imp.ConnectionBase] (vert.x-eventloop-thread-2) Invalid object PooledUnsafeDirectByteBuf(freed)
2023-03-14 07:30:30,105 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Quinoa is forwarding web socket: '/'
2023-03-14 07:30:30,132 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Quinoa client websocket: 127.0.0.1:5173/
2023-03-14 07:30:30,150 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Quinoa has forwarded web socket: '/'

@melloware
Copy link
Contributor Author

Also from looking at your threads it looks like the socket got called from thread 2 and 3 simultaneously from your browser?

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 14, 2023

I am using chrome

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 14, 2023

ah maybe I had two tabs open

@melloware
Copy link
Contributor Author

melloware commented Mar 14, 2023

Yep try it fresh from incognito mode just to take all caching out of the equation and starts a fresh websocket.

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 14, 2023


2023-03-14 14:56:31,706 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2023-03-14 14:56:31,707 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, quinoa, resteasy-reactive, smallrye-context-propagation, vertx]
2023-03-14 14:56:37,448 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-2) Sec-WebSocket-Protocol: vite-hmr
2023-03-14 14:56:37,449 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-2) Quinoa is forwarding web socket: '/'
2023-03-14 14:56:37,467 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-2) Quinoa client websocket: 127.0.0.1:5173/
2023-03-14 14:56:37,470 ERROR [io.ver.cor.net.imp.ConnectionBase] (vert.x-eventloop-thread-2) Invalid object PooledUnsafeDirectByteBuf(freed)
2023-03-14 14:56:37,471 ERROR [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Quinoa failed to forward request '/node_modules/svelte-hmr/runtime/overlay.js?v=446aea97', see logs.: java.lang.IllegalStateException: Invalid object PooledUnsafeDirectByteBuf(freed)
	at io.vertx.core.http.impl.Http1xClientConnection.lambda$static$0(Http1xClientConnection.java:79)
	at io.vertx.core.http.impl.Http1xClientConnection.handleMessage(Http1xClientConnection.java:721)
	at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:157)
	at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:153)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318)
	at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:833)


14:56:37 [vite] ws error:
RangeError: Invalid WebSocket frame: RSV1 must be clear
    at Receiver.getInfo (file:///Users/ia3andy/Downloads/vite-svelte-quinoa/src/main/webui/node_modules/vite/dist/node/chunks/dep-ca21228b.js:54761:14)
    at Receiver.startLoop (file:///Users/ia3andy/Downloads/vite-svelte-quinoa/src/main/webui/node_modules/vite/dist/node/chunks/dep-ca21228b.js:54708:22)
    at Receiver._write (file:///Users/ia3andy/Downloads/vite-svelte-quinoa/src/main/webui/node_modules/vite/dist/node/chunks/dep-ca21228b.js:54646:10)
    at writeOrBuffer (node:internal/streams/writable:391:12)
    at _write (node:internal/streams/writable:332:10)
    at Receiver.Writable.write (node:internal/streams/writable:336:10)
    at Socket.socketOnData (file:///Users/ia3andy/Downloads/vite-svelte-quinoa/src/main/webui/node_modules/vite/dist/node/chunks/dep-ca21228b.js:57428:37)
    at Socket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:315:12)
    at readableAddChunk (node:internal/streams/readable:289:9)
2023-03-14 14:56:37,513 WARN  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-2) Server websocket is not ready: WebSocket is closed
2023-03-14 14:56:40,732 ERROR [io.ver.cor.net.imp.ConnectionBase] (vert.x-eventloop-thread-3) Invalid object PooledUnsafeDirectByteBuf(freed)
2023-03-14 14:56:40,734 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Sec-WebSocket-Protocol: vite-hmr
2023-03-14 14:56:40,735 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Quinoa is forwarding web socket: '/'
2023-03-14 14:56:40,736 ERROR [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Quinoa failed to forward request '/node_modules/.vite/deps/chunk-XTA3UROE.js?v=446aea97', see logs.: io.vertx.core.http.HttpClosedException: Connection was closed

2023-03-14 14:56:40,738 INFO  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Quinoa client websocket: 127.0.0.1:5173/
2023-03-14 14:56:40,743 WARN  [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-3) Server websocket is not ready: WebSocket is closed

@melloware
Copy link
Contributor Author

So weird that is not happening for me with your project and Svelte is hot reloading fine. I can make a change in a page and see it reflected immediately and see the traffic on the websocket.

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 14, 2023

Any hint on how I could debug it to figure it out?

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 14, 2023

image

@melloware
Copy link
Contributor Author

So I have DEBUG messages in all the socket send and receive you can flip them to INFO to see any WebSocket traffic.

@melloware
Copy link
Contributor Author

melloware commented Mar 14, 2023

Interesting your error RSV1 must be clear is related to compressing the socket: websockets/ws#1140

Are you using a MacOS Chrome by any chance?

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 14, 2023

Interesting your error RSV1 must be clear is related to compressing the socket: websockets/ws#1140

Are you using a MacOS Chrome by any chance?

yes!

@melloware
Copy link
Contributor Author

One commenter wrote:

I'm getting the same error if the client connecting is from MacOS/Chrome, but NOT from Windows/Chrome. What can I do on the Server or Client to be able to connect from MacOS?
I can't make it work on the Mac. Same code everywhere.... :-(

@melloware
Copy link
Contributor Author

Can you try Safari on MacOS? I have been using both Chrome and Firefox on Windows and everything works properly,

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 14, 2023

It's working on Safari but the problem is in the Quinoa WS code as it works with Chrome if I add this:

server: {
    port: 5173,
    host: '127.0.0.1',
    hmr: {
      port: 5173,
      host: '127.0.0.1',
    }
  }

@melloware
Copy link
Contributor Author

Yeah but I think this line...

 hmr: {
      port: 5173,
      host: '127.0.0.1',
    }

Bypasses our 8080 route and just goes right to 5173. Which is totally fine. But its just weird the passthrough socket doesn't work with that error on Chrome on Mac OS.

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 14, 2023

Yeah but I think this line...

 hmr: {
      port: 5173,
      host: '127.0.0.1',
    }

Bypasses our 8080 route and just goes right to 5173. Which is totally fine. But its just weird the passthrough socket doesn't work with that error on Chrome on Mac OS.

Yes that's what I meant, it means the problem is not Chrome Mac or the Node server as it works when bypassing.

@melloware
Copy link
Contributor Author

OK what Node version are you using?

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 14, 2023

With the reproducer project, it's the one specified in the application.properties 16.17.0

@melloware
Copy link
Contributor Author

oK yeah I tried 16.17 and 18.8.0 and I can't reproduce your issue .

@melloware
Copy link
Contributor Author

melloware commented Mar 14, 2023

OK I pushed a fix not to forward websocket headers on to Vite. Can you try again?

It also gets rid of that strange socket error Invalid object PooledUnsafeDirectByteBuf(freed)

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 15, 2023

It's still failing but I have been debugging all morning and I made a bit of progress.. I'll let you know..

@melloware
Copy link
Contributor Author

Awesome. I appreciate it. I wish I could make it happen regularly so you didn't have to debug it!

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 15, 2023

Ok I added a commit:

  • Add the config to disable websocket for the dev server
  • Add the config to make the devserver not managed by Quinoa (started manually). I used it to debug the NodeJS part.
  • Add "*" as Allowed Subprotocols to the Vertx config when WebSocket is enabled (this is what fixed the issue)
  • Added Client close on Server close
  • Stop fowarding the Upgrade request as http as it was generating weird logs (Invalid object PooledUnsafeDirectByteBuf(freed))
  • Separate the WSHandler class to allow separate logging (better for debugging)
  • Clean logs to allow better debugging

Most of the things where added to allow me to debug the problem but are good to keep.

Thanks @tsegismont you saved my day !

@ia3andy
Copy link
Collaborator

ia3andy commented Mar 15, 2023

@melloware now we are waiting for your review :)

I've tested vite, react and angular, and it works like a charm!

Also if ok, please squash it all to one commit.

@melloware
Copy link
Contributor Author

testing it now!

@melloware
Copy link
Contributor Author

melloware commented Mar 15, 2023

OK tested NextJS and Vite on Windows and both looking good.

@melloware
Copy link
Contributor Author

I think this is safe to merge!

@melloware
Copy link
Contributor Author

Commits Squashed

@ia3andy ia3andy merged commit 37cd18f into quarkiverse:main Mar 15, 2023
@ia3andy
Copy link
Collaborator

ia3andy commented Mar 15, 2023

Thanks @melloware this is a very good contribution!!!

@melloware
Copy link
Contributor Author

I appreciate the assist this make this Extension even more awesome for people to adopt!

@melloware melloware deleted the nextjs-268 branch March 15, 2023 18:32
@ia3andy
Copy link
Collaborator

ia3andy commented Mar 15, 2023

@all-contributors please add @melloware for code, doc

@allcontributors
Copy link
Contributor

@ia3andy

I've put up a pull request to add @melloware! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for React NextJS Handle websocket in dev-mode or document that it is not forwarded (HMR)
2 participants