Rumah > Soal Jawab > teks badan
Senario: Terdapat pelayan A dan klien B, dan terdapat sambungan soket.
Apa yang saya tulis sekarang adalah bahagian B di bahagian klien, bahagian pelayan tidak dapat dikawal.
Ternyata B menghantar paket dahulu, menunggu A mengembalikan kandungan yang ditentukan, dan kemudian B menghantar paket seterusnya
def do():
s.send(...)
yield 1
s.send(...)
yield 2
# 接收到数据后的回调
def callback():
global f
next(f)
f=do()
next(f)
Sekarang saya mahu melaksanakan tamat masa dan melaksanakan penyekatan. Selepas B menghantar data, ia menyekat sehingga A mengembalikan data (atau menimbulkan ralat jika ia tidak menerima pulangan daripada A dalam masa 5 saat. Sila beritahu saya bagaimana untuk mencapai ini?
黄舟2017-05-18 11:02:46
Dengan Tornado, saya tidak boleh menulis lebih daripada beberapa baris kod.
Mari kita buat Server mudah dahulu untuk memudahkan demonstrasi:
# -*- 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()
Kemudian, untuk melaksanakan Klien, logik asas adalah untuk menutup sambungan apabila tamat masa berlaku, dan kemudian mewujudkan semula sambungan:
# -*- 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()