Maison > Questions et réponses > le corps du texte
Scénario : Il existe un serveur A et un client B, et il existe une connexion socket.
Ce que j'écris maintenant est la partie B côté client, le côté serveur est incontrôlable.
Il s'avère que B envoie d'abord un paquet, attend que A renvoie le contenu spécifié, puis B envoie le paquet suivant
def do():
s.send(...)
yield 1
s.send(...)
yield 2
# 接收到数据后的回调
def callback():
global f
next(f)
f=do()
next(f)
Maintenant, je souhaite implémenter un délai d'attente et implémenter le blocage. Une fois que B a envoyé les données, il bloque jusqu'à ce que A renvoie les données (ou génère une erreur s'il ne reçoit pas de retour de A dans les 5 secondes). Veuillez me dire comment y parvenir ?
黄舟2017-05-18 11:02:46
Avec Tornado, je ne peux pas écrire plus de quelques lignes de code.
Créons d'abord un serveur simple pour faciliter la démonstration :
# -*- 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()
Ensuite, pour implémenter le Client, la logique de base est de fermer la connexion après un délai d'attente puis de rétablir la connexion :
# -*- 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()