diff --git a/src/meshcat/servers/zmqserver.py b/src/meshcat/servers/zmqserver.py index 3b7e39a..fd28135 100644 --- a/src/meshcat/servers/zmqserver.py +++ b/src/meshcat/servers/zmqserver.py @@ -4,6 +4,7 @@ import base64 import os import re +import signal import sys import subprocess import multiprocessing @@ -406,10 +407,21 @@ def main(): if results.open: webbrowser.open(bridge.web_url, new=2) + def cleanup(): + bridge.zmq_socket.close() + bridge.context.destroy() + + # Make sure also kill results in socket being closed otherwise ZMQbg/Reaper and IO processes might stay open + atexit.register(cleanup) + signal.signal(signal.SIGTERM, cleanup) + signal.signal(signal.SIGINT, cleanup) + try: bridge.run() except KeyboardInterrupt: pass + finally: + cleanup() if __name__ == '__main__': main() diff --git a/src/meshcat/visualizer.py b/src/meshcat/visualizer.py index b7b9264..7960d31 100644 --- a/src/meshcat/visualizer.py +++ b/src/meshcat/visualizer.py @@ -1,3 +1,4 @@ +import signal import webbrowser import umsgpack import numpy as np @@ -79,6 +80,12 @@ def get_image(self, w, h): img = Image.open(io.BytesIO(img_bytes)) return img + def close(self): + self.zmq_socket.close() + self.context.destroy() + if self.server_proc is not None: + self.server_proc.kill() + self.server_proc.wait() def srcdoc_escape(x): return x.replace("&", "&").replace('"', """)