title: Detect when Websocket is disconnected, with Python Bottle / gevent-websocket
body: <p>I'm using the <code>gevent-websocket</code> module with <code>Bottle</code> Python framework. </p>
  
  <p>When a client closes the browser, this code</p>
  
  <pre><code>$(window).on('beforeunload', function() { ws.close(); });
  </code></pre>
  
  <p>helps to close the websocket connection properly.</p>
  
  <p>But <strong>if the client's network connection is interrupted</strong>, no "close" information can be sent to the server.</p>
  
  <p>Then, often, even 1 minute later, the server still believes the client is connected, and the websocket is still open on the server. </p>
  
  <p><strong>Question: How to detect properly that a websocket is closed because the client is disconnected from network?</strong></p>
  
  <p><strong>Is there a websocket KeepAlive feature available in Python/Bottle/gevent-websocket?</strong></p>
  
  <hr>
  
  <p>One answer from <a href="https://stackoverflow.com/questions/25220006/web-socket-cannot-detect-client-connection-on-internet-disconnect">Web Socket: cannot detect client connection on internet disconnect</a> suggests to use a heartbeat/ping packet every x seconds to tell the server "I'm still alive".   The other answer suggests using a <code>setKeepAlive(true).</code> feature. Would this feature be available in <code>gevent-websocket</code>?</p>
  
  <hr>
  
  <p>Example server code, <a href="https://github.com/zeekay/bottle-websocket/blob/master/examples/chat/chat.py" rel="nofollow noreferrer">taken from here</a>:</p>
  
  <pre><code>from bottle import get, template, run
  from bottle.ext.websocket import GeventWebSocketServer
  from bottle.ext.websocket import websocket
  
  users = set()
  
  @get('/')
  def index():
      return template('index')
  
  @get('/websocket', apply=[websocket])
  def chat(ws):
      users.add(ws)
      while True:
          msg = ws.receive()
          if msg is not None:
              for u in users:
                  u.send(msg)
          else:
              break
      users.remove(ws)
  
  run(host='127.0.0.1', port=8080, server=GeventWebSocketServer)
  </code></pre>