Panggilan balik tak segerak Python menjadi segerak dan melaksanakan tamat masa
过去多啦不再A梦
过去多啦不再A梦 2017-05-18 11:00:46
0
1
732

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?

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

membalas semua(1)
黄舟

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()


Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!