Redis 作为一个持久层是相关的,它也支持本机发布/订阅。因此,您可以订阅频道并将消息推送给您,而不是轮询数据库以查找新消息的情况。
我找到了您描述的系统类型的工作示例。魔术发生在socketio 视图中:
def socketio(request):
"""The socket.io view."""
io = request.environ['socketio']
redis_sub = redis_client().pubsub()
user = username(request.user)
# Subscribe to incoming pubsub messages from redis.
def subscriber(io):
redis_sub.subscribe(room_channel())
redis_client().publish(room_channel(), user + ' connected.')
while io.connected():
for message in redis_sub.listen():
if message['type'] == 'message':
io.send(message['data'])
greenlet = Greenlet.spawn(subscriber, io)
# Listen to incoming messages from client.
while io.connected():
message = io.recv()
if message:
redis_client().publish(room_channel(), user + ': ' + message[0])
# Disconnected. Publish disconnect message and kill subscriber greenlet.
redis_client().publish(room_channel(), user + ' disconnected')
greenlet.throw(Greenlet.GreenletExit)
return HttpResponse()
逐步查看视图:
- 设置socket.io,获取redis客户端和当前用户
- 使用 Gevent 注册一个“订阅者”——这将接收来自 Redis 的传入消息并将它们转发到客户端浏览器。
- 运行一个“发布者”,它从 socket.io(来自用户的浏览器)获取消息并将它们推送到 Redis
- 重复直到套接字断开
Redis Cookbook 提供了更多关于 Redis 方面的详细信息,并讨论了如何持久化消息。
关于您的其余问题:Twisted 是一个基于事件的网络库,在此应用程序中它可以被视为 Gevent 的替代品。根据我的经验,它功能强大且难以调试。
Celery 是一个“分布式任务队列”——基本上,它可以让你将工作单元分散到多台机器上。“分布式”角度意味着机器之间需要某种运输。Celery 支持多种类型的传输,包括 RabbitMQ(以及 Redis)。
在您的示例的上下文中,只有当您必须对每条消息进行某种昂贵的处理(例如扫描脏话或其他内容)时,Celery 才适用。即便如此,仍然需要启动 Celery 任务,因此需要一些代码来监听 socket.io 回调。
(以防你不完全困惑,Celery 本身可以使用 Gevent 作为其底层并发库。)
希望有帮助!