加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – Autobahn Asyncio ReconnectingClientFactory

发布时间:2020-12-20 13:12:26 所属栏目:Python 来源:网络整理
导读:我想用asyncio创建一个ReconnectingClientFactory.特别是为了处理客户端启动时服务器不可用的情况,在这种情况下ReconnectingClientFactory将继续尝试.这是asyncio.events.create_connection不能做的事情. 具体来说: EchoClient例子没问题. 关键是如何建立联
我想用asyncio创建一个ReconnectingClientFactory.特别是为了处理客户端启动时服务器不可用的情况,在这种情况下ReconnectingClientFactory将继续尝试.这是asyncio.events.create_connection不能做的事情.

具体来说:

EchoClient例子没问题.
关键是如何建立联系.

factory = EchoClientFactory('ws://127.0.0.1:5678')
connectWS(factory)

在使用ReconnectingClientFactory的扭曲版本的情况下.

VS

factory = EchoClientFactory(u"ws://127.0.0.1:5678")
factory.protocol = SecureServerClientProtocol

loop = asyncio.get_event_loop()

# coro = loop.create_connection(factory,'ws_server',5678)
coro = loop.create_connection(factory,'127.0.0.1',5678)

loop.run_until_complete(asyncio.wait([
    alive(),coro
]))
loop.run_forever()
loop.close()

或者类似于asycnio版本.

问题是在asyncio版本中,连接是由asyncio.events.create_connection建立的,如果服务器不可用,它就会失败.

我怎样才能调和这两个?

非常感谢

解决方法

我想我得到了你想要的东西.这是基于 asyncio TCP echo client protocol example的代码和示例.

import asyncio
import random


class ReconnectingTCPClientProtocol(asyncio.Protocol):
    max_delay = 3600
    initial_delay = 1.0
    factor = 2.7182818284590451
    jitter = 0.119626565582
    max_retries = None

    def __init__(self,*args,loop=None,**kwargs):
        if loop is None:
            loop = asyncio.get_event_loop()
        self._loop = loop
        self._args = args
        self._kwargs = kwargs
        self._retries = 0
        self._delay = self.initial_delay
        self._continue_trying = True
        self._call_handle = None
        self._connector = None

    def connection_lost(self,exc):
        if self._continue_trying:
            self.retry()

    def connection_failed(self,exc):
        if self._continue_trying:
            self.retry()

    def retry(self):
        if not self._continue_trying:
            return

        self._retries += 1
        if self.max_retries is not None and (self._retries > self.max_retries):
            return

        self._delay = min(self._delay * self.factor,self.max_delay)
        if self.jitter:
            self._delay = random.normalvariate(self._delay,self._delay * self.jitter)
        self._call_handle = self._loop.call_later(self._delay,self.connect)

    def connect(self):
        if self._connector is None:
            self._connector = self._loop.create_task(self._connect())

    async def _connect(self):
        try:
            await self._loop.create_connection(lambda: self,*self._args,**self._kwargs)
        except Exception as exc:
            self._loop.call_soon(self.connection_failed,exc)
        finally:
            self._connector = None

    def stop_trying(self):
        if self._call_handle:
            self._call_handle.cancel()
            self._call_handle = None
        self._continue_trying = False
        if self._connector is not None:
            self._connector.cancel()
            self._connector = None


if __name__ == '__main__':
    class EchoClientProtocol(ReconnectingTCPClientProtocol):
        def __init__(self,message,**kwargs):
            super().__init__(*args,**kwargs)
            self.message = message

        def connection_made(self,transport):
            transport.write(self.message.encode())
            print('Data sent: {!r}'.format(self.message))

        def data_received(self,data):
            print('Data received: {!r}'.format(data.decode()))

        def connection_lost(self,exc):
            print('The server closed the connection')
            print('Stop the event loop')
            self._loop.stop()


    loop = asyncio.get_event_loop()
    client = EchoClientProtocol('Hello,world!',8888,loop=loop)
    client.connect()
    loop.run_forever()
    loop.close()

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读