- 场景
使用asyncio.Protocol进行异步连接时,如何断线重连 - code
socket client 放在了单独的一个线程中
soket_server.py
import asyncio
class EchoServerClientProtocol(asyncio.Protocol):
def connection_made(self, transport):
peername = transport.get_extra_info('peername')
print('Connection from {}'.format(peername))
self.transport = transport
def data_received(self, data):
message = data.decode()
print('Data received: {!r}'.format(message))
message = "Hello Client"
self.transport.write(data)
self.transport.close()
loop = asyncio.get_event_loop()
# Each client connection will create a new protocol instance
coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888)
server = loop.run_until_complete(coro)
# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
loop.run_forever()
except KeyboardInterrupt:
pass
# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
l
socket_client.py
import asyncio
from threading import Thread
class EchoClientProtocol(asyncio.Protocol):
def __init__(self, loop):
self.loop = loop
self.host, self.port = None, None
def connection_made(self, transport):
print('connected')
self.host, self.port = transport.get_extra_info('peername')
message = "Hello Server"
transport.write(message.encode())
print('Data sent: {!r}'.format(message))
def data_received(self, data):
print('Data received: {!r}'.format(data.decode()))
def connection_lost(self, exc):
print('disconnected')
# reconnected after 5 seconds
self.loop.call_later(5, reconnect, self.host, self.port)
class SocketClient(Thread):
def __init__(self, host, port):
Thread.__init__(self)
self.host, self.port = host, port
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop)
def run(self):
protocol = EchoClientProtocol(self.loop)
self.loop.run_until_complete(do_connect(self.loop, self.host, self.port, protocol))
self.loop.run_forever()
self.loop.close()
def reconnect(host, port):
protocol = EchoClientProtocol(single_client.loop)
single_client.loop.create_connection(lambda: protocol, host=host, port=port)
asyncio.async(do_connect(single_client.loop, host, port, protocol))
@asyncio.coroutine
def do_connect(loop, ip, port, protocol):
while True:
try:
yield from loop.create_connection(lambda: protocol, host=ip, port=port)
except OSError as e:
print("{}, retrying in 5 seconds")
yield from asyncio.sleep(5)
else:
break
single_client = SocketClient('127.0.0.1', 8888)
single_client.run()
client输出
connected
Data sent: 'Hello Server'
Data received: 'Hello Server'
disconnected
connected
Data sent: 'Hello Server'
Data received: 'Hello Server'
disconnected
connected
Data sent: 'Hello Server'
Data received: 'Hello Server'
disconnected
网友评论