Python 捕获瓶子服务器错误

Python 捕获瓶子服务器错误,python,python-2.7,long-polling,bottle,Python,Python 2.7,Long Polling,Bottle,我正在尝试获取我的瓶子服务器,这样当游戏中的一个人注销时,每个人都可以立即看到它。由于我使用长轮询,因此所有用户都有一个打开的请求 我遇到的问题是捕获当用户从无法再连接到页面的长轮询中离开页面时抛出的异常。错误信息在这里 Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/gevent/pywsgi.py", line 438, in handle_one_response self.ru

我正在尝试获取我的瓶子服务器,这样当游戏中的一个人注销时,每个人都可以立即看到它。由于我使用长轮询,因此所有用户都有一个打开的请求

我遇到的问题是捕获当用户从无法再连接到页面的长轮询中离开页面时抛出的异常。错误信息在这里

Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/gevent/pywsgi.py", line 438, in handle_one_response
    self.run_application()
  File "/usr/lib/python2.7/dist-packages/gevent/pywsgi.py", line 425, in run_application
    self.process_result()
  File "/usr/lib/python2.7/dist-packages/gevent/pywsgi.py", line 416, in process_result
    self.write(data)
  File "/usr/lib/python2.7/dist-packages/gevent/pywsgi.py", line 373, in write
    self.socket.sendall(msg)
  File "/usr/lib/python2.7/dist-packages/gevent/socket.py", line 509, in sendall
    data_sent += self.send(_get_memory(data, data_sent), flags)
  File "/usr/lib/python2.7/dist-packages/gevent/socket.py", line 483, in send
    return sock.send(data, flags)
error: [Errno 32] Broken pipe
<WSGIServer fileno=3 address=0.0.0.0:8080>: Failed to handle request:
  request = GET /refreshlobby/1 HTTP/1.1 from ('127.0.0.1', 53331)
  application = <bottle.Bottle object at 0x7f9c05672750>

127.0.0.1 - - [2013-07-07 10:59:30] "GET /refreshlobby/1 HTTP/1.1" 200 160 6.038377
回溯(最近一次呼叫最后一次):
文件“/usr/lib/python2.7/dist packages/gevent/pywsgi.py”,第438行,在handle\u one\u响应中
self.run_应用程序()
文件“/usr/lib/python2.7/dist packages/gevent/pywsgi.py”,第425行,在run_应用程序中
self.process_result()
文件“/usr/lib/python2.7/dist packages/gevent/pywsgi.py”,第416行,进程中\u结果
自写(数据)
写入文件“/usr/lib/python2.7/dist packages/gevent/pywsgi.py”,第373行
self.socket.sendall(msg)
文件“/usr/lib/python2.7/dist packages/gevent/socket.py”,第509行,在sendall中
数据发送+=自发送(\u获取\u内存(数据,数据发送),标志)
文件“/usr/lib/python2.7/dist packages/gevent/socket.py”,第483行,在send中
返回sock.send(数据、标志)
错误:[Errno 32]管道破裂
:无法处理请求:
请求=从('127.0.0.1',53331'获取/刷新大厅/1 HTTP/1.1
应用程序=
127.0.0.1--[2013-07-07 10:59:30]“获取/刷新大厅/1 HTTP/1.1”2001606.038377
处理该页面的函数如下所示

@route('/refreshlobby/<id>')
def refreshlobby(id):
    while True:
        yield lobby.refresh()
        gevent.sleep(1)
@route('/refreshLobble/'))
def刷新大厅(id):
尽管如此:
refresh()
gevent.睡眠(1)
我尝试在函数中捕获异常,并在一个decorator中放入@route进行包装,这两种方法都不起作用。我试着做一个@error(500)装饰器,但也没有触发。这似乎与瓶子的内部结构有关

编辑:我现在知道我需要捕获socket.error,但我不知道WSGI运行程序在我的代码中的位置 仔细观察回溯:这不是发生在函数中,而是发生在WSGI运行程序中

Traceback (most recent call last):
    File "/usr/lib/python2.7/dist-packages/gevent/pywsgi.py", line 438, in handle_one_response
        self.run_application()
在您的案例中,WSGI runner的工作方式是:

  • 收到请求
  • 从代码中获取部分响应
  • 将其发送到客户端(这是引发异常的地方)
  • 重复步骤2-3
  • 您无法捕获此异常 代码中未出现此错误

    当您尝试向关闭连接的客户端发送响应时,就会发生这种情况

    因此,您将无法从代码中捕获此错误

    替代解决方案 不幸的是,无法从生成器(您的代码)中判断它何时停止使用

    依靠垃圾收集生成器也不是一个好主意

    你还有一些其他的解决方案

    “最后一次见面” 了解用户何时断开连接的另一种方法可能是在
    yield
    语句之后记录“最后一次看到”

    您将能够识别断开连接的客户端,如果它们最后一次出现在遥远的过去

    其他跑步者
    另一个非WSGI运行程序更适合于实时应用程序。您可以尝试一下
    tornado

    另一个解决方案是使用monkey-patch-gevents套接字实现。sock.send要具体。