2015-02-09 19 views
2

我試圖創建波科::淨多個HTTP服務器和Boost庫,但在內部出現以下錯誤波科文件Application.cpp多個HTTP服務器與波索和Boost C++

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
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的異步調用和服務的結構(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 

第二臺服務器啓動時顯示錯誤。

回答

2

HttpServerApplication不適用於這種方式。它的設計是一個單身人士。

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

您可以通過從ServerApplicationHttpServer類派生未修復的一部分。畢竟,你需要多個服務器,而不是應用程序。

在我簡單的測試,以下工作:

#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一個子類的主要退出前claling受保護的方法waitForTerminationRequest()的唯一原因。如果你需要參數解析,當然通過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(); 
    } 
} 

OLD答覆文件

你是如何實例化對象HttpServer

  1. 你應該很明顯,使用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(); 
    } 
    
  2. 另外,如果你要在100個線程池運行它,你需要要麼使用一個strand(執行的邏輯線程)鎖在任何線程上使用它之前,請使用HttpServer對象。

+0

林實例化沒有問題: 的boost :: shared_ptr的服務器(新的HttpServer( 「127.0.0.1」,8080)); 實例化和鎖定不是問題= /,謝謝。 – lopes 2015-02-09 13:33:29

+0

@lopes我不懷疑你的確如此。但是,您不顯示該代碼。所以這是首先要檢查的。 (請將它添加到問題而不是在評論中) – sehe 2015-02-09 13:34:54

+0

@lopes我已經做了一些簡單的測試,並更新了我的答案。 – sehe 2015-02-09 15:13:37