Je suis coincé dans un scénario et j'ai besoin de votre contribution. Actuellement, je travaille sur une fonctionnalité qui consiste à verrouiller la réservation pour d'autres administrateurs. J'ai créé un champ dans la table des réservations où je mets le user_id lorsqu'un administrateur entre dans la réservation, les champs sont mis à jour avec l'ID administrateur actuel et d'autres administrateurs ont accès à cette réservation pour le moment.
Le problème est donc si l'utilisateur ferme l'onglet, la réservation reste également verrouillée pour les autres administrateurs.
J'ai essayé de nombreuses façons différentes dans vueJs telles que la méthode beforeunload
.
J'ai utilisé les méthodes Xhr et axios échouent tous les deux dans cette condition.
Que puis-je faire d'autre pour résoudre ce problème
removeUser (id) { let payload = { locked_by: '', id: id } this.updateIsLockedField(payload).then(() => { console.log('updated') return 'something' }) },
mounted() { window.addEventListener('beforeunload', this.removeUser)
a également essayé l'appel axios sur l'événement avant déchargement
removeUser () { var params = JSON.stringify({ locked_by: '' }); let xhr = new XMLHttpRequest() xhr.open('PUT',Url, true) xhr.setRequestHeader("Authorization", 'Bearer ' + localStorage.getItem('app_access_token')) xhr.setRequestHeader("Content-length", params.length); xhr.setRequestHeader("Content-type", "application/json; charset=utf-8") xhr.responseType = 'arraybuffer' xhr.onreadystatechange = function() {//Call a function when the state changes. if(xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } } xhr.send(params);
3 Réponses :
Il n'y a aucun moyen fiable d'exécuter quelque chose à la fermeture de l'onglet / de la fenêtre. Cela va à l'encontre du principe même de «fermer» l'onglet, c'est-à-dire de libérer des ressources.
La façon dont je gérerais votre situation est de laisser le frontend contenir quelque chose qui meurt de lui-même lorsque l'onglet se ferme.
Soit ouvrez un websocket que vous pouvez utiliser à de nombreuses autres fins, et quand il meurt et ne revient pas dans quelques secondes, vous savez que le client est déconnecté, ou envoyez un ping régulier lorsque l'onglet est ouvert et quand il a manqué quelques pings, vous pouvez supposer que le client est déconnecté.
Je suppose que vous avez raison, je dois utiliser Websockets pour écouter l'événement lorsque l'utilisateur est déconnecté.
Essayez de faire une requête de synchronisation en passant un faux à la méthode open
: xhr.open ('PUT', Url, false)
removeUser () { var params = JSON.stringify({ locked_by: '' }); let xhr = new XMLHttpRequest() xhr.open('PUT',Url, false) // `false` makes the request synchronous xhr.setRequestHeader("Authorization", 'Bearer ' + localStorage.getItem('app_access_token')) xhr.setRequestHeader("Content-length", params.length); xhr.setRequestHeader("Content-type", "application/json; charset=utf-8") xhr.responseType = 'arraybuffer' xhr.onreadystatechange = function() {//Call a function when the state changes. if(xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } }
Ainsi, Vuejs vous propose plusieurs hooks, l'un d'eux est le destroy, ce hook sera appelé si l'instance de vue est fermée, dans tous les cas, cela inclut le navigateur fermé, quelque chose comme:
destroyed() { callYourFunctionName }
Je travaille actuellement sur un système identique au vôtre, nous devons déverrouiller les données lorsque l'utilisateur quitte, après de nombreuses recherches, malheureusement, il n'y a aucun moyen de garantir que votre fonction mettra fin à sa logique avant la fermeture du navigateur si vous demandez une fonction prendre un peu de temps, cela ne fonctionnera probablement pas = /.
Ici, nous faisons ce premier essai dans le hook destroy (), et notre application a un deuxième facteur de sécurité qui déverrouille tout registre après 10 minutes d'utilisateur afk.
J'espère que cela aide
Il n'y a pas de moyen fiable à 100% de faire ce que vous essayez de faire; l'onglet du navigateur peut se fermer de différentes manières sans que votre code ait aucune chance de s'exécuter. (Considérez que l'alimentation peut tomber en panne.) Généralement, ce genre de problème est résolu en associant une limite de temps à chaque verrou.
Quel sera un bon scénario pour cela? Du point de vue du backend et du front-end
Vous ne pouvez pas savoir à 100% quand un onglet est fermé, mais vous pouvez surveiller si l'onglet est toujours ouvert. Votre interface doit envoyer une requête xhr chaque fois pour actualiser le temps de recharge de la suppression du verrou.
Oui, je suggérerais que vous puissiez atteindre un point final à chaque fois, comme le dit @iguypouf. Vous pouvez mettre à jour un champ dans une base de données qui ressemble à 'last_active_at' et si cela n'a pas été mis à jour par exemple 60 secondes, puis déverrouillez.
Je ne ferais aucune sorte de solution côté client. L'acquisition d'un verrou sur le serveur peut se faire en supprimant d'abord tous les verrous qui ont été inactifs pendant plus que la durée choisie (10 minutes peut-être). Ensuite, s'il y a toujours un verrou actif, la tentative échoue - vous devez quand même gérer cela. S'il n'y a pas de verrou actif, la tentative réussit. Chaque action ultérieure pendant que le verrou est actif doit mettre à jour l'horodatage.