text: Title: Intermittent long delay during connection upgrade
  Body: **Summary**
  We are using `python-socketio` to push out regular service status updates to browser clients, which are using  the `socket.io` JS client library. Most of the time it works fine but we are intermittently seeing a situation where there is a ~30 second delay part-way through the connection upgrade process, and no messages are received during this time. Eventually the connection is closed (although the process looks a bit messy) and a reconnect occurs, after which everything works fine again.
  
  We can reproduce this fairly easily with a unit test that repeatedly navigates to the relevant page and away again, forcing the socket to be recreated and a connection re-established each time. We reliably run into the issue after a few iterations of this.
  
  **Versions**
  `python-socketio`: 4.3.1    (have also tried 4.4.0)
  `python-engineio`: 3.10.0    (have also tried 3.11.0)
  `socket.io JS client`: 2.3.0    (have also tried 2.2.0)
  
  **Code**
  This is a simplified version of our server code, which is running inside a Docker container within a Kubernetes pod:
  ```python
  from gevent import monkey, pywsgi
  monkey.patch_all()
  
  from geventwebsocket.handler import WebSocketHandler
  import logging
  import socketio
  import time
  
  
  logging.getLogger('socketio.server').setLevel(logging.INFO)
  logging.getLogger('engineio.server').setLevel(logging.INFO)
  
  sio = socketio.Server(
      logger=True,
      engineio_logger=True,
      cors_allowed_origins="*",
      async_mode='gevent'
      )
  app = socketio.WSGIApp(sio)
  
  
  @sio.on('connect')
  def connect(sid, environ):
      logger.info(f'Client connected with session id: {sid}')
      logger.info(f'Environment is: {environ}')
  
  
  @sio.on('disconnect')
  def disconnect(sid):
      logger.info(f'Client disconnected from session id: {sid}')
  
  
  @sio.on('join')
  def join(sid, room):
      sio.enter_room(sid, room)
      logger.info(f'Client joining room {room} in session {sid}')
  
  
  def generate_update_message():
      # Do some work here to generate the right status message
      # ...
  
  
  def update_loop():
      while True:
          # Generate and emit an update every second
          update = generate_update_message()
          sio.emit('update', update, room='admin')
          sio.sleep(0.1)
          time.sleep(1.0)
          
  
  def main():
      sio.start_background_task(update_loop)
      pywsgi.WSGIServer(('', 8080), app, handler_class=WebSocketHandler).serve_forever()
  ```
  
  The relevant bit of our client code is:
  ```javascript
  function admin_vm() {
      const self = this;
  
      self.socket = io.connect({
          path: window.config.project_url + 'status/system/socket.io'
      });
  
      self.socket.on('connect', function() {
          console.log('Socket connected, joining admin room');
          self.socket.emit('join', 'admin');
      });
  
      self.socket.on('update', function (update) {
          update = JSON.parse(update);
          const u = update;
          console.log(
              'Update for system status left server [' + u.timestamp +
              '] arrived here [' + new Date().toString() + '] update count [' + update_count++ + ']'
              );
  
          // Apply the update to the UI here...
      });
  }
  ```
  
  **Logs**
  I've captured some detailed logs of both client and server both when the connection works and when it doesn't (see attached). 
  
  [bad-client.log](https://github.com/miguelgrinberg/python-socketio/files/3940079/bad-client.log)
  [bad-server.log](https://github.com/miguelgrinberg/python-socketio/files/3940080/bad-server.log)
  [good-client.log](https://github.com/miguelgrinberg/python-socketio/files/3940081/good-client.log)
  [good-server.log](https://github.com/miguelgrinberg/python-socketio/files/3940082/good-server.log)
  
  
  When the issue occurs, the client log clearly shows the delay while it's probing for the availability of the websocket transport:
  ```
  12:58:46.220 socket.io.js 391:131 "engine.io-client:socket probe transport \"%s\" pong +7ms"   "websocket"
  12:58:46.220 socket.io.js 391:131 "engine.io-client:socket pausing current transport \"%s\" +1ms"   "polling"
  12:58:46.220 socket.io.js 391:131 "engine.io-client:polling we are currently polling - waiting to pause +8ms"
  12:59:11.356 socket.io.js 391:131 "engine.io-client:socket writing ping packet - expecting pong within %sms +25s"   60000
  12:59:17.224 socket.io.js 391:131 "engine.io-client:polling polling got data %s +31s"   ArrayBuffer(0)
  12:59:17.224 socket.io.js 391:131 "engine.io-client:polling pre-pause polling complete +2ms"
  12:59:17.224 socket.io.js 391:131 "engine.io-client:polling paused +1ms"
  12:59:17.224 socket.io.js 391:131 "engine.io-client:socket changing transport and sending upgrade packet +6s"
  12:59:17.224 socket.io.js 391:131 "engine.io-client:socket setting transport %s +1ms"   "websocket"
  12:59:17.224 socket.io.js 391:131 "engine.io-client:socket clearing existing transport %s +0ms"   "polling"
  12:59:17.224 socket.io.js 391:131 "engine.io-client:polling ignoring poll - transport state \"%s\" +4ms"   "paused"
  12:59:17.224 socket.io.js 391:131 "engine.io-client:socket flushing %d packets in socket +3ms"   1
  ```
  
  On the server side, we see part of the upgrade process and then it seems to stop (while still emitting update messages)...and eventually the server gives up and closes the socket:
  ```
  12:58:46,184 1 MainProcess DEBUG Attempting to upgrade connection - geventwebsocket.handler
  12:58:46,185 1 MainProcess DEBUG WebSocket request accepted, switching protocols - geventwebsocket.handler
  12:58:46,185 1 MainProcess INFO 6294b24868144273b4a9bceaf0e439f9: Received request to upgrade to websocket - engineio.server
  12:58:46,186 1 MainProcess DEBUG Initializing WebSocket - geventwebsocket.handler
  12:58:46,187 1 MainProcess DEBUG Validating WebSocket request - geventwebsocket.handler
  12:58:46,187 1 MainProcess DEBUG Can only upgrade connection if using GET method. - geventwebsocket.handler
  12:58:46,187 1 MainProcess INFO 6294b24868144273b4a9bceaf0e439f9: Received packet MESSAGE data 2["join","admin"] - engineio.server
  12:58:46,187 1 MainProcess INFO received event "join" from 6294b24868144273b4a9bceaf0e439f9 [/] - socketio.server
  12:58:46,188 1 MainProcess INFO ::ffff:10.0.9.139 - - [12:58:46] "POST /socket.io/?EIO=3&transport=polling&t=MxglQ0a&sid=6294b24868144273b4a9bceaf0e439f9 HTTP/1.1" 200 208 0.001325 - geventwebsocket.handler
  12:58:46,188 1 MainProcess INFO 6294b24868144273b4a9bceaf0e439f9 is entering room admin [/] - socketio.server
  12:58:46,188 1 MainProcess INFO Client joining room admin in session 6294b24868144273b4a9bceaf0e439f9 - admin.status
  12:58:46,190 1 MainProcess DEBUG Initializing WebSocket - geventwebsocket.handler
  12:58:46,190 1 MainProcess DEBUG Validating WebSocket request - geventwebsocket.handler
  12:58:46,199 1 MainProcess INFO ::ffff:10.0.9.139 - - [12:58:46] "GET /socket.io/?EIO=3&transport=polling&t=MxglQ0c&sid=6294b24868144273b4a9bceaf0e439f9 HTTP/1.1" 200 159 0.009237 - geventwebsocket.handler
  12:58:46,215 1 MainProcess INFO emitting event "update" to admin [/] - socketio.server
  12:58:46,217 1 MainProcess DEBUG Initializing WebSocket - geventwebsocket.handler
  12:58:46,217 1 MainProcess DEBUG Validating WebSocket request - geventwebsocket.handler
  12:58:47,400 1 MainProcess INFO emitting event "update" to admin [/] - socketio.server
  12:58:48,576 1 MainProcess INFO emitting event "update" to admin [/] - socketio.server
  ...
  12:59:14,619 1 MainProcess INFO emitting event "update" to admin [/] - socketio.server
  12:59:15,841 1 MainProcess INFO emitting event "update" to admin [/] - socketio.server
  12:59:17,045 1 MainProcess INFO emitting event "update" to admin [/] - socketio.server
  12:59:17,046 1 MainProcess INFO 6294b24868144273b4a9bceaf0e439f9: Client is gone, closing socket - engineio.server
  12:59:17,046 1 MainProcess INFO Client disconnected from session id: 6294b24868144273b4a9bceaf0e439f9 - admin.status
  12:59:17,046 1 MainProcess INFO 6294b24868144273b4a9bceaf0e439f9: Client is gone, closing socket - engineio.server
  12:59:17,047 1 MainProcess INFO ::ffff:10.0.9.139 - - [12:59:17] "GET /socket.io/?EIO=3&transport=polling&t=MxglQ14&sid=6294b24868144273b4a9bceaf0e439f9 HTTP/1.1" 200 155 30.829922 - geventwebsocket.handler
  12:59:17,064 1 MainProcess INFO 6294b24868144273b4a9bceaf0e439f9: Upgrade to websocket successful - engineio.server
  12:59:17,065 1 MainProcess INFO 6294b24868144273b4a9bceaf0e439f9: Received packet PING data None - engineio.server
  12:59:17,065 1 MainProcess INFO Receive error -- socket is closed - engineio.server
  12:59:17,068 1 MainProcess DEBUG Closed WebSocket - geventwebsocket.handler
  12:59:17,069 1 MainProcess DEBUG Failed to write closing frame -> closing socket - geventwebsocket.handler
  12:59:17,069 1 MainProcess DEBUG Closed WebSocket - geventwebsocket.handler
  ```
  
  As you can see in the full log, a re-connection follows and it works, but we really want to eliminate this 30 second delay as it leads to a bad user experience.
  
  **Workaround**
  As a test, we tried using the websocket transport directly instead of starting with long polling (as described at https://socket.io/docs/client-api/#With-websocket-transport-only):
  ```javascript
      self.socket = io.connect({
          path: window.config.project_url + 'status/system/socket.io',
          transports: ['websocket']       // Default to websocket transport first, only falling back to long-polling on connection failure
      });
  
      self.socket.on('reconnect_attempt', () => {
          // On reconnection, reset the transports option, as the Websocket connection may
          // have failed (caused by proxy, firewall, browser, ...)
          self.socket.io.opts.transports = ['polling', 'websocket'];
      });
  ```
  This seems to solve the problem - our test case can go through hundreds of iterations without any problem.
  
  
  
  