带有Poco和Boost C ++的多个Http服务器 [英] Multiple Http Servers with Poco and Boost C++

查看:195
本文介绍了带有Poco和Boost C ++的多个Http服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Poco :: Net和Boost库创建多个Http服务器,但是在Poco文件 Application.cpp 中内部发生以下错误:

I'm trying to create multiple Http servers with Poco::Net and Boost libraries, but is occurring the following error internally in Poco file Application.cpp:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Assertion violation: _pInstance == 0 [in file "src/Application.cpp", line 115]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

我正在使用以下代码:

#include <Poco/Net/HTMLForm.h>
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <boost/asio/io_service.hpp>

boost::asio::io_service service(100);

class RequestHandler : public Poco::Net::HTTPRequestHandler {
public:
    RequestHandler(){}
    void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response){}
};

class RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
    RequestHandlerFactory(){}
    Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request)
    {
        return new RequestHandler();
    }
};

class HttpServer :
        public Poco::Util::ServerApplication,
        public boost::enable_shared_from_this<HttpServer>{

    Poco::Net::ServerSocket svs;
    Poco::Net::HTTPServer srv;

public:
    HttpServer(std::string address_, Poco::UInt16 port_):
        svs(Poco::Net::SocketAddress(address_.empty() ? "127.0.0.1" : address_, port_)),
        srv(new RequestHandlerFactory(), svs, new Poco::Net::HTTPServerParams)
    {
        svs.setReuseAddress(true);
        svs.setReusePort(true);
    }

    virtual ~HttpServer(){}

    void start()
    {
        service.post(
            boost::bind(&HttpServer::exec, shared_from_this()));
    }

    void stop()
    {
        srv.stop();
    }

private:
    void exec()
    {
        srv.start();
        waitForTerminationRequest();
        srv.stop();
    }    
};

这是服务器的主要代码,例如,Im在主要功能处创建服务器. service.post 调用用于方法 exec 的异步调用, service(100)的构造引用大小为100的线程池

This is the main code of server, and Im creating the servers at main function for example. The service.post call, is for asynchronous call of method exec and the construction of service(100) refers to a thread pool of size 100.

服务器创建如下:

boost::shared_ptr<HttpServer> server(
        new HttpServer("", 8080));

boost::shared_ptr<HttpServer> server2(
        new HttpServer("", 8181));

server->start();
server2->start(); // Error occurs here

启动第二台服务器时显示错误.

The error is shown when the second server is started.

推荐答案

HttpServerApplication并非设计用于这种方式.它被设计为一个单例.

HttpServerApplication is not designed to be used in this way. It's designed to be a singleton.

http://pocoproject.org/docs/Poco.Util.ServerApplication.html

您可以通过不继承HttpServer类中的ServerApplication来修复该部分.毕竟,您需要多个服务器,而不是应用程序.

You can fix that part by not deriving from ServerApplication in your HttpServer class. After all, you want multiple servers, not applications.

在我最简单的测试中,以下工作有效:

In my simplest test, the following works:

#include <Poco/Net/HTMLForm.h>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPRequestHandlerFactory.h>
#include <Poco/Net/ServerSocket.h>
#include <Poco/Net/HTTPServer.h>
#include <Poco/Util/ServerApplication.h>
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/make_shared.hpp>
#include <boost/bind.hpp>

boost::asio::io_service service(100);

class RequestHandler : public Poco::Net::HTTPRequestHandler {
public:
    RequestHandler(){}
    void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response){}
};

class RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
    RequestHandlerFactory(){}
    Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request)
    {
        return new RequestHandler();
    }
};

class HttpServer : public boost::enable_shared_from_this<HttpServer>{

    Poco::Net::ServerSocket svs;
    Poco::Net::HTTPServer srv;

public:
    HttpServer(std::string address_, Poco::UInt16 port_):
        svs(Poco::Net::SocketAddress(address_.empty() ? "127.0.0.1" : address_, port_)),
        srv(new RequestHandlerFactory(), svs, new Poco::Net::HTTPServerParams)
    {
        svs.setReuseAddress(true);
        svs.setReusePort(true);
    }

    virtual ~HttpServer(){}

    void start()
    {
        service.post(
            boost::bind(&HttpServer::exec, shared_from_this()));
    }

    void stop()
    {
        srv.stop();
    }

private:
    void exec()
    {
        srv.start();
    }    
};

main中,我创建ServerApplication的子类的唯一原因是在main退出之前将受保护的方法waitForTerminationRequest()连接起来.如果您需要参数解析,则当然将argc, argv传递给app.run.但是目前我看不到需要.

In main, I create a subclass of ServerApplication for the sole reason of claling the protected method waitForTerminationRequest() before exit of main. If you need argument parsing, of course pass argc, argv to app.run. But at this point I don't see the need.

int main() {
    struct App : Poco::Util::ServerApplication {
        ~App() {
            waitForTerminationRequest();
        }
    } app;

    for (int i=0; i<2; ++i) {
        boost::make_shared<HttpServer>("", 8080+i)->start();
    }
}


旧答案文本


OLD ANSWER TEXT

如何实例化HttpServer对象?

  1. 很明显,您应该使用boost::make_shared<HttpServer>(host, port)(或shared_ptr<HttpServer>(new HttpServer(host, port)))来允许enable_shared_from_this.至少在服务启动之前(通过将其exec()调用发布到io_service),不要忘记保留共享的ptr.

  1. You should, obviously, use boost::make_shared<HttpServer>(host, port) (or shared_ptr<HttpServer>(new HttpServer(host, port))) for enable_shared_from_this to be allowed. Don't forget to hold on to the shared ptr at least until the service has been started (by posting it's exec() call to io_service).

具体来说,这是非法的:

Specifically, this is illegal:

for (int i=0; i<10; ++i) {
    HttpServer s("", 8080+i);
    s.start();
}

请使用例如

for (int i=0; i<10; ++i) {
    boost::make_shared<HttpServer>("", 8080+i)->start();
}

  • 此外,如果要在100个线程的池中运行它,则 需要 可以使用strand(对于逻辑执行线程) 在将HttpServer对象用于任何线程之前将其锁定.

  • Also, if you're going to run it on a pool of 100 threads, you need to either use a strand (for a logical thread of execution) or lock the HttpServer object before you use it on any thread.

    这篇关于带有Poco和Boost C ++的多个Http服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆