Working on server

This commit is contained in:
Davte 2020-03-26 12:32:01 +01:00
parent 971927a798
commit 40dba845fd

View File

@ -1,27 +1,32 @@
import asyncio import asyncio
import collections
import logging import logging
import signal
class Server: class Server:
def __init__(self, host='localhost', input_port=None, output_port=None): def __init__(self, host='localhost', input_port=3001, output_port=3002,
buffer_chunk_size=10**4, buffer_length_limit=10**4):
self._host = host self._host = host
self._input_port = input_port self._input_port = input_port
self._output_port = output_port self._output_port = output_port
self._reader = None self._reader = None
self._writer = None self._writer = None
self._stopping = False self._stopping = False
self.buffer = [] # Shared list self.buffer = collections.deque() # Shared queue of bytes
self._buffer_chunk_size = buffer_chunk_size # How many bytes per chunk
self._buffer_length_limit = buffer_length_limit # How many chunks in buffer
@property @property
def host(self): def host(self) -> str:
return self._host return self._host
@property @property
def input_port(self): def input_port(self) -> int:
return self._input_port return self._input_port
@property @property
def output_port(self): def output_port(self) -> int:
return self._output_port return self._output_port
@property @property
@ -29,45 +34,72 @@ class Server:
return self._reader return self._reader
@property @property
def writer(self) -> asyncio.StreamReader: def writer(self) -> asyncio.StreamWriter:
return self._writer return self._writer
@property @property
def stopping(self) -> bool: def stopping(self) -> bool:
return self._stopping return self._stopping
async def setup_reader(self): @property
reader, _ = await asyncio.open_connection(self.host, self.input_port) def buffer_length_limit(self) -> int:
self._reader = reader return self._buffer_length_limit
async def setup_writer(self): @property
_, writer = await asyncio.open_connection(self.host, self.output_port) def buffer_chunk_size(self) -> int:
self._writer = writer return self._buffer_chunk_size
async def run_server(self): async def run_server(self):
await self.setup_reader() logging.info("===== Started server...")
await asyncio.gather(
self.run_reader(),
self.run_writer()
)
logging.info("... stopped server. =====")
return
async def run_reader(self):
reader, _ = await asyncio.open_connection(self.host, self.input_port)
self._reader = reader
while not self.stopping: while not self.stopping:
try: try:
while len(self.buffer) >= 10**4: # Stop if buffer is full
while len(self.buffer) >= self.buffer_length_limit:
await asyncio.sleep(1) await asyncio.sleep(1)
continue
try: try:
input_data = await self.reader.readexactly(10**4) input_data = await self.reader.readexactly(self.buffer_chunk_size)
except asyncio.IncompleteReadError as e: except asyncio.IncompleteReadError as e:
input_data = e.partial input_data = e.partial
self.buffer.append(input_data) self.buffer.append(input_data)
except Exception as e: except Exception as e:
logging.error(e) logging.error(e)
async def run_writer(self):
_, writer = await asyncio.open_connection(self.host, self.output_port)
self._writer = writer
while not self.stopping:
try:
# Slow down if buffer is short
if len(self.buffer) < 3:
await asyncio.sleep(.1)
try:
input_data = self.buffer.popleft()
except IndexError:
continue
self.writer.write(input_data)
except Exception as e:
logging.error(e)
def stop(self):
self._stopping = True
if __name__ == '__main__': if __name__ == '__main__':
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
try: server = Server()
logging.info("Starting file bridging server...") loop.add_signal_handler(signal.SIGINT, server.stop, loop)
# loop.run_until_complete( logging.info("Starting file bridging server...")
# asyncio.gather( loop.run_until_complete(server.run_server())
# read_input_socket, logging.info("Received KeyboardInterrupt, stopping...")
# write_on_output_socket loop.close()
# )
# )
except KeyboardInterrupt():
logging.info("Received KeyboardInterrupt, stopping...")