Skip to content

fix: handle websocket connections using experimental deno:request event#3446

Closed
CertainLach wants to merge 1 commit into
freshframework:mainfrom
CertainLach:fix/handle-websocket-connections
Closed

fix: handle websocket connections using experimental deno:request event#3446
CertainLach wants to merge 1 commit into
freshframework:mainfrom
CertainLach:fix/handle-websocket-connections

Conversation

@CertainLach

@CertainLach CertainLach commented Sep 16, 2025

Copy link
Copy Markdown
Contributor

Comment on lines +20 to +24
if (
headers.get("upgrade") !== "websocket" ||
// Vite uses websockets with protocol set to vite-hmr, vite-ping
headers.get("sec-websocket-protocol")?.startsWith("vite-")
) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I wish every non-vite request was going through this route, as the current implementation looks too fragile

It is however only required and used for websocket for now.

@DontMash

Copy link
Copy Markdown
Contributor

@marvinhagemeister
I'm really interested in this fix and would also like to help.
You mentioned (#3554 (comment)) that this change will likely not be merged since

it deviates from the web platform

What would be your approach if intercepting the request is not the correct way.

@marvinhagemeister

marvinhagemeister commented Oct 29, 2025

Copy link
Copy Markdown
Contributor

@DontMash Create a Fresh cli that calls vite as a middleware. That's the proper solution. This PR can't be merged because it depends on another PR being merged into Deno itself. The PR for Deno is very unlikely to be merged.

@DontMash

DontMash commented Nov 1, 2025

Copy link
Copy Markdown
Contributor

Create a Fresh cli that calls vite as a middleware.
What do you mean by cli and how to use vite as a middleware?

Should App provide a websocket command to define a websocket route and use vite as a middleware?

As far as I know, the vite middleware can only be accessed when creating a server or configuring a plugin.
That is why I also assumed intercepting the request in the plugin is the best solution.

@CertainLach

CertainLach commented Nov 1, 2025

Copy link
Copy Markdown
Contributor Author

Should App provide a websocket command to define a websocket route and use vite as a middleware?

You don't need to do that with requests being Deno requests, which is default in Fresh

The problem is that vite starts a node.js http server instead, and you can't properly convert node requests back to deno requests, because node.js handles websockets differently

It is possible however to create a vite dev middleware for fresh (I.e app.use(viteMiddleware(viteConfig))), that performs compilation, and responds with built client files from vite's output MemFS (or however it is called there).

@DontMash

DontMash commented Nov 2, 2025

Copy link
Copy Markdown
Contributor

You don't need to do that with requests being Deno requests, which is default in Fresh

I know, but you still need to handle the upgrade yourself. The question was also closer related to meaning of cli in this context

The problem is that vite starts a node.js http server instead, and you can't properly convert node requests back to deno requests, because node.js handles websockets differently

I also tried to convert Nodejs websocket requests to Deno myself.

It is possible however to create a vite dev middleware for fresh (I.e app.use(viteMiddleware(viteConfig))), that performs compilation, and responds with built client files from vite's output MemFS (or however it is called there).

This would mean that just the dev_server would not be part of the plugin anymore, but rather be implemented as a middleware for fresh?

@CertainLach

Copy link
Copy Markdown
Contributor Author

This would mean that just the dev_server would not be part of the plugin anymorer, but rather be implemented as a middleware for fresh?

Exactly. It is not quite a middleware, because of how fresh handles build cache updates, but I already did that for webpack and the resulting setup works very well for me, it should work similarly for vite.

image

@bartlomieju

Copy link
Copy Markdown
Contributor

Closing — this depends on denoland/deno#30746 which was never merged and is unlikely to be (deviates from the web platform, per maintainer feedback).

The proper fix is for Deno.upgradeWebSocket() to work with node:http upgrade events, tracked in denoland/deno#33220. In the meantime, #3737 provides a working workaround using a second Deno.serve() + TCP proxy.

@bartlomieju bartlomieju closed this Apr 9, 2026
@CertainLach CertainLach deleted the fix/handle-websocket-connections branch May 25, 2026 21:29
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.

Fresh V2 Beta WebSocket upgrade request never reaches server behind vite development environment

4 participants