analogjs / analog

The fullstack meta-framework for Angular. Powered by Vite and Nitro
https://analogjs.org
MIT License
2.53k stars 241 forks source link

Looking for a possibility to also stream data from backend to frontend #732

Closed alaendle closed 9 months ago

alaendle commented 11 months ago

Which scope/s are relevant/related to the feature request?

trpc

Information

Currently I believe that this could only be achieved with some kind of WebSocket support.

One possible way (and maybe the most comfortable from a user perspective) might be to support to trcp's wsLink/subscription mechanism (https://trpc.io/docs/subscriptions). As I'm looking for a workround, I'm missing some entry-point during the application startup that allows me to inject some code that starts just an independent WebSocket-Server - did I miss something? A pure Angular universal application offers the server.ts, but I haven't found something similar for an Analog application (also no option to inject a startup procedure).

And please forgive me if I remain so vague at first, but there are so many ways to basically fulfill this requirement that it seems difficult for me to formulate this more precisely at the moment - especially because I simply lack the experience in web development.

Describe any alternatives/workarounds you're currently using

No response

I would be willing to submit a PR to fix this issue

goetzrobin commented 11 months ago

I did some digging and it seems like websockets are not "natively" supported by nitro, which is what we use as a server (yet.) There seems to be ways to use hooks to attach a e.g. socket.io server that would enable this. Heres are the GitHub issues for your reference: https://github.com/nuxt/cli/issues/108 https://github.com/nuxt/nuxt/pull/19230#issuecomment-1475933592

Which brings me to your question about trpc subscriptions. Right now the trpc client does not support that, which means some changes have to be made to it to enable support. However, trpc is not a necessity to interact with sockets. RxJs seems to actually support this pretty "natively" with this: https://rxjs.dev/api/webSocket/webSocket. Which fits pretty well into the Angular Clients idea of Observables for API calls.

Maybe this article is helpful: https://craigsh.dev/blog/robust-websockets-using-rxjs/

alaendle commented 11 months ago

Thank you @goetzrobin for the hint for the nitro plugin - this was exactly the piece I've missed. So with this it is easy to startup a separate websocket/socket.io server.

However at least to me this all feels like a strange workaround for something that should be more straight forward (e.g. I haven't found a good solution/hook for shutting down the socket server to allow code reload (without address/port in use exceptions) in the development server). I also tried to use the exiting server for websockets communication (like discussed here: https://github.com/nuxt/nuxt/discussions/16663) - however I've failed so far.

I more and more tend to avoid socket communication and use server sent events instead (also inspired by this issue https://github.com/trpc/trpc/issues/544 and the mentioned blog post https://wundergraph.com/blog/deprecate_graphql_subscriptions_over_websockets) ...

As I'm now able to basically implement what I need - and also since the better support of some kind of streaming mechanism seems to mainly depend on the progress of other tools/libraries I think we could close this issue for now - unless someone wants to look into the matter in more detail 😉

Again - many thanks for your kind support.

goetzrobin commented 9 months ago

@alaendle hey there! Just wanted to follow up on this and see if you got this to work! server sent events seems like a good option! curious to learn more about your experience here!

alaendle commented 9 months ago

Hi @goetzrobin, thank you for asking, but to be honest I haven't been able to delve deeper into it yet. So it's still the same situation (https://github.com/analogjs/analog/issues/732#issuecomment-1803498575) - in principle it works, it just feels wrong.

The question of the "right" way came up in a larger project - where we might want to combine an existing nestjs backend and a angular frontend into a single angular SSR application. Therefore, the question of streaming data is just one piece of the puzzle - my feeling is that using SSE will improve the situation (and not even/only because of the technology, but simple because data could only flow from the server to the client which would enforce a much cleaner communication design - not in general, but in the context of our application), but the potential impact cannot yet be fully assessed.

If we really continue, I'll definitely get in touch again 😉 .