import abc import asyncio import struct class __InternalProtocol(asyncio.Protocol): __reader:asyncio.StreamReader def __init__(self, reader:asyncio.StreamReader): assert isinstance(reader, asyncio.StreamReader) self.__reader = reader async def _drain_helper(self): pass class __InternalTransport(asyncio.WriteTransport): __close: bool __reader: asyncio.StreamReader def __init__(self, reader: asyncio.StreamReader): self.__close = True assert isinstance(reader, asyncio.StreamReader) self.__reader = reader def close(self): self.__close = False self.__reader.feed_eof() def is_closing(self): return not self.__close def write(self, data: bytes): self.__reader.feed_data(data) def create_internal_stream(loop=None): if loop is None: loop = asyncio.get_event_loop() reader = asyncio.StreamReader(loop=None) internal_protocol = __InternalProtocol(reader) internal_transport = __InternalTransport(reader) writer = asyncio.StreamWriter(internal_transport, internal_protocol, reader=reader, loop=loop) return reader, writer class BaseConnectionServer(abc.ABC): __in:asyncio.StreamReader __out:asyncio.StreamWriter __size_format = struct.Struct("!I") def __init__(self, in_io:asyncio.StreamReader, out_io:asyncio.StreamWriter): if not isinstance(in_io, asyncio.StreamReader): raise TypeError("in_io have to be a stream reader.") if not isinstance(out_io, asyncio.StreamWriter): raise TypeError("out_io have to be a stream writer.") self.__in, self.__out = in_io, out_io async def init(self): # Send own config self.__out.write(self.__size_format.pack(0)) await self.__out.drain() # Read other config size = self.__size_format.unpack(await self.__in.readexactly(self.__size_format.size))[0] await self.__in.readexactly(size) # Send applied config self.__out.write(self.__size_format.pack(0)) await self.__out.drain() # Read other applied config size = self.__size_format.unpack(await self.__in.readexactly(self.__size_format.size))[0] await self.__in.readexactly(size)