WestKeys
Replacing HTTP with Websockets (or other persistent transport)
A lot of LiveView’s advantages stem from its persistent connection model.
- No more manually handling internal http requests (vs rest)
- Server is source of truth: no more manually managing client state (vs rest / graphql)
- No more authenticating every request i.e. db round trip (vs stateless server)
Obviously the “fragmental real time html rerendering” (can’t find appropriate term) is the main innovation here and probably LiveView’s biggest selling point, but isn’t feasible on mobile today. However, I wonder whether LiveView’s persistent connection model is. If we omit UI, the not-so-LiveView-specific concept of a persistent connection to handle all requests replaces the conventional stateless request/response model, and can potentially offer all the pros enumerated above.
So I was wondering what are the cons of using this approach, specifically for mobile?
So far I have come up with the following cons:
- Lack of a standard protocol on top of the transport (i.e. websockets has numerous subprotocols without a clear winner/best practice/idiomatic one) vs HTTP
- Increase in server load to handle the persistent connections/sessions vs stateless api server
- Spotty networks on mobile
Thoughts?
Most Liked
kokolegorille
I don’t think it was personal ![]()
GraphQL over websockets is currently being standardized by the GraphQL working group.
GraphQL is transport agnostic, it works on websocket too.
I see channels as extended controllers, and liveview as extended channels, but in the end, the work is mostly done in Contexts, or Functional Core. You should be able to switch easily from one to the other.
In a request/response cycle I don’t see websocket advantage. But I see many when the server interact with the client.
chrismccord
I haven’t seen enough data to support websockets being a poor fit for mobile, at least in the context of day-to-day average use. It’s true spotty connections will suffer, but simulating 30% packet loss I don’t have WebSocket issues so it would be better to have real data to discuss and what kinds of edge users you need to support. In any case, you can use LiveView with the longpoll channel transport to go over HTTP if needed:
import {Socket, LongPoll} from "phoenix"
import {LiveSocket} from "./phoenix_live_view"
let liveSocket = new LiveSocket("/live", Socket, {transport: LongPoll, ...})
hauleth
I think that more of the problem is not spotty network, but changing network on-the-fly is more of the problem. And on mobile it can happen constantly, WiFi to cellular and back, cellular to cellular on roaming borders (for while it can be less of the problem in US, it can be quite painful in EU for example). With such situations we are back to @WestKeys point about managing client state. And managing that state isn’t that much of a problem, in the end in most cases it is one simple token that need to be stored client side.
Of course WS over QUIC could solve some of that problems, but AFAIK there is no such implementation yet. Additionally HTTP/2 and HTTP over QUIC (also known as HTTP/3) already manages most of the pain points of HTTP.
About original points:
No more manually handling internal http requests (vs rest)
You just need to manually (even more manually) handle internal requests in whatever form you want over WS. So instead of having stable and tested technology you are trying to build almost the same from the ground up using different transport?
Server is source of truth: no more manually managing client state (vs rest / graphql)
As I said earlier, you still need to manage client state in case of reconnections due to network change (as the IP will change and TCP multihoming isn’t that popular and IPv6 isn’t deployed in numbers big enough to use that feature).
No more authenticating every request i.e. db round trip (vs stateless server)
That is not true. Imagine situation where you have some kind of access control, for example RBAC:
- User creates connection with access to limited resource. You save that information in the connection state.
- Admin revokes access to given resource for our user.
- User still can access the resource, due to Write-After-Read Hazard.
So you still need to check each time whether user can access given resources. Of course, you can try to listen on events happening in application and change internal state of connection to match the expectations, but it makes flow much harder and much more prone to omission. So in general you replaced small inconvenience with possible bottleneck for a solution that requires much more complex implementation, with much more testing, and much more places where it can fail. Doesn’t seem like good approach to me.
Popular in Discussions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









