From 6e6894c22179abf5ecbcefe2dcf0ee00ec3438c1 Mon Sep 17 00:00:00 2001 From: "hufeng.mao" Date: Mon, 5 Dec 2022 15:12:24 +0800 Subject: [PATCH] feat: share bus --- README.rst | 10 +++++++ can_remote/server.py | 62 +++++++++++++++++++++---------------------- can_remote/version.py | 2 +- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/README.rst b/README.rst index ba44c30..96c9020 100644 --- a/README.rst +++ b/README.rst @@ -53,3 +53,13 @@ It is available on the same address using HTTP, e.g. http://localhost:54701/. .. _python-can: https://python-can.readthedocs.org/en/stable/ + +dev 分支改动 +------------ + +这个分支在`master@0.2.1`基础上做了一些修改, 具体改动如下: + +1. 启动 `RemoteServer` 后立即打开 `target_bus`, 并从 `target_bus` 中 `recv message`. +2. `recv` 有效 `message` 后, 遍历所有 `connected client list`, 并分发 `message` +3. 当有 `client` 连上后, 放入 `connected client list` +4. `client` 关闭后, 从 `connected client list` 中移除. \ No newline at end of file diff --git a/can_remote/server.py b/can_remote/server.py index 907f2da..2893779 100644 --- a/can_remote/server.py +++ b/can_remote/server.py @@ -55,6 +55,10 @@ def __init__(self, host='0.0.0.0', port=DEFAULT_PORT, ssl_context=None, **config self.clients = [] HTTPServer.__init__(self, address, ClientRequestHandler) logger.info("Server listening on %s:%d", address[0], address[1]) + try: + self.bus = can.interface.Bus(**config) + except Exception as exc: + raise if ssl_context: self.socket = ssl_context.wrap_socket(self.socket, server_side=True) scheme_suffix = "s" @@ -64,6 +68,28 @@ def __init__(self, host='0.0.0.0', port=DEFAULT_PORT, ssl_context=None, **config scheme_suffix, self.server_port) logger.info("Open browser to 'http%s://localhost:%d/'", scheme_suffix, self.server_port) + + self.running = True + self._send_thread = threading.Thread(target=self._send_to_client) + self._send_thread.daemon = True + self._send_thread.start() + + + def _send_to_client(self): + """Continuously read CAN messages and send to client.""" + while self.running: + try: + msg = self.bus.recv(0.5) + except Exception as e: + logger.exception(e) + for client in self.clients: + client.send_error(e) + else: + if msg is not None: + for client in self.clients: + client.send_msg(msg) + logger.info('Disconnecting from CAN bus') + self.bus.shutdown() class ClientRequestHandler(BaseHTTPRequestHandler): @@ -98,7 +124,7 @@ def start_websocket(self): self.end_headers() websocket = WebSocket(None, protocol, sock=self.request) - protocol = RemoteServerProtocol(self.server.config, websocket) + protocol = RemoteServerProtocol(self.server.bus, websocket) self.server.clients.append(protocol) protocol.run() logger.info("Closing connection to %s", self.address_string()) @@ -129,56 +155,30 @@ def send_trace_webpage(self): class RemoteServerProtocol(RemoteProtocolBase): - def __init__(self, config, websocket): + def __init__(self, bus, websocket): super(RemoteServerProtocol, self).__init__(websocket) event = self.recv() if not event or event["type"] != "bus_request": print(event) raise RemoteServerError("Client did not send a bus request") - new_config = {} - new_config.update(event["payload"]["config"]) - logger.info("Config received: %r", new_config) - new_config.update(config) - self.config = new_config - try: - self.bus = can.interface.Bus(**new_config) - except Exception as exc: - self.terminate(exc) - raise + + self.bus = bus + logger.info("Connected to bus '%s'", self.bus.channel_info) self.send_bus_response(self.bus.channel_info) self.running = True self._send_tasks = {} - self._send_thread = threading.Thread(target=self._send_to_client) - self._send_thread.daemon = True def send_bus_response(self, channel_info): self.send("bus_response", {"channel_info": channel_info}) def run(self): - self._send_thread.start() try: self._receive_from_client() except Exception as exc: self.terminate(exc) finally: self.running = False - if self._send_thread.is_alive(): - self._send_thread.join(3) - - def _send_to_client(self): - """Continuously read CAN messages and send to client.""" - while self.running: - try: - msg = self.bus.recv(0.5) - except Exception as e: - logger.exception(e) - self.send_error(e) - else: - if msg is not None: - self.send_msg(msg) - logger.info('Disconnecting from CAN bus') - self.bus.shutdown() def _receive_from_client(self): """Continuously read events from socket and send messages on CAN bus.""" diff --git a/can_remote/version.py b/can_remote/version.py index 3ced358..0dddc48 100644 --- a/can_remote/version.py +++ b/can_remote/version.py @@ -1 +1 @@ -__version__ = "0.2.1" +__version__ = "0.2.1-dev"