search

Home  >  Q&A  >  body text

How to save user session information when user closes website

I'm trying to build user replay session functionality for a website, and I'm using the rrweb library to do this.

What this library does is when recording: it captures all the events in the web page and I can save these events by storing them in an array and when I want to replay the session I just Pass array to the replay function, which handles session replay.

Currently for testing purposes I am saving this array in my sessionStorage and every time a new event is emitted I get the array and then push that new event to which then save sessionStorage again in my sessionStorage like this: < /p>

rrweb.record({
    emit(event) {
        const sessions = JSON.parse(sessionStorage.getItem('sessions')) || [];
        sessions.push(event);
        sessionStorage.setItem('sessions', JSON.stringify(sessions));
    },
});

However, for production, I don't want to save that array in my sessionStorage and then update it every time a new event is emitted, but instead save that array in in my database, and I want to call a function that saves the array when the user exits or when the user decides to close the site (like pressing the X button), once to my database.

Part one - when the user logs out - very simple, I just added an eventListener on the logout button, here is the second part - when When a user decides to close the site - this gives me a bit of a headache.

I know there is a beforeUnload event, but after a quick search it became clear to me that it is unreliable, so basically what I'm looking for is a reliable way to determine when the user Closing my website so I can trigger the async function will save the array to my database.

P粉725827686P粉725827686252 days ago458

reply all(1)I'll reply

  • P粉492959599

    P粉4929595992024-03-22 10:27:35

    Here are my thoughts on how to mitigate the unreliability of the beforeunload event:

    1. When the page is loaded for the first time, get and save the current number of entries in the sessions array. Assuming we are talking about a single page that you wish to replay, you can save this count as a JavaScript variable eventCount. Better would be to get the count from a server side table in case for some reason the last time the page was closed it didn't successfully save all logged events.
    2. Schedule a function to be called every N seconds using the window's checkEvents (you must decide how often this function is called) setInterval method. This function will look at the current event count (variable newCount) and if it is greater than the current eventCount value, the Navigator sendBeacon method can be used to send a message to the server Send a request, passing all events added since the last call (i.e. JSON.stringify(sessions.slice(eventCount, newCount)) and when the request completes assign eventCount = newCount if newCount is > eventCount. Note that new events may be generated when an asynchronous sendBeacon request runs, which is why we update the event count using newCount instead of sessions the current size of the array.
    3. When unloading the page, you need to perform a final sendBeacon request. Since we know that the beforeunload and unload events are unreliable, we use the visibiltychanged event (if the browser supports it) when the new one is visible We update the server when the sexual status is "Hidden". The documentation discusses user actions that cause this event to be triggered (not just when closing the page). However, if the browser does not support this event, the <必须使用 code>pagehide event.
    The documentation for the

    Navigator.sendBeacon method does not discuss whether there can be multiple concurrent requests. Assuming it's possible (this is an asynchronous call), the user may decide to leave the page or close it due to the setInterval while the sendBeacon request is currently in progress. transfer. Then, the server URL you post this request to should probably lock the table while performing the insert, so that any subsequent POST to that URL will block until the previous one completes. If your table uses some kind of sequence number as a primary key, another solution I would suggest is to pass the starting array index of the first event passed to the server, and the server will use that to explicitly set the sequence for each event No. insert event. Concurrent updates can then be run without locking the entire table.

    reply
    0
  • Cancelreply