使用瓶子和gevent.wsgi?

2024-05-18 16:17:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个使用bottlegevent.wsgi实现的小型异步服务器。有一个用于实现长轮询的例程,它看起来很像bottle documentation中的“事件回调”示例:

def worker(body):
  msg = msgbus.recv()
  body.put(msg)
  body.put(StopIteration)

@route('/poll')
def poll():
  body = gevent.queue.Queue()
  worker = gevent.spawn(worker, body)
  return body

这里,msgbus是一个ZMQsub套接字。在

这一切都很好,但是如果客户端在 worker在{}上被阻止,该greenlet任务将挂起 “永远”左右(好吧,直到收到消息),而且只会 当断开连接的客户端试图发送 回应。在

如果我不想阻止,我可以使用msgbus.poll(timeout=something) 一直在等待ipc消息,但我还是检测不到客户端 断开连接。在

我想做的是得到客户的参考 这样我就可以在某种selectpoll循环中使用它, 或者在我的greenlet里得到一些异步通知,但是 我不知道如何用这些来完成这两件事 框架(瓶子和gevent)。在

有没有办法通知客户机断开连接?在


Tags: 服务器消息客户端wsgibottleputdefgevent
1条回答
网友
1楼 · 发布于 2024-05-18 16:17:41

啊哈!至少在gevent.wsgi下,wsgi.input变量有一个rfile成员,它是一个类似文件的对象。这似乎不是WSGI spec所必需的,因此它可能无法与其他服务器一起工作。在

通过这个,我可以修改我的代码,使其看起来像:

def worker(body, rfile):
  poll = zmq.Poller()
  poll.register(msgbus)
  poll.register(rfile, zmq.POLLIN)

  while True:
    events = dict(poll.poll())

    if rfile.fileno() in events:
      # client disconnect!
      break

    if msgbus in events:
      msg = msgbus.recv()
      body.put(msg)
      break

    body.put(StopIteration)

@route('/poll')
def poll():
  rfile = bottle.request.environ['wsgi.input'].rfile
  body = gevent.queue.Queue()
  worker = gevent.spawn(worker, body, rfile)
  return body

这个很好用。。。在

…除了在OpenShift上,您必须使用 alternate frontend在支持websockets的8000端口上。在

相关问题 更多 >

    热门问题