使用Poco和Boost C++的多个Http服务器
Multiple Http Servers with Poco and Boost C++
我正试图用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();
}
};
这是服务器的主代码,例如,我在主功能中创建服务器。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
您可以通过不从HttpServer
类中的ServerApplication
派生来修复该部分。毕竟,您需要多个服务器,而不是应用程序。
在我最简单的测试中,以下方法有效:
#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
。但在这一点上,我认为没有必要。
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
对象的?
显然,应该使用
boost::make_shared<HttpServer>(host, port)
(或shared_ptr<HttpServer>(new HttpServer(host, port))
)来允许使用enable_shared_from_this
。不要忘记至少在服务启动之前保留共享ptr(通过将其exec()
调用发布到io_service
)。具体来说,这是非法的:
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
对象之前锁定它。- 为什么在使用boost::asio时,我需要每个连接一条绞线
- 在 MySQL 中运行 HTTP 服务器以从客户端接收数据
- 我不明白异步操作如何使HTTP服务器并发
- 将文件发送到 HTTP 服务器 (C++ Wininet)
- boost::asio http 服务器无法向 Postman 返回有效响应
- 如果C/C Python3扩展托管HTTP服务器并将Python代码称为请求处理程序,则如何处理并发
- QT-简单的HTTP服务器
- Apache HTTP服务器 - 如何在模块上打印到控制台
- Windows HTTP服务器API HTTPS服务器
- 在多线程HTTP服务器中发送后,如何干净地关闭套接字
- Boost Asio 示例 HTTP 服务器 -- 以这个例子为例,让它变得"production ready"
- AJAX与C HTTP服务器断开连接
- 如何在boostc++中添加http服务器端口的路径
- 使用 BSD 套接字的 HTTP 服务器不关闭连接或与 Windows 浏览器通信
- 如果我访问该页面,带有casablanca的http服务器将崩溃
- Boost http服务器示例不起作用
- 带有libevent的多线程HTTP服务器
- 为什么在读取非HTTP服务器的套接字时需要异步IO
- 使用Poco和Boost C++的多个Http服务器
- 铬中的NPAPI tcp http服务器c++
- 登录 HTTP 服务器 c++