2

Django Web アプリケーションがあります。また、django(で実行)を備えた同じマシンで実行されるtwistedを使用して記述されたスペルサーバーもありますlocalhost:8090。ユーザーが何らかのアクションを実行すると、要求が Django に送信され、Django がこのねじれたサーバーに接続し、サーバーがデータを Django に送り返すという考えです。最後に、Django はこのデータを HTML テンプレートに入れ、ユーザーに返します。

ここで私は問題を抱えています。私の Django アプリでは、リクエストが来ると、単純なツイスト クライアントを作成して、ローカルで実行されているツイスト サーバーに接続します。

...
        factory = Spell_Factory(query) 
        reactor.connectTCP(AS_SERVER_HOST, AS_SERVER_PORT, factory)
        reactor.run(installSignalHandlers=0)
        print factory.results
...

reactor.run()が問題を引き起こしています。イベントループなので。次回、この同じコードが Django によって実行されると、サーバーに接続できません。これをどのように処理しますか?

4

3 に答える 3

4

上記の2つの答えは正しいです。ただし、スペルサーバーを既に実装していることを考慮して、それを 1 つとして実行します。同じマシン上で別のプロセスとして実行することから始めることができます - at localhost:PORT. 現時点では、非常に単純なバイナリ プロトコル インターフェースが既にあるようsocketです。ブロッキング モードで標準ライブラリのインターフェースを使用して、同様に単純な Python クライアントを実装できます。

ただし、twisted.web単純な Web インターフェイスを試して公開することをお勧めします。JSON を使用してデータをシリアル化および逆シリアル化できます。これは Django で十分にサポートされています。非常に簡単な例を次に示します。

import json
from twisted.web import server, resource
from twisted.python import log

class Root(resource.Resource):
    def getChild(self, path, request):
        # represents / on your web interface
        return self

class WebInterface(resource.Resource):
    isLeaf = True
    def render_GET(self, request):
        log.msg('GOT a GET request.')
        # read request.args if you need to process query args
        # ... call some internal service and get output ...
        return json.dumps(output)

class SpellingSite(server.Site):
    def __init__(self, *args, **kwargs):
        self.root = Root()
        server.Site.__init__(self, self.root, **kwargs)
        self.root.putChild('spell', WebInterface())

それを実行するには、次のスケルトン.tacファイルを使用できます。

from twisted.application import service, internet

site = SpellingSite()
application = service.Application('WebSpell')
# attach the service to its parent application
service_collection = service.IServiceCollection(application)
internet.TCPServer(PORT, site).setServiceParent(service_collection)

サービスを別のファースト クラス サービスとして実行すると、必要に応じて別のマシンでいつでも実行できます。Web インターフェースを公開すると、リバース プロキシ ロード バランサーの背後でも簡単に水平方向にスケーリングできます。

于 2011-01-16T15:35:31.350 に答える
3

reactor.run()プログラム全体で一度だけ呼び出す必要があります。「私が持っているこの 1 つの要求を開始する」と考えないでください。「Twisted のすべてを開始する」と考えてください。

バックグラウンド スレッドでリアクタを実行することは、これを回避する 1 つの方法です。その後、blockingCallFromThreadDjango アプリケーションは Django アプリケーションで使用でき、ブロッキング API と同じように Twisted API を使用できます。ただし、このバックグラウンドの Twisted スレッドが適切なタイミングで開始および停止されるようにする必要があるため、WSGI コンテナーからの少しの協力が必要になります (それぞれインタープリターが初期化および破棄されるとき)。

Twisted を WSGI コンテナーとして使用することもできます。その場合、特別なことを開始または停止する必要はありません。blockingCallFromThreadすぐに機能します。のコマンドライン ヘルプを参照してくださいtwistd web --wsgi

于 2010-12-27T03:37:48.293 に答える
1

Twisted サーバーから結果を取得した後、または何らかのエラー/タイムアウトが発生した後は、reactor を停止する必要があります。したがって、Twisted サーバーへのクエリを必要とする Django リクエストごとに、reactor を実行してから停止する必要があります。ただし、Twisted ライブラリではサポートされていません — リアクターは再起動できません。可能な解決策:

  • Twisted リアクターには別のスレッドを使用しますが、長時間実行されるスレッドをサポートするサーバーに django アプリをデプロイする必要があります (これらは今はありませんが、独自のスレッドを簡単に作成できます :-))。

  • クライアント プロトコルの実装に Twisted を使用しないでください。単純な stdlib のsocketモジュールを使用してください。

于 2010-12-26T20:11:00.967 に答える