1
0

server.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import asyncio
  2. import json
  3. from . jrequest import request_type
  4. class AServer(object):
  5. """
  6. Initalizes a new asynchronous server object.
  7. This server invokes methods with request_type decorators,
  8. when data is read. See requests.py
  9. """
  10. def __init__(self, port, bot):
  11. print(request_type.get_types())
  12. self.port = port
  13. self.bot = bot
  14. # constants
  15. self.BUFFER_SIZE = 512
  16. # privates
  17. self.__writer = None
  18. self.__alive = False
  19. self.__loop = None
  20. def start(self):
  21. """
  22. Starts the asynchronous server on the given port.
  23. """
  24. self.__loop = asyncio.get_event_loop()
  25. self.__alive = True
  26. coro = asyncio.start_server(self.handle_connection, '0.0.0.0', self.port)
  27. asyncio.ensure_future(coro)
  28. # try:
  29. # self.__loop.run_forever()
  30. # finally:
  31. # self.__loop.close()
  32. def stop(self):
  33. """
  34. Stops the asynchronous server.
  35. """
  36. self.__loop.stop()
  37. self.__alive = False
  38. async def handle_connection(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
  39. """
  40. Handles a new client connection using NIO.
  41. When reading, it invokes the suitable request callback depending
  42. on the JSON request.
  43. :param: reader, the stream reader to read data from (in bytes)
  44. :param: writer, the stream writer to write data to (in bytes)
  45. """
  46. print("Incoming client connection")
  47. try:
  48. self.__writer = writer
  49. while self.__alive:
  50. #await self.write("hi")
  51. data = await reader.readuntil(b"\r\n")
  52. data = data.decode('ascii')
  53. print(data)
  54. try:
  55. # try parse the JSON, then get the type of request
  56. data = json.loads(data)
  57. # if it's a /terminate/ type, terminate the server
  58. if(data['type'] == 'terminate'):
  59. self.stop()
  60. # invoke a callback belonging to a requset type if it is available
  61. funcs = request_type.get_types()
  62. if(funcs.get(data['type'])):
  63. await funcs[data['type']](self, data)
  64. except:
  65. pass
  66. except ConnectionError:
  67. self._writer = None
  68. print("Client disconnected")
  69. async def write(self, message: str):
  70. """
  71. Writes data to the stream writer
  72. """
  73. if self.__writer == None:
  74. return
  75. self.__writer.write(message.encode())
  76. await self.__writer.drain()