gpt4 book ai didi

c++ - 使用 Poco 和 Boost C++ 的多个 Http 服务器

转载 作者:搜寻专家 更新时间:2023-10-31 02:24:08 27 4
gpt4 key购买 nike

我正在尝试使用 Poco::Net 和 Boost 库创建多个 Http 服务器,但在 Poco 文件 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();
}
};

这是服务器的主要代码,例如我在 main 函数中创建服务器。service.post 调用用于方法 exec 的异步调用,service(100) 的构造指的是大小为 100 的线程池.

服务器创建如下:

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

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

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

第二个服务器启动时显示错误。

最佳答案

HttpServerApplication并非旨在以这种方式使用。它被设计成一个单例。

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

您可以通过不从 ServerApplication 派生来修复该部分在你的HttpServer类(class)。毕竟,您需要多个服务器,而不是应用程序。

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

#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 的子类仅出于调用 protected 方法的原因 waitForTerminationRequest()在 main 退出之前。如果需要参数解析,当然传argc, argvapp.run .但在这一点上,我认为没有必要。

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

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

旧答案文本

您如何实例化 HttpServer对象?

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

    具体来说,这是非法的:

    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();
    }
  2. 此外,如果您要在 100 个线程的池上运行它,您需要要么使用 strand (对于逻辑执行线程)锁定HttpServer在任何线程上使用它之前对象。

关于c++ - 使用 Poco 和 Boost C++ 的多个 Http 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28410694/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com