-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
feat: native support for Websockets #12973
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
base: main
Are you sure you want to change the base?
Conversation
…ionality for different handlers at different URLs, added example use cases to options-2 test app, added upgrade function for supporting additional adapters, and much more.
🦋 Changeset detectedLatest commit: 24e8475 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
preview: https://svelte-dev-git-preview-kit-12973-svelte.vercel.app/ this is an automated message |
@LukeHagar LMK, if you need any help with this (you can reach me also on discord |
Sorry to reopen the thread again. I was very excited about WebSockets, and even if it’s not as perfect as intended, there should at least be a branch for testing and using crossws in the meantime, while the perfect solution is being worked on. |
We'll be sharing some thoughts very soon on how we plan to evolve data loading in SvelteKit, and real-time is part of that, but we're mainly thinking about unidirectional stuff (i.e. SSEs). Curious if people have use cases for WebSockets specifically, rather than real-time more broadly? |
Personally, I use SvelteKit quite a bit with real-time games, where data needs to be sent between the client and server bidirectionally at a fairly constant rate. To my knowledge, using a technique like SSE would require every client to server interaction to create a separate request, adding a lot of overhead for updating variables that need to change quickly, like position. I'm currently using this PR to develop another game, and I've found it to be a very smooth experience when compared to external methods that I've used in the past, which add many complications in server setup and deployment. (This comment isn't really about the PR, just answering the use-cases question above) |
I will use this PR as well. I haven’t had any issues with it so far — I almost finished a game engine using it. I thought it was heading in a good direction. To answer the question: I use bidirectional communication 99.9% of the time, much more than SSE — not just for games, but also for other projects I’m starting to develop for the company I work for where we need websockets. This was something no other framework offered, and it was truly revolutionary. |
We are using Sveltekit + websockets in two different projects. One is a semi-real time gaming system. The other project is an MVP that needs to handle continuous interaction with thousands of remote systems (which themselves are in production). We are not using this PR build directly, but I used it as an inspiration to write a custom vite plugin which works mostly fine. The former project (gaming system) was earlier using SSE (since I hadn't figured out sveltekit+websocket back then). But SSE was a pain to work with. The connection sometimes doesn't close cleanly on the server, eating server resources. And because it's unidirectional, you need to have a separate route for client initiated communication. I don't really see the point of going back to SSE, when a much more capable alternative exists. |
I would definitely agree that a perfect solution here would allow for native support for SSE, WebSockets, and WebTransport, and the ability to use them independently. I am greatly excited to hear more about the Svelte team's plans for the direction here, and excited for a sveltey WebSocket experience |
I actually agree with @Rich-Harris — a lot of developers aren’t even aware that things like Server-Sent Events exist. Most just default to WebSockets and assume that’s the only option for real-time communication. Since SvelteKit is positioning itself as the go-to framework, it really makes sense for it to support all the common real-time patterns — not just WebSockets, but also SSE and others. |
Here's the RFC for Remote Functions we just published, which hopefully gives you an idea of the broader context. Essentially, we want to separate data fetching from routing. Not shown in the RFC is this idea for streaming real-time data from the server —
This would be powered by Server Sent Events, and would thus be available on every platform that supports streaming responses. It's a good approach because it works the same way everywhere and works very naturally with serverless platforms. It also has limitations — there's per-request overhead, and it's one-way only. So my question in #12973 (comment) was trying to gauge how many use cases would be satisfied by this design, vs something that is specifically backed by Hope this provides some clarity — I realise that many of you are chomping at the bit for this stuff to be built in! |
Awesome. This sound like something that is trending in the direction I enjoy.
This seems relevant: I work on apps that push data pretty fast, so keeping a websocket open makes sense. I really like doing bidirectional communication over persistent websockets, because opening new connections for every request seems like not the best thing, when you are receiving lots of data regularly anyways. |
I believe the statement regarding server sent events and platform compatibility is referring to there being hosting platforms that do not support web sockets server side, Vercel being a good example. |
I am not sure, but I think it boils down to long running processes are not typical of most hosting options that uses runtime like workerd. If you want them, you need to host it yourself using Bun, Node, Deno, etc. So far, I have not been able to get SSE or WebSockets to work at all with these platforms like Vercel or Cloudflare, but have running my apps via the Bun runtime in an OCI container like Docker with zero issues. Going serverless means restricting what runtime features are present. To leverage long-running process type hosting (not serverless), I typically use Svetle's node adapter even though I am using bun, then pass the --bun flag during runtime like this |
The functionality is available in Cloudflare Workers (link). I personally had no issues when I tried it out, but I did not try it with a complex application. |
I'm building a multiplayer music studio. I use WS for signalling for WebRTC and keeping a general tab on users in rooms etc. I use Socket.io mainly because it provides a bunch of niceties such as room management etc that is actually quite fiddly to get right just using vanillla JS. | I also use it to keep track in memory of the current "music game state" which is then periodically saved to Mongo based on updates from users and provided to users when they join. I also use websockets to determine the current "time" - ie User pings GET_TIME and then adds half of the round trip. Not sure if there's anything there that goes beyond typically "live multiplayer game", but that's above my pay grade ;-) Currently this is all node as a separate node server which adds a bit of faff and deployment fiddling, though the separation of concerns is a positive. |
As someone who has been using SSE with Sveltekit for a couple years now, this sounds great. I have yet to face a problem that required me to use WebSocket. I have a question will every Since if each stream uses it's own endpoint and connection, having multiple real time streams is inefficient, especially on servers. |
Yes, the plan is to re-use the same connection for multiple |
Websockets allow binary data SSE does not. Automerge uses binary data to sync efficent conflict free replication data structures (Google docs style multi user experiences). Svelte's reactive nature makes it a good fit for these kinds of realtime multi user apps. |
This is looking great! Please make sure there's a way to catch client disconnects on the server. In ORTC we are given an AbortSignal that we can use to cancel/cleanup the server side resources if the SSE connection is dropped. export const time = query.stream(async function* ({signal}) {
signal.addEventListener("abort", () => { /* ...cleanup... */ })
//...
}); This also very useful for all the other libraries that use the same pattern, you can just pass this along instead of making your own AbortController. |
This looks really nice! Is there a method to get URL slugs from a peer connection? Right now the only way to get the slug is during the upgrade connection and by manually parsing the peer.request.url string (as far as I know). |
This is really great change coming into SvelteKit. I am wondering what prevents it from being merged into main-stream except for the single step that says 'Update language tools +server exports validation' . I have been a long term user of Svelte. I hope I can contribute if there is anything that can be done. |
|
I know your feeling bro. I havent been programming in a while, i'm also waiting for this to become merge into the main-stream, i dont know why they keep delaying such an important feature. AI is winning the race :( |
This is the most wanted new feature for me when it comes to sveltekit. As a adapter-node user I was a bit worried that something like this would not be pursued as it didn't fit with some serverless adapters (eg. vercel) but I'm glad to be proven wrong. This together with the new remote functions capability feels great. Personally I would mainly use it for unidirectional (push) events at the moment, but I suppose having support for both SSE and websockets would be nice. Really hope this is high on the "coming next" list. |
It's crazy to think that remote functions just dropped, and now all I want is remote functions and My usecase is a conversational AI app, and I need to continuously send data both ways. @Rich-Harris Thank you for all these amazing features! Eagerly waiting for websockets <3 |
This PR works for me where |
I'll second this, I have many uses for the native Websocket protocol, which are not usable when the endpoints and connections are all abstracted away |
This PR is a replacement to #12961 with a completely different Websocket implementation using
crossws
that should be fully compatible with all major runtimes.Functionality has been validated locally using basic tests in the
options-2
test app.Here is the new usage experience.
+server.js
The newest implementation allows different sets of handlers to be implemented on a per-route basis. I have tested some basic uses of websockets locally to much success.
This PR is intended to:
Resolve #12358
Resolve #1491
Steps left
+server
exports validationPlease don't delete this checklist! Before submitting the PR, please make sure you do the following:
Tests
pnpm test
and lint the project withpnpm lint
andpnpm check
Changesets
pnpm changeset
and following the prompts. Changesets that add features should beminor
and those that fix bugs should bepatch
. Please prefix changeset messages withfeat:
,fix:
, orchore:
.Edits