2
from twisted.web.resource import Resource
from twisted.web.server import Site, Session
from twisted.internet import ssl
from twisted.internet import reactor

class Echo(Resource):
    def render_GET(self, request):
        return "GET"

class WebSite(Resource):
    def start(self):
        factory = Site(self, timeout=5)
        factory.sessionFactory = Session
        self.putChild("echo", Echo())
        reactor.listenSSL(443, factory, ssl.DefaultOpenSSLContextFactory('privkey.pem', 'cacert.pem'))
        #reactor.listenTCP(8080, factory)
        self.sessions = factory.sessions

if __name__ == '__main__':
    ws = WebSite()
    ws.start()
    reactor.run()

上記のコードでは、Web ブラウザーから「https://localhost/echo」という URL を入力すると、ページが取得されます。5 秒後にページをリロードしようとすると、Web ページが更新されず、リロード操作でスタックします。リロードの 2 回目の試行で、ページが即座に取得されます。

上記のコードを react.listenTCP(8080, factory) で実行すると、そのような問題は発生しません。(リロードをスタックせずにページをリロードして、ページを即座に取得できます)

問題は、Chrome、Firefox で繰り返される可能性があります。しかし、Ubuntu の Epiphany ブラウザで試してみると、そのような問題は発生しません。

なぜこれが起こるのか理解できませんでした。

問題の理解/解決に関するコメントは歓迎されます。

追加情報:

  • listenSSL を使用すると、タイムアウト秒後に接続に関連するファイル記述子が閉じられません。ページをリロードしている間、ページは静止したままで、2 回目のリロード操作で閉じられ、新しいファイル記述子が開かれます。(そして私はすぐにページを取得します)
  • listenTCP を使用すると、タイムアウト秒後にファイル記述子が閉じ、ページをリロードすると、新しいファイル記述子が開き、すぐにページが返されます。
  • また、Telnet 接続では、どちらの場合も期待どおりに接続がタイムアウトします。
  • このサーバーに接続する Twisted クライアントも、予想どおりタイムアウトに影響します。
4

1 に答える 1

1

接続をタイムアウトするクラスは TimeoutMixin クラスです。

そして、transport.loseConneciton() メソッドを使用して接続をタイムアウトにします。

どういうわけか、DefaultOpenSSLFactory は接続 (?) を使用するため、loseConnection メソッドはトランスポートの終了を待ち、その時点で接続上のプロセスを受け入れません。

ねじれたドキュメントによると:

上記のコードでは、トランスポートへの書き込み直後に LooseConnection が呼び出されます。LooseConnection 呼び出しは、すべてのデータが Twisted out によってオペレーティング システムに書き込まれた場合にのみ接続を閉じます。したがって、この場合、トランスポート書き込みが失われることを心配することなく安全に使用できます。プロデューサーがトランスポートで使用されている場合、loseConnection は、プロデューサーが登録解除された後にのみ接続を閉じます。

場合によっては、すべてのデータが書き出されるまで待つことは望ましくありません。ネットワーク障害、または接続の反対側のバグや悪意により、トランスポートに書き込まれたデータが配信できない可能性があるため、loseConnection が呼び出されたとしても、接続は失われません。これらの場合、abortConnection を使用できます。これは、バッファリングされたデータがまだトランスポートに書き込まれていないか、またはプロデューサーがまだ登録されているかに関係なく、接続をすぐに閉じます。abortConnection は Twisted 11.1 以降でのみ利用可能であることに注意してください。

その結果、それをオーバーライドして timeoutMixinClass で loseConnection() を abortConnection() に変更すると、状況は発生しなくなりました。

特定の状況で LooseConnection が接続を閉じるのに十分ではない理由を明確にしたら、ここにメモします。(それについてのコメントは大歓迎です)

于 2013-02-25T10:17:49.283 に答える