Reconnect LiveView on `online event` of browser window, instead of trying to reconnect at a time interval (default behaviour)

I am in the position that I need to add some offline functionality to a LiveView. Therefore, I want to circumvent the default connecting and reconnecting behaviour of LiveView. The LiveView should only try to connect when there is an internet connection on page load or whenever connection is made to the internet.

A service worker handles caching of the initial html render (and some other assets). Whenever the page is loaded without an internet connection, the “dead view” loads from the cache. However, LiveView keeps trying to establish a connection until an internet connection is made.

I would like to disable this feature and, instead, reconnect to the LiveSocket on window.addEventListener('online', () => {}).

I have been digging around in the source code of LiveView and the window.liveSocket object to see if there are any built-in functions I could leverage, but so far without success. Specifically, I have set liveSocket.maxReloads = 0 and overwrote the default timeout value to 99999999999 (new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}, timeout: 999999999})), but that did not help.

Any ideas?

Manually disconnecting and connecting the LiveSocket also does not get rid of the default reconnecting behaviour.

let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})

if (window.nagivator.onLine === true) {
  liveSocket.connect()
}

window.addEventListener('offline', event => {
  liveSocket.disconnect()
})

window.addEventListener('online', event => {
  liveSocket.connect()
})

Ignore this. This doesn’t make sense.

But I still haven’t been able to get a smooth transition from offline to online, or the other way around. It may seem out of the ordinary to use LiveView and also want offline functionality, but I reckon it could work nicely.

Of course I could hide the reloading message with css :slight_smile: , but that does not seem like such an elegant “solution”.

I found that detecting online/offline is not easy, and you can’t rely on browser events. The worst case is when you’re in this in-between state that in theory, you’re online but in practice the connection is sketchy. I ended up writing a custom connection monitor. It’s just Phoenix Channels app, however, so no LiveView.

I think @chrismccord in his very useful LiveBeats demo app is measuring Ping to server and determines the online/offline based on that, if I understand the code correctly, and it’s LV app so I recommend you have a look at it and maybe it’s useful: live_beats/app.js at e5c15c7166d271911f6df81e710f77ad45a673f1 · fly-apps/live_beats · GitHub

2 Likes

I looked at LiveBeats before, but not specifically for this. Good idea. Ty.

I’m working with CRDT, so being offline keeps some of the core functionality of the app. Or at least, that’s the idea. So I might get away with: in case of doubt about online/offline, disconnect LiveView.

I thought about not using LiveView at all. But the online version of the website benefits from it quite a bit. Or at least, less code needed to write some of the online functionalities.

Also, live navigation and, in particular, having the ability to create live components that don’t reload across page navigation is very welcome.

So that’s another reason to hold on to LiveView.