0

クライアントからの着信接続を処理するためにgeventStreamServerを使用しています。

クライアントが接続された後、クライアントはサーバーにいくつかのメッセージを送信し、サーバーはそれを処理します。この側ではすべてが正常に機能します。しかし、時々、サーバーは特定のクライアントにメッセージを送り返します。

これは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 に答える