2013-02-21 91 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