| 34 | |
| 35 | |
| 36 | class Server(): |
| 37 | def __init__(self, host="", port=0): |
| 38 | self.host = host |
| 39 | self.port = port |
| 40 | self._ws = None |
| 41 | self._server = None |
| 42 | self._site = None |
| 43 | self._start_time = 0 |
| 44 | |
| 45 | |
| 46 | def send(self, msg, binary=True): |
| 47 | if self._ws is not None: |
| 48 | if binary: |
| 49 | asyncio.ensure_future(self._ws.send_bytes(msg, False)) |
| 50 | else: |
| 51 | asyncio.ensure_future(self._ws.send_str(msg, False)) |
| 52 | |
| 53 | |
| 54 | @property |
| 55 | def connected(self): |
| 56 | return self._ws is not None and not self._ws.closed |
| 57 | |
| 58 | |
| 59 | def start(self): |
| 60 | started = False |
| 61 | |
| 62 | self._start_time = int(time()) |
| 63 | |
| 64 | async def _start_a(self): |
| 65 | nonlocal started |
| 66 | self._server = web.Server(self._receive) |
| 67 | |
| 68 | runner = web.ServerRunner(self._server) |
| 69 | await runner.setup() |
| 70 | |
| 71 | self._site = web.TCPSite(runner, self.host, self.port) |
| 72 | await self._site.start() |
| 73 | |
| 74 | started = True |
| 75 | |
| 76 | async_loop.ensure_async_loop() |
| 77 | stop = asyncio.wait_for(_start_a(self), timeout=5.0) |
| 78 | |
| 79 | try: |
| 80 | asyncio.get_event_loop().run_until_complete(stop) |
| 81 | util.refresh() |
| 82 | except asyncio.TimeoutError: |
| 83 | raise RuntimeError(f"Could not start server at {self.host}:{self.port}") |
| 84 | |
| 85 | |
| 86 | def stop(self): |
| 87 | async def _stop_a(): |
| 88 | if self._ws is not None: # no connections happened |
| 89 | await self._ws.close() |
| 90 | await self._site.stop() |
| 91 | await self._site._runner.cleanup() |
| 92 | await self._server.shutdown() |
| 93 | |