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

Handle websocket in dev-mode or document that it is not forwarded (HMR) #71

Closed
ia3andy opened this issue May 30, 2022 · 8 comments · Fixed by #270
Closed

Handle websocket in dev-mode or document that it is not forwarded (HMR) #71

ia3andy opened this issue May 30, 2022 · 8 comments · Fixed by #270

Comments

@ia3andy
Copy link
Collaborator

ia3andy commented May 30, 2022

Some NodeJS dev-server don't allow to set the websocket port for for hot reload. Currently those websocket connection are not forwarded by Quinoa.

Some other dev-server like Vite allow to change the HMR port, then http is sent and forwarded by Quinoa and HMR is sent to the frontend dev-server (which works great).

@ia3andy
Copy link
Collaborator Author

ia3andy commented May 30, 2022

When stopping the dev mode, it might end up with an exception:

022-05-30 13:52:08,679 INFO  [io.qua.qui.dep.PackageManager] (Thread-40) Stopping Quinoa package manager live coding as a dev service.
2022-05-30 13:52:08,698 ERROR [io.ver.cor.net.imp.ConnectionBase] (vert.x-eventloop-thread-2) Connection reset
2022-05-30 13:52:08,699 ERROR [io.qua.qui.QuinoaDevProxyHandler] (vert.x-eventloop-thread-2) Quinoa failed to forward request, see logs.: java.net.SocketException: Connection reset
	at java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:394)
	at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:426)
	at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:258)
	at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1132)
	at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:350)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
	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)

@ia3andy
Copy link
Collaborator Author

ia3andy commented May 30, 2022

@cescoffier any idea on how we could listen/forward websocket events?

@cescoffier
Copy link

@ia3andy
Copy link
Collaborator Author

ia3andy commented May 30, 2022

Did you look at vertx.io/docs/vertx-core/java/#_websockets?

@cescoffier yes I did. But here are my issues:

  • How to know if I should handle a given event or not (what if there is a Quarkus Websocket server also)
  • How to send event the npm server from Vertx (client in the doc is JS)
  • The Quarkus Vertx http server is not accessible from an extension and there is no BuildItem for it. I am not sure it's a good idea to create another one?

@cescoffier
Copy link

I don't understand your first point. Web sockets are not a publish/subscribe thing, it's end to end.
I believe you can receive the request and upgrade to a web socket.

About the second point, do you have a channel of communication? A web socket maybe?

About the third point, yes, but a simple route upgrading the connection to a web socket is generally much better.

@ia3andy ia3andy changed the title Handle websocket in dev-mode or document that it is not forwarded Handle websocket in dev-mode or document that it is not forwarded (HMR) Nov 8, 2022
@melloware
Copy link
Contributor

melloware commented Mar 10, 2023

@cescoffier maybe you can help here. We receive a WebSocket request on 8080 but we need to forward it to 3000 (NextJS).

        if (headers.get("Connection").contains("Upgrade")) {
            LOG.infof("Quinoa is forwarding web socket: '%s'", request.uri());
            Future<ServerWebSocket> fut = request.toWebSocket();
            fut.onSuccess(serverWs -> {
                LOG.infof("Quinoa is forwarded web socket: '%s'", request.uri());
                WebSocketConnectOptions options = new WebSocketConnectOptions()
                        .setHost(request.localAddress().host())
                        .setPort(port)
                        .setURI(uri)
                        .setAllowOriginHeader(false);
                httpClient.webSocket(options, res -> {
                    WebSocket clientWs = res.result();
                    clientWs.pipeTo(serverWs);
                    serverWs.pipeTo(clientWs);
                    LOG.infof("Connected! ");
                });
            });

But essentially the goal is we are trying to forward and 8080 WebSocket to 3000 and keep it open for two way communication.

I can see the Next ping-pong but something still isn't working.

image

@melloware
Copy link
Contributor

melloware commented Mar 10, 2023

OK I think I found the issue. when running raw Next the event.data is a JSON string.

image

When receiving it from VertX it is a Blob not a string and its breaking Next.

image

So I am wondering how to have VertX send strings back instead of Blobs?

@melloware
Copy link
Contributor

I got it all working for both NextJS and Vite. PR on the way...

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 a pull request may close this issue.

3 participants