2011-04-10 57 views
30

花费了两天时间后,我仍然发现无法理解Python中Comet的所有选择和配置。我已经阅读了所有的答案以及我能找到的每篇博文。感觉就像我即将出血一样,所以我对这个问题的任何错误致以最大的歉意。需要帮助了解Python中的彗星(使用Django)

我完全不熟悉所有这些,我之前完成的所有操作都是在Apache上使用PHP/Django后端的简单非实时站点。

我的目标是创建一个实时聊天应用程序;希望绑定到用户,身份验证,模板等Django

每当我读到一个工具它说我需要另一个工具之上,它感觉像一个永无止境的链。

首先,任何人都可以将这项工作所需的所有工具分类吗?
我已经读过关于不同的服务器,网络库,引擎,客户端的JavaScript,我不知道还有什么。我从来没有想到这将是复杂的。 (扭曲的Web看起来很流行,但我不知道要整合它或我需要什么(猜测我至少需要客户端JS)。

如果我理解正确,Orbited内置扭曲,我需要其他任何东西吗?

Gevent和Eventlet与Twisted属于同一类别吗?我还需要多少钱?

像Redis这样的Celery,RabbitMQ或KV商店在哪里?我不太了解消息队列的概念。他们是必不可少的,他们提供什么样的服务?

我应该看看有没有完整的聊天应用程序教程?

我会完全感激任何帮助我度过这个精神障碍的人,如果我遗漏了任何东西,请不要犹豫,问问。我知道这是一个非常有问题的问题。

+0

你看过这个吗?它似乎拥有工作所需的所有资源。 http://www.rkblog.rk.edu.pl/w/p/django-and-comet/ – jbcurtin 2011-04-10 20:49:53

+0

@ jbcurtin非常感谢,这可能是我读过的最好的文章。轨道似乎没有得到很好的维护,有没有很多类似的项目?我仍然无法知道是否需要使用其他任何东西(特别是因为我希望所有消息在数据库中持久存在);就像我仍然需要知道所有关于扭曲本身? – XOR 2011-04-10 22:28:43

+0

我不认为用django来完成这个任务会有很多好运。我能找到的衣柜里的东西是'django evserver'。扭曲可能是一条路,最终彗星只是暂停一条线来保持它的开放。你必须杀死整个Django的生命周期来完成这个任务。 – jbcurtin 2011-04-11 22:17:58

回答

5

我觉得你的痛苦,不得不在过去几个月通过相同的研究。我还没有时间处理正确的文档,但我有一个使用Django的工作示例,其中socket.iotornadiohttp://bitbucket.org/virtualcommons/vcweb-我希望能够建立从Django服务器端到使用队列的tornadio服务器进程的直接通信(即,Django视图中的逻辑将消息推送到队列中,然后由tornadio处理,将该消息的json编码版本推送给所有感兴趣的订阅者),但尚未完全实现该部分。目前我已经得到了它设立的方式包括:

  1. external tornado (tornadio) server,另一个端口上运行,接受socket.io请求,并与Django模型的工作。这个服务器进程唯一写入数据库的是需要存储的聊天消息。它可以完全访问所有的Django模型等,所有的实时交互都需要直接通过这个服务器进程。
  2. 需要实时访问Django的模板页面包括JavaScript和建立与tornadio服务器

我看着orbitedhookboxgevent但决定去与socket.io直接连接的socket.io +龙卷风,因为它似乎让我最干净的JavaScript + Python代码。但我可能会错,刚刚在去年学习Python/Django。

+0

很好的答案,谢谢。将检查出Tornadio和你的代码。我也是Python/Django的新手,所以我愿意接受所有建议! – XOR 2011-04-13 19:07:56

3

Redis与持久层相关,该层也支持本地publish/subscribe。因此,而不是轮询分贝寻找新消息的情况,您可以订阅频道,并将消息发送给您。

我找到了您描述的系统类型的working example。魔术发生在socketio view

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() 

持有的观点一步一步:

  1. 设置socket.io,得到了Redis的客户端和当前用户
  2. 使用GEVENT注册一个“订阅者” - 这会将来自Redis的传入消息转发给客户端浏览器。
  3. 运行“出版商”这需要从消息socket.io(从用户的浏览器),直到插座断开

Redis的食谱上Redis的侧面给出了little more detail他们推入Redis的

  • 重复,并讨论如何坚持消息。

    关于您的其余问题:Twisted是一个基于事件的网络库,它可以被认为是Gevent在这个应用程序中的替代品。根据我的经验,它功能强大且难以调试。

    芹菜是一个“分布式任务队列” - 基本上,它可以让你在多台机器上传播工作单元。 “分布式”角度意味着机器之间需要某种运输。芹菜支持几种类型的运输,包括RabbitMQ(以及Redis)。

    在您的例子的情况下,如果你不得不做一些昂贵的处理像扫描亵渎或某事的每个消息芹菜才适宜。即使如此,一些东西也不得不启动Celery任务,所以需要一些代码来监听socket.io回调。

    (万一你没有完全糊涂了,芹菜本身可以由使用GEVENT作为底层的并发库)。

    希望帮助!