【问题标题】:ZeroMQ XSUB/XPUB proxy() API is not returningZeroMQ XSUB/XPUB proxy() API 没有返回
【发布时间】:2018-02-28 16:04:50
【问题描述】:

我使用 POCO 库编写了一个演示 Windows 服务。

根据 POCO API,函数 waitForTerminationRequest() 等待服务终止请求。

现在,在这个基于 POCO 的 Windows 服务中,我想启动一个基于 ZeroMQ 库的消息队列代理来实现 XSUB/XPUB 消息队列。

更多信息可以在这里http://zguide.zeromq.org/page:all了解。

为此我写了另一个class ZeroMQProxy,它在服务的主函数中启动代理。

class ZeroMQProxy
{
private:
    zmq::context_t context;
    zmq::socket_t xsub;
    zmq::socket_t xpub;

public:
    ZeroMQProxy()
        : context(1),
        xsub(context, ZMQ_XSUB),        // Publisher End Proxy Sockets
        xpub(context, ZMQ_XPUB)         // Subscriber End Proxy Sockets
    {
    }

    ~ZeroMQProxy()
    {
    }

    void proxyopen()
    {
        xsub.bind("tcp://*:5559");
        xpub.bind("tcp://*:5560");

        zmq::proxy(xsub, xpub, nullptr);
    }

    void proxyclose()
    {
    }
};

class demopocoservice : public ServerApplication
{
private:
    bool _helpRequested;

public:
    demopocoservice() : _helpRequested(false)
    {
    }

    ~demopocoservice()
    {
    }

protected:
    void initialize(Application& self)
    {
        loadConfiguration();
        ServerApplication::initialize(self);
    }

    void uninitialize()
    {
        ServerApplication::uninitialize();
    }

    void defineOptions(OptionSet& options)
    {
        ServerApplication::defineOptions(options);

        options.addOption(
            Option("help", "h", "poco display help")
            .required(false)
            .repeatable(false)
            .callback(OptionCallback<demopocoservice>(
                this, &demopocoservice::handleHelp)));
    }

    void handleHelp(const std::string& name,
        const std::string& value)
    {
        _helpRequested = true;
        displayHelp();
        stopOptionsProcessing();
    }

    void displayHelp()
    {
        HelpFormatter helpFormatter(options());
        helpFormatter.setCommand(commandName());
        helpFormatter.setUsage("OPTIONS");
        helpFormatter.setHeader("poco: Zero message Queue.");
        helpFormatter.format(std::cout);
    }

    int main(const ArgVec& args)
    {
        if (!_helpRequested)
        {
            ZeroMQProxy zmqproxyObj;
            zmqproxyObj.proxyopen();

            waitForTerminationRequest();

            zmqproxyObj.proxyclose();
        }
        return Application::EXIT_OK;
    }
};


int main(int argc, char** argv)
{
    cout << "Hello Poco ZMQ\n";

    demopocoservice pobj;
    pobj.run(argc, argv);

    return 0;
}

我的目标是当我启动服务时,zmq::proxy() 应该已经启动了代理,当我停止服务时,代理应该与套接字一起关闭。

问题是 zmq::proxy() 没有返回。 所以我无法停止服务。
即使我这样做 net stop &lt;service name&gt;waitForTerminationRequest() 也不会因为zmq::proxy() 而收到终止请求。

当我停止服务时,我应该如何停止/关闭代理?

【问题讨论】:

    标签: zeromq poco poco-libraries


    【解决方案1】:

    ZeroMQ API 证实了这一点:

    说明

    zmq_proxy() 函数在当前应用程序线程中启动内置的 ØMQ 代理
    ...

    在调用 zmq_proxy() 之前,您必须设置任何套接字选项,并连接或绑定 frontendbackend 套接字。两种传统的代理模型是:

    zmq_proxy() 在当前线程中运行并且仅在当前上下文关闭时返回

    鉴于这一事实,最好实例化一个独立线程,让代理在那里运行并让调用者返回,以便继续您的其他代码执行流程,保持独立于独立的 zmq_proxy() 执行。

    另一个公平的做法是(总是)设置 LINGER == 0,然后再采取任何进一步的步骤和/或措施来使用新实例化的套接字。

    【讨论】:

    • 我曾尝试在 poco 可运行线程中调用 proxy()。但这并没有帮助。类 ZMQThread : public Poco::Runnable void run() { ZeroMQProxy zmqproxyObj; zmqproxyObj.proxyopen();在服务的 main 中调用上述线程为:MQThread mqOne("Poco One", 4); Poco::Thread threadOne; threadOne.start(mqOne); threadOne.join();
    猜你喜欢
    • 2015-04-21
    • 1970-01-01
    • 2015-07-03
    • 2017-07-23
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多