捕捉瓶子的服务器错误[英] Catching bottle server errors

本文是小编为大家收集整理的关于捕捉瓶子的服务器错误的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在尝试获取我的瓶服务器,以便当游戏中的一个人注销时,每个人都可以立即看到它.当我使用长民意调查时,所有用户都有一个请求.

我遇到麻烦的是,当用户从不再连接到页面的长期轮询中离开页面时,会遇到异常.错误消息在这里.

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

处理该页面的功能就是这样.

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

我尝试在功能中捕获异常,然后在装饰器中包装@Route,其中两个都没有用.我尝试制作@Error(500)装饰器,但这也没有触发.看来这与瓶子的内部有关.

编辑:我现在知道我需要抓住插座.

推荐答案

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()

在您的情况下,WSGI Runner的工作方式是:

  1. 收到请求
  2. 从您的代码中得到部分响应
  3. 将其发送给客户(这是提出例外的地方)
  4. 重复步骤2-3

您无法捕获此异常

您的代码中未提出此错误.

当您尝试将响应发送给关闭连接的客户端时,它会发生.

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

替代解决方案

不幸的是,当发电机停止消耗时,无法从发电机内(您的代码)分辨出来.

依靠发电机收集的发电机也不是一个好主意.

您还有其他几个解决方案.

"最后一个看见"

知道用户何时断开连接的另一种方法可能是在您的yield语句之后记录"最后一个看见".

如果过去的最后一个见面,您将能够识别出断开连接的客户.

其他跑步者

另一个非WSGI跑步者将更适合实时应用程序.您可以尝试tornado

本文地址:https://www.itbaoku.cn/post/1579881.html

问题描述

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. I tried making an @error(500) decorator, but that didn't trigger, either. 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

推荐答案

The WSGI runner

Look closely at the traceback: this in not happening in your function, but in the WSGI runner.

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:

  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

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.

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. You could give tornado a try.