Der asynchrone Python-Rückruf wird synchron und implementiert eine Zeitüberschreitung
过去多啦不再A梦
过去多啦不再A梦 2017-05-18 11:00:46
0
1
694

Szenario: Es gibt einen Server A und einen Client B und es besteht eine Socket-Verbindung.
Was ich jetzt schreibe, ist Teil B auf der Clientseite, die Serverseite ist unkontrollierbar.
Es stellt sich heraus, dass B zuerst ein Paket sendet, darauf wartet, dass A den angegebenen Inhalt zurückgibt, und dann sendet B das nächste Paket

def do(): s.send(...) yield 1 s.send(...) yield 2 # 接收到数据后的回调 def callback(): global f next(f) f=do() next(f)

Jetzt möchte ich ein Timeout und eine Blockierung implementieren. Nachdem B die Daten gesendet hat, blockiert es, bis A die Daten zurückgibt (oder löst einen Fehler aus, wenn es nicht innerhalb von 5 Sekunden eine Antwort von A erhält). Sagen Sie mir bitte, wie ich das erreichen kann.

过去多啦不再A梦
过去多啦不再A梦

Antworte allen (1)
黄舟

用 Tornado 的话,写不了几行代码吧。

先作个简单的 Server ,以方便演示:

# -*- coding: utf-8 -*- from tornado.ioloop import IOLoop from tornado.tcpserver import TCPServer from tornado import gen class Server(TCPServer): @gen.coroutine def handle_stream(self, stream, address): while 1: data = yield stream.read_until('\n') if data.strip() == 'exit': stream.close() break if data.strip() == '5': IOLoop.current().call_at(IOLoop.current().time() + 5, lambda: stream.write('ok 5\n')) else: stream.write('ok\n') if __name__ == '__main__': Server().listen(8000) IOLoop.current().start()

然后,来实现 Client ,基本逻辑是,超时就关闭连接,然后再重新建立连接:

# -*- coding: utf-8 -*- import functools from tornado.ioloop import IOLoop from tornado.tcpclient import TCPClient from tornado import gen def when_error(stream): print 'ERROR' stream.close() main() @gen.coroutine def main(): client = TCPClient() stream = yield client.connect('localhost', 8000) count = 0 IL = IOLoop.current() while 1: count += 1 stream.write(str(count) + '\n') print count, '...' timer = IL.call_at(IL.time() + 4, functools.partial(when_error, stream)) try: data = yield stream.read_until('\n') except: break IL.remove_timeout(timer) print data yield gen.Task(IL.add_timeout, IOLoop.current().time() + 1) if __name__ == '__main__': main() IOLoop.current().start()
    Neueste Downloads
    Mehr>
    Web-Effekte
    Quellcode der Website
    Website-Materialien
    Frontend-Vorlage
    Über uns Haftungsausschluss Sitemap
    Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!