admin管理员组

文章数量:1241098

I am in a situation where I want to do different things depending on the following two possibilities:

  1. If a disconnect occurs because the page has been unloaded
  2. If a disconnect occurs through other means

Right now, by default I keep players logged in to the game for two minutes if they disconnect. This is because unpredictable disconnects can occur. But this means that any player that leaves the game on purpose will linger, which I want to prevent.

The solution I attempted was this:

On the client,

window.addEventListener('beforeunload', () => {
    this.socket.emit('manualDisconnect')
})

On the server,

import { Event } from '../lib/types'
import { logout } from '../lib/utils/logout'

const ManualDisconnect: Event = {
    name: 'manualDisconnect',
    lobbyRequired: false,
    handler: ({ player }) => {
        player.socket.disconnect()
        logout(player.id)
        console.log(`${player.profile.displayName} was manually disconnected.`)
    }
}

export default ManualDisconnect

This solution works okay on some browsers, but it is unreliable. According to some comments in the socket.io code, Firefox and Chrome have different behaviors concerning their onbeforeunload disconnect events.

Another solution I tried was to use the disconnect event reason to determine if a socket connection was closed due to the page unloading. The reason for disconnects from the page unload event is "transport close" which according to the documentation can also be a reason for a disconnect if the user just loses connection or switches from wifi to 5G, which is the opposite of what I would have hoped.

If you have any suggestions on how I can tell whether or not a disconnect was due to a page unload, I would greatly appreciate it! Thank you.

I am in a situation where I want to do different things depending on the following two possibilities:

  1. If a disconnect occurs because the page has been unloaded
  2. If a disconnect occurs through other means

Right now, by default I keep players logged in to the game for two minutes if they disconnect. This is because unpredictable disconnects can occur. But this means that any player that leaves the game on purpose will linger, which I want to prevent.

The solution I attempted was this:

On the client,

window.addEventListener('beforeunload', () => {
    this.socket.emit('manualDisconnect')
})

On the server,

import { Event } from '../lib/types'
import { logout } from '../lib/utils/logout'

const ManualDisconnect: Event = {
    name: 'manualDisconnect',
    lobbyRequired: false,
    handler: ({ player }) => {
        player.socket.disconnect()
        logout(player.id)
        console.log(`${player.profile.displayName} was manually disconnected.`)
    }
}

export default ManualDisconnect

This solution works okay on some browsers, but it is unreliable. According to some comments in the socket.io code, Firefox and Chrome have different behaviors concerning their onbeforeunload disconnect events.

Another solution I tried was to use the disconnect event reason to determine if a socket connection was closed due to the page unloading. The reason for disconnects from the page unload event is "transport close" which according to the documentation can also be a reason for a disconnect if the user just loses connection or switches from wifi to 5G, which is the opposite of what I would have hoped.

If you have any suggestions on how I can tell whether or not a disconnect was due to a page unload, I would greatly appreciate it! Thank you.

Share Improve this question asked 2 days ago trevdevtrevdev 11 bronze badge New contributor trevdev is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
Add a comment  | 

1 Answer 1

Reset to default 0

You can use pagehide event. According to chrome, pageHide is more reliable than beforeunload. But again, like other events, this event is not reliably fired by browsers, especially on mobile.

For more information:

  • https://developer.chrome/docs/web-platform/deprecating-unload#alternatives_to_unload_events
  • https://developer.chrome/docs/web-platform/page-lifecycle-api
  • https://developer.mozilla./en-US/docs/Web/API/Window/pagehide_event

本文标签: How do I know if a disconnect occurred due to the beforeunload event in socketioStack Overflow