28

これに丸2日を費やした後でも、PythonでのCometのすべての選択肢と構成を理解することは不可能だと感じています。私はここですべての答えと私が見つけたすべてのブログ投稿を読みました。この時点で出血しそうな気がするので、この質問に問題があったことを心からお詫び申し上げます。

私はこれらすべてにまったく慣れていません。これまでに行ったことは、ApacheにPHP/Djangoバックエンドを備えた単純な非リアルタイムサイトでした。

私の目標は、リアルタイムのチャットアプリケーションを作成することです。うまくいけば、ユーザー、認証、テンプレートなどのためにDjangoに関連付けられています。

ツールについて読むたびに、その上に別のツールが必要だと書かれていますが、それは終わりのない連鎖のように感じます。

まず第一に、誰かがこの仕事に必要なすべてのツールを分類できますか?
さまざまなサーバー、ネットワークライブラリ、エンジン、クライアント側のJavaScriptについて読んだことがありますが、他に何があるのか​​わかりません。こんなに複雑になるとは想像もしていませんでした。

Twisted / Twisted Webは人気があるようですが、それを統合したり、他に必要なものを統合したりすることはできません(少なくともクライアント側のJSが必要だと思います)。

私が正しく理解している場合、OrbitedはTwistedに基づいて構築されていますが、他に何か必要ですか?

GeventとEventletはTwistedと同じカテゴリにありますか?他にどれくらい必要ですか?

Celery、RabbitMQ、またはRedisのようなKVストアのようなものはどこから入りますか?メッセージキューの概念がよくわかりません。それらは不可欠であり、どのようなサービスを提供していますか?

私が見なければならない完全なチャットアプリのチュートリアルはありますか?

この精神的な障害を乗り越えるのを手伝ってくれた人には心からお世話になります。何か忘れてしまった場合は、遠慮なく質問してください。私はそれがかなりの質問であることを知っています。

4

3 に答える 3

8

Socket.IO を使用できます。そのための gevent および tornado ハンドラーがあります。ここで Django を使用した gevent-socketio に関する私のブログ投稿を参照してください: http://codysoyland.com/2011/feb/6/evented-django-part-one-socketio-and-gevent/

于 2011-04-11T00:30:21.563 に答える
5

過去数ヶ月にわたって同じ研究をしなければならなかったので、あなたの痛みを感じます。適切なドキュメントを扱う時間はまだありませんが、http://bitbucket.org/virtualcommons/vcwebでsocket.ioとtornadioでDjangoを使用した実例あります-からの直接通信を設定したいと思っていましたキューを使用したtornadioサーバープロセスへのDjangoサーバー側(つまり、djangoビューのロジックはメッセージをキューにプッシュし、tornadioによって処理されます。tornadioはそのメッセージのjsonエンコードバージョンをすべての関心のあるサブスクライバーにプッシュします)が、その部分はまだ完全に実装されています。私が現在それを設定している方法は以下を含みます:

  1. 別のポートで実行され、socket.ioリクエストを受け入れ、Djangoモデルを操作する外部トルネード(tornadio)サーバー。このサーバープロセスがデータベースに書き込むのは、保存する必要のあるチャットメッセージだけです。すべてのDjangoモデルなどに完全にアクセスでき、すべてのリアルタイムのやり取りはこのサーバープロセスを直接通過する必要があります。
  2. リアルタイムアクセスを必要とするDjangoテンプレートページには、socket.io javascriptが含まれ、tornadioサーバーへの直接接続を確立します

orbitedhookboxgeventを調べましたが、最もクリーンなjavascript + pythonコードが可能であると思われたため、socket.io+tornadoを使用することにしました。ただし、この1年でPython / Djangoを学び始めたばかりなので、それについては間違っている可能性があります。

于 2011-04-11T21:06:31.843 に答える
3

Redis は、ネイティブのpublish/subscribeもサポートする永続化レイヤーとして関連しています。したがって、データベースをポーリングして新しいメッセージを探している状況の代わりに、チャネルにサブスクライブして、メッセージをプッシュすることができます。

あなたが説明したタイプのシステムの実例を見つけました。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()

ビューを段階的に見ていきます。

  1. socket.io をセットアップし、redis クライアントと現在のユーザーを取得します
  2. Gevent を使用して「サブスクライバー」を登録します。これにより、受信メッセージが Redis から取得され、クライアント ブラウザーに転送されます。
  3. (ユーザーのブラウザーから) socket.io からメッセージを受け取り、それらを Redis にプッシュする「パブリッシャー」を実行します。
  4. ソケットが切断されるまで繰り返します

Redis Cookbookでは、Redis 側の詳細と、メッセージを永続化する方法について説明しています。

あなたの質問の残りの部分について: Twisted はイベントベースのネットワーキング ライブラリです。このアプリケーションでは Gevent の代替と見なすことができます。私の経験では、強力でデバッグが困難です。

Celery は「分散タスク キュー」です。基本的に、ワークアウトの単位を複数のマシンに分散させることができます。「分散」角度は、マシン間で何らかのトランスポートが必要であることを意味します。Celery は、RabbitMQ (および Redis も) など、いくつかのタイプのトランスポートをサポートしています。

あなたの例のコンテキストでは、冒とく的な表現などをスキャンするなど、各メッセージに対して何らかのコストのかかる処理を行う必要がある場合にのみ、Celery が適切です。それでも、Celery タスクを開始する必要があるため、socket.io コールバックをリッスンするコードが必要になります。

(完全に混乱していない場合に備えて、Celery 自体で Gevent をその基礎となる同時実行ライブラリとして使用するようにすることができます。)

それが役立つことを願っています!

于 2012-09-10T17:51:33.210 に答える