python异步回调转为同步并实现超时
问题描述
场景:一个服务端A,一个客户端B,存在一个socket连接。现在写的是客户端B部分,服务端不可控。原来是 B先发送一个包,等待A返回指定内容,B再发送下一个包
def do(): s.send(...) yield 1 s.send(...) yield 2# 接收到数据后的回调def callback(): global f next(f) f=do()next(f)
现在想实现一个timeout,并且实现阻塞。B发送数据后阻塞,直到A返回数据(或5秒内未接受到来自A的返回raise一个错误),请教如何实现?
问题解答
回答1:用 Tornado 的话,写不了几行代码吧。
先作个简单的 Server ,以方便演示:
# -*- coding: utf-8 -*-from tornado.ioloop import IOLoopfrom tornado.tcpserver import TCPServerfrom tornado import genclass 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 5n’)) else:stream.write(’okn’)if __name__ == ’__main__’: Server().listen(8000) IOLoop.current().start()
然后,来实现 Client ,基本逻辑是,超时就关闭连接,然后再重新建立连接:
# -*- coding: utf-8 -*-import functoolsfrom tornado.ioloop import IOLoopfrom tornado.tcpclient import TCPClientfrom tornado import gendef when_error(stream): print ’ERROR’ stream.close() main()@gen.coroutinedef main(): client = TCPClient() stream = yield client.connect(’localhost’, 8000) count = 0 IL = IOLoop.current() while 1:count += 1stream.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: breakIL.remove_timeout(timer)print datayield gen.Task(IL.add_timeout, IOLoop.current().time() + 1)if __name__ == ’__main__’: main() IOLoop.current().start()
相关文章:
1. angular.js - 请教angularjs里html和js通信的问题2. node.js - 怎么在初始化的时候使得一个子组件不加载?3. android自带时钟应用的这个效果是怎么做的4. 代码如下,java用BigDecimal四舍五入怎么还有问题呀?哪种方式是完全没有问题的?5. javascript - 关于向java后台上传base64位字符串的图片数据,求助6. 求解决方法:Parse error: syntax error, unexpected7. 新人做网站求帮助8. 老师所用的IDE开发环境是什么?9. 请问“由于 Cookie “PHPSESSID”的“SameSite”属性设置为“None”,但缺少“Secure”属性,此 Cookie 未来将被拒绝。”请问出现这个问题怎么办?10. Help!求帮助