Liveview form keeps on refreshing every 15s

Hi,

I’ve been using liveview for a form. Sometimes the page keeps on refreshing, even if the user is typing something. It looks like it happens every 15s. here are an example in the logs


Asking the user directly he says that the page keeps on refreshing and clearing his input.
I was thinking that perhaps it was due to a bad network connection (and maybe that is), but that last occurence has been happening for somebody in the UK, and the server is in Germany.

I’m wondering how to debug this further.
Here is what I have tried so far

  • I can’t reproduce this consistently, it only happens for some users, sometimes. It looks like a heisenbug. I’ve tried opening an issue on liveview directly, but it was closed saying I don’t have a way to reproduce it.
  • I’ve checked the server load, it’s below 25% (CPU and memory both).
  • I’ve checked that the assets loaded on the page are not too heavy (just in case).

I’m not sure how to debug this further. Perhaps, liveview is waiting for an acknowledgement message from the client’s browser, and if it fails to receive it, it will trigger a reload.

I’m wondering if this ever happened to anybody else using liveview with forms.

Do you have more information from the user?
Which browser, OS and version?
Anything interesting happening in the browser console logs or the network tab?

It seems to me that this is a websockets connection problem. Is it possible to check the browser’s console for errors?

Do you have check_origin configured in your Endpoint?

check_origin: ["//*.yoursite.com"]

Are you perhaps using Google Cloud? https://stackoverflow.com/questions/46971676/phoenix-channels-socket-keeps-getting-closed-in-distributed-cluster-environment

Thank you for your answer.

The user is using safari, on his ipad and on his macbook pro.

I haven’t got any information about the browser console logs and the network tab, I’ll ask him.

check_origin is set to false.

I’ll ask about the browser console.

Thanks!

I’m not on google cloud. Running on baremetal with Hetzner.

The problem is only happening intermittently, for most of the users on production (I would say 99%, it’s fine).

Perhaps there’s something between the user and your server dropping idle connections too aggressively? You could try passing a shorter value to heartbeatIntervalMs when creating the socket, it’s documented here.

Let us know if heartbeatIntervalMs helped. I’m also planning to create small site with LiveView so I’m interested to hear about your results. I read that its default is 30s meaning 30000 ms and I feel that it’s bit high, I would try something like 5000 ms.

This thread has example how to use it Can Phoenix channel detect client offline immediately?Like WiFi disconnected

@dom @wanton7 Thanks for the idea.
Let me try that on monday, I should be able to report by the end of next week hopefully.

I tried quite hard at finding anything that references those things in liveview itself, but didn’t get to anything.

Here is my understanding. Since the idle timeout is already set at 10s, then there is nothing to do there. The only thing that needs to be changed would be the heartbeatIntervalMs. Here is how I went about it. In my app.js where you define the liveview, this is what I have

let liveSocket = new LiveSocket("/live", Socket, {
  dom: {
    onBeforeElUpdated(from, to) {
      if (from.__x) {
        window.Alpine.clone(from.__x, to);
      }
    },
  },
  params: {
    _csrf_token: csrfToken,
  },
  hooks: Hooks,
  heartbeatIntervalMs: 5000,
});

(the dom thing is coming from alpinejs intergration. I just deployed that to production, I’ll check how that works and if this has any impact.)

in the official doc it says that all options except a couple will be passed to the socket constructor

it’s true that opts are passed. Look at the last line in this code.

export class LiveSocket {
  constructor(url, phxSocket, opts = {}){
    this.unloaded = false
    if(!phxSocket || phxSocket.constructor.name === "Object"){
      throw new Error(`
      a phoenix Socket must be provided as the second argument to the LiveSocket constructor. For example:
          import {Socket} from "phoenix"
          import {LiveSocket} from "phoenix_live_view"
          let liveSocket = new LiveSocket("/live", Socket, {...})
      `)
    }
    this.socket = new phxSocket(url, opts)
1 Like

Ok, after 2 days, I think I still have one instance of this. The refresh times seem to be much shorter though.


It seems to be 15s exactly. 5s of heartbeat and 10s of timeout I’m guessing.
Not sure what values to put for a really bad network. Maybe 2s of heartbeat is too much?
How about a timeout of 5s, is that unreasonable?

If connection drops after 15s it should have had at least two heartbeats with interval of 5s. Do you have any reverse proxies in front of your app? If you do maybe it is interfering with WebSocket connection?

Actually googled this more because I was interested what this could be. Would it be possible user to be using some old browser like Internet Explorer? From what I read it only supports only 6 concurrent WebSocket connections by default. So if they open multiple tabs that do websocket connection to same domain this could cause a problem. Also not sure if it’s related but it has one timeout of 15s related to WebSocket https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330736(v=vs.85)#websocket-close-timeout

Maybe you should start logging what browser users are using?

In that case you might want to look a this: https://github.com/phoenixframework/phoenix_live_view#browser-support

1 Like

I checked yesterday, and it happened again with Mobile Safari 14.0 on iOS 14.3
So likely not due to IE.
I’m going to try to enable the debug and see what informations I can gather from it.
Will update this thread with what I find.

Any chance it could be related to this?https://github.com/socketio/socket.io/issues/2924
It seems that if in Safari you move focus to another tab or put browser to background problems start. Some suggestions there was to use visility API and disable WebSocket while tab doesn’t have focus then reconnect when it does. But this might not help with LiveView.

Edit: Also found this https://apple.stackexchange.com/questions/280679/preventing-safari-background-tabs-disconnecting-from-server that sound quite similar to what is happening to you.

Found something related to this from LiveView’s github repo written by @josevalim https://github.com/phoenixframework/phoenix_live_view/issues/1228#issuecomment-728877492