Я использую gevent StreamServer для обработки входящих соединений с клиентами.Ожидание как gevent socket, так и redis blocking blpop
После того, как клиенты подключены, клиент отправит на сервер некоторые сообщения, и сервер обработает их. Все отлично работает на этой стороне. Но время от времени сервер также отправлял сообщения обратно конкретному клиенту.
Я сделал бы это с redis. Я создал очередь с определенным идентификатором клиента в качестве ключа. После того, как клиент отправит сообщение, я проверяю очередь и, если есть какое-либо сообщение, я отправляю его клиенту.
Недостатком этого подхода является то, что сервер может отправлять сообщение только после того, как клиент отправит сообщение.
Есть ли способ, чтобы я мог ждать входящих данных и 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()
Клиент уже имеет соединение. Проблема в том, что на стороне сервера она ждет fp.readline(). Поэтому у меня нет механизма для опроса/ожидания события от redis. Я читал о 'select', но нет документации о том, как правильно ее использовать. – Awi
Я добавил пример кода, теперь, когда я знаю, что вы держите открытое соединение. Вы, как правило, хотите разделить чтение и письмо, а не пытаться чередовать его вместе, по моему опыту. – Ivo
Отлично! Ваш пример кода помог изменить код, чтобы делать то, что я хочу. Большое спасибо! – Awi