0

我正在使用 gevent StreamServer 来处理来自客户端的传入连接。

客户端连接后,客户端会向服务器发送一些消息,服务器会进行处理。这方面一切正常。但有时服务器也会将消息发送回特定的客户端。

我会用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()
4

1 回答 1

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()
于 2013-02-24T17:18:01.893 回答