| 85 | |
| 86 | |
| 87 | class BinaryServer(object): |
| 88 | |
| 89 | def __init__(self, internal_server, hostname, port): |
| 90 | self.logger = logging.getLogger(__name__) |
| 91 | self.hostname = hostname |
| 92 | self.port = port |
| 93 | self.iserver = internal_server |
| 94 | self.loop = None |
| 95 | self._server = None |
| 96 | self._policies = [] |
| 97 | self.clients = [] |
| 98 | |
| 99 | def set_policies(self, policies): |
| 100 | self._policies = policies |
| 101 | |
| 102 | def set_loop(self, loop): |
| 103 | self.loop = loop |
| 104 | |
| 105 | def start(self): |
| 106 | prop = dict( |
| 107 | iserver=self.iserver, |
| 108 | loop=self.loop, |
| 109 | logger=self.logger, |
| 110 | policies=self._policies, |
| 111 | clients=self.clients |
| 112 | ) |
| 113 | protocol_factory = type('OPCUAProtocol', (OPCUAProtocol,), prop) |
| 114 | |
| 115 | coro = self.loop.create_server(protocol_factory, self.hostname, self.port) |
| 116 | self._server = self.loop.run_coro_and_wait(coro) |
| 117 | # get the port and the hostname from the created server socket |
| 118 | # only relevant for dynamic port asignment (when self.port == 0) |
| 119 | if self.port == 0 and len(self._server.sockets) == 1: |
| 120 | # will work for AF_INET and AF_INET6 socket names |
| 121 | # these are to only families supported by the create_server call |
| 122 | sockname = self._server.sockets[0].getsockname() |
| 123 | self.hostname = sockname[0] |
| 124 | self.port = sockname[1] |
| 125 | self.logger.warning('Listening on {0}:{1}'.format(self.hostname, self.port)) |
| 126 | |
| 127 | def stop(self): |
| 128 | self.logger.info("Closing asyncio socket server") |
| 129 | for transport in self.iserver.asyncio_transports: |
| 130 | transport.close() |
| 131 | if self._server: |
| 132 | self.loop.call_soon(self._server.close) |
| 133 | self.loop.run_coro_and_wait(self._server.wait_closed()) |
| 134 | self.loop = None |