Usually, when a client disconnects, it closes the TCP socket on both ends and we can send the "member removed" event immediately. However, certain situations can result in the client not cleanly disconnecting, and leaving a "half open connection" where a client will still be seen as online by the server even though they aren't connected. We find and close these half open connections by sending a ping to the client after a certain period of inactivity, and then if no pong response is received, the connection is assumed dead and closed. This can take a couple of minutes to happen.
The timeout for inactive connections in Pusher is 200 seconds. After the 200 seconds a ping is sent and if a pong is not received within 30 seconds then the connection is cleaned up. This means that Pusher can indicate a connection is open for up to 230 seconds before cleaning up.
You can tweak the amount of time before a ping is sent, and the amount of time to wait for a pong, by changing the activityTimeout and pongTimeout in the options object that gets passed to the Pusher constructor: https://pusher.com/docs/client_api_guide/client_connect#options_parameter. It might be worth experimenting with some different values for these if you are often seeing problems like this.