2013-02-21 44 views
0

我正在使用gevent StreamServer处理来自客户端的传入连接。等待gevent套接字和redis阻止blpop

客户端连接后,客户端会发送一些消息到服务器,服务器会处理它。一切工作都很好。但时不时的服务器也会将消息发回给特定的客户端。

我会用redis来做到这一点。我创建了一个具有特定客户端ID的队列作为关键字。客户端发送消息后,我检查队列,如果有任何消息,我将它发回给客户端。

这种方法的缺点是,服务器只能在客户端发送消息后发送消息。

有没有办法可以等待传入数据和redis blpop,所以我可以在消息准备好后立即将消息发送回客户端,而不是等到客户端发送下一个数据?

import gevent 
from gevent import socket 
from gevent.server import StreamServer 
import redis 

r = redis.Redis('localhost') 

def handle_echo(sock, address): 
    fp = sock.makefile() 
    while True: 
     line = fp.readline() 
     if line: 
      client_id = line.split(",")[0] 
      if r.llen('%s:servercmds' % client_id) > 0: 
       tosend = r.lrange('%s:servercmds' % imei, 0, 0)[0] 
       try:   
        fp.write(tosend) 
        fp.flush() 
        r.lpop('%s:servercmds' % imei) 
       except: 
        print('cannot send data to client') 
      else: 
       break 
     sock.shutdown(socket.SHUT_WR) 
     sock.close() 

server = StreamServer(('', 8045), handle_echo, spawn=10000) 
server.serve_forever() 

回答

1

您需要客户端保持连接处于打开状态,以便您可以将消息发回给它,或者正在侦听消息本身。

编辑:这是代码关闭我的头顶部。国际海事组织(IMO)通常会像这样分开阅读和写作。不过,这不是您可以使用的唯一模式。

import gevent 
from gevent import socket 
from gevent.server import StreamServer 
import redis 

r = redis.Redis('localhost') 

def handle_echo(sock, address): 
    def read_loop(sock): 
     while True: 
      try: 
       socket.wait_read(sock.fileno()) 
      except socket.error: 
       break 
      # read from socket 

    def write_loop(sock): 
     while True: 
      try: 
       socket.wait_write(sock.fileno()) 
      except socket.error: 
       break 
      # write to socket 

    jobs = [gevent.spawn(func, sock) for func in (read_loop, write_loop)] 
    gevent.joinall(jobs) 

server = StreamServer(('', 8045), handle_echo) 
server.serve_forever() 
+0

客户端已经拥有连接。问题是,在服务器端,它在fp.readline()等待。所以我没有机制来轮询/等待来自redis的事件。 我读了'select',但没有关于如何正确使用它的文档。 – Awi 2013-02-25 03:03:55

+0

我添加了示例代码,现在我知道你正在打开一个连接。你通常想分开阅读和写作,而不是尝试按照我的经验交织在一起。 – Ivo 2013-02-25 08:53:17

+0

太棒了!你的代码示例已经帮助修改代码以做我想做的事。非常感谢! – Awi 2013-02-26 01:47:30