简体   繁体   English

捕获瓶服务器错误

[英]Catching bottle server errors

I am trying to get my bottle server so that when one person in a game logs out, everyone can immediately see it. 我正在尝试获取我的瓶子服务器,以便游戏中的一个人注销时,每个人都可以立即看到它。 As I am using long polling, there is a request open with all the users. 当我使用长时间轮询时,所有用户都会打开一个请求。

The bit I am having trouble with is catching the exception that is thrown when the user leaves the page from the long polling that can no longer connect to the page. 我遇到的麻烦是从长时间无法再连接到页面的轮询中捕获用户离开页面时引发的异常。 The error message is here. 错误消息在这里。

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

The function to handle that page is this. 处理该页面的功能是这个。

@route('/refreshlobby/<id>')
def refreshlobby(id):
    while True:
        yield lobby.refresh()
        gevent.sleep(1)

I tried catching the exception within the function, and in a decorator which I put to wrap @route, neither of which worked. 我试图在函数中以及在装饰器中捕获异常,该装饰器包装了@route,但都不起作用。 I tried making an @error(500) decorator, but that didn't trigger, either. 我尝试制作一个@error(500)装饰器,但是也没有触发。 It seems that this is to do with the internals of bottle. 看来这与瓶子的内部有关。

Edit: I know now that I need to be catching socket.error, but I don't know whereabouts in my code 编辑:我现在知道我需要捕获socket.error,但是我不知道代码中的下落

The WSGI runner WSGI亚军

Look closely at the traceback: this in not happening in your function, but in the WSGI runner. 仔细观察一下追溯:这不是在您的函数中发生,而是在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()

The way the WSGI runner works, in your case, is: 在您的情况下,WSGI运行器的工作方式是:

  1. Receives a request 收到请求
  2. Gets a partial response from your code 从您的代码中获得部分响应
  3. Sends it to the client (this is where the exception is raised) 发送给客户端(这是引发异常的地方)
  4. Repeats steps 2-3 重复步骤2-3

You can't catch this exception 您无法捕获此异常

This error is not raised in your code. 您的代码中不会引发此错误。

It happens when you try to send a response to a client that closed the connection. 当您尝试向关闭连接的客户端发送响应时,就会发生这种情况。

You'll therefore not be able to catch this error from within your code. 因此,您将无法从代码中捕获此错误。

Alternate solutions 替代解决方案

Unfortunately, it's not possible to tell from within the generator (your code) when it stops being consumed. 不幸的是,无法从生成器(您的代码)中得知何时停止使用它。

It's also not a good idea to rely on your generator being garbage collected. 依靠生成器进行垃圾回收也不是一个好主意。

You have a couple other solutions. 您还有其他一些解决方案。

"Last seen" “最后一次露面”

Another way to know when an user disconnects would probably be to record a "last seen", after your yield statement. 知道用户何时断开连接的另一种方法可能是在yield语句之后记录“最后一次看到”。

You'll be able to identify clients that disconnected if their last seen is far in the past. 如果最近一次断开连接的客户端已经过去,您将能够确定它们已断开连接。

Other runner 其他亚军

Another, non-WSGI runner, will be more appropriate for a realtime application. 另一个非WSGI运行器将更适合于实时应用程序。 You could give tornado a try. 您可以尝试tornado

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM