proxy - 如何在 Python 中关闭 ZeroMQ zmq.proxy?

标签 proxy daemon zeromq shutdown

我已经在 Python 中实现了一个“网络服务”父类(super class),如下所示:

class NetworkService (threading.Thread):

    """
        Implements a multithreaded network service
    """

    # Class Globals (ie, C++ class static)
    ZmqContext = zmq.Context.instance()

    # ==========================================================================================
    # Class Mechanics
    # ==========================================================================================

    def __init__(self, name, port, conc=4):
        """
            Network service initilization
        """
        self.service_name = name
        self.service_port = port
        self.concurrency = conc
        self.handler_url = "inproc://" + name
        self.client_url = "tcp://*:" + str(port)
        self.shutdown = True # Cleared in run()
        self.thread = {}
        super(NetworkService, self).__init__()

    # ==========================================================================================
    # Class Operation
    # ==========================================================================================

    def run(self): # Called [only] by threading.Thread.start()
        self.shutdown = False

        clients = NetworkService.ZmqContext.socket(zmq.ROUTER)
        clients.bind(self.client_url)

        handlers = NetworkService.ZmqContext.socket(zmq.DEALER)
        handlers.bind(self.handler_url)

        for i in range(self.concurrency):
            self.thread[i] = threading.Thread(target = self.handler, name = self.service_name + str(i))
            self.thread[i].daemon = True
            self.thread[i].start()

        zmq.proxy(clients, handlers)
        clients.close()
        handlers.close()

    def terminate(self):
        self.shutdown = True

    def handler(self):
        socket = NetworkService.ZmqContext.socket(zmq.REP)
        socket.connect(self.handler_url)
        iam = repr(get_pids()[2])
        log.info("nsh@%s is up", iam)
        while not self.shutdown:
            string = socket.recv()
            toe = datetime.utcnow()
            command = pickle.loads(string)
            reply = self.protocol(command)
            string = pickle.dumps(reply)
            socket.send(string)

    def protocol(self, command): # Override this in subclass
        reply = {}
        reply["success"] = False
        reply["detail"] = "No protocol defined (NetworkService.protocol(...) not overridden)"
        if "ident" in command:
            reply["ident"] = command["ident"]
        return reply

问题出在“zmq.proxy(clients, handlers)”行:我似乎无法结束它。曾经。如果所有处理程序终止,zmq.proxy() 仍然不会返回。我不介意创建一个独立的线程来运行代理,但这是在我希望能够干净地关闭的守护进程中。

我在文档中读到这是 zmq.proxy 的正确行为,但对我来说似乎不太正确;-}。

谁能推荐一个近似的等价物,一旦处理程序线程终止就可以关闭?

最佳答案

API 基本上意味着您必须终止上下文。您可以在具有共享上下文的单独线程中运行您的代理,然后终止它,但 zmq.ContextTerminated 除外。

try:
    zmq.proxy(self.frontend, self.backend)
except zmq.ContextTerminated:
    # cleanup if needed

关于proxy - 如何在 Python 中关闭 ZeroMQ zmq.proxy?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32130071/

相关文章:

html - IE8 代理 CSS 兼容性

java - 为什么在 jUnit 测试中非守护线程会终止?

python - 如何使用 zdaemon 创建多个脚本守护进程?

c - 向stderr写入数据使程序成为守护进程后退出

python - 如何将数据从 MetaTrader 4/5 终端发送到外部服务器?

proxy - Node.js 中的 Google GAX/gRPC 不支持 HTTP/S 代理

java - 使用代理服务器使用 Jsch 编写的 Java 中的 SFTP 示例

angularjs - 在代理后面的 Eclipse 中创建 Angular2 项目

javascript - zmq 和express 错误

python - 使用线程在 ZeroMQ REQ/REP 模式的服务器端创建许多回复器套接字