カンタンWebサーバを作る
アプリケーション組み込み型Webサーバの用途として、独自のGUI画面の代わりに、ブラウザを使用するアプリケーションをイメージしています。例えば、「Googleデスクトップ」のような感じです。Googleデスクトップは、設定メニューを呼び出すと、ブラウザが立ち上がります。URL入力欄をよく見てください。
どこかのWebサーバと通信しているわけではなく、ローカルのWebサーバと通信して設定画面をブラウザに表示しているのです。この形であれば、ローカルの環境にあまり左右されずに、柔軟なGUI画面を構成できるのではないでしょうか。
プロジェクトを作る
では、まず新規のプロジェクトを作ります。[新規作成]メニューで、プロジェクトを選択します。新しいプロジェクトのダイアログが表示されるので、Win32コンソールアプリケーションのテンプレートを選び、プロジェクト名は任意の名前、例えば「MiniWebServer」にします。[OK]をクリックすると、アプリケーションウィザードの設定になりますので、アプリケーションの種類を「コンソールアプリケーション」にします。
「MiniWebServer.cpp」の中身
サンプルと同様、「MiniWebServer.cpp」の1ファイルにクラスの定義と実装を記述することにします。
#include "stdafx.h" #include "Poco/Net/HTTPServer.h" #include "Poco/Net/HTTPRequestHandler.h" #include "Poco/Net/HTTPRequestHandlerFactory.h" #include "Poco/Net/HTTPServerParams.h" #include "Poco/Net/HTTPServerRequest.h" #include "Poco/Net/HTTPServerResponse.h" #include "Poco/Net/HTTPServerParams.h" #include "Poco/Net/ServerSocket.h" #include "Poco/Util/ServerApplication.h" #include "Poco/File.h" class NotFileHandler: public Poco::Net::HTTPRequestHandler { public: void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) { response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_NOT_FOUND); response.setContentType("text/html"); std::ostream& ostr = response.send(); ostr << "<html><head>"; ostr << "<title>MiniWebServer powered by POCO</title>"; ostr << "</head><body>ファイルがありません<br />"; ostr << "</body></html>"; } }; class FileRequestHandler: public Poco::Net::HTTPRequestHandler { public: void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) { try{ std::string fpass = "."; fpass += request.getURI(); response.sendFile(fpass, "text/html"); } catch(Poco::Exception& ) { } } }; class MiniRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory { public: Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) { std::string fpass = "."; fpass += request.getURI(); Poco::File f(fpass); if ( !f.exists() || !f.isFile() ) return new NotFileHandler(); return new FileRequestHandler(); } }; class MiniWebServer: public Poco::Util::ServerApplication { protected: int main(const std::vector<std::string>& args) { int maxThreads = 1; // クライアント最大同時接続数 // 接続スレッド数設定 Poco::ThreadPool::defaultPool().addCapacity(maxThreads); // 設定値クラス Poco::Net::HTTPServerParams* pParams = new Poco::Net::HTTPServerParams; pParams->setMaxQueued(100); // 接続要求ソケット最大数 pParams->setMaxThreads(maxThreads); Poco::Net::ServerSocket svs(9980); // 9980ポート使用 // HTTPサーバクラスのインスタンス Poco::Net::HTTPServer srv(new MiniRequestHandlerFactory(), svs, pParams); srv.start(); // サーバ動作開始 waitForTerminationRequest(); // CTRL-C が押されるまで、 // またはプロセスが強制終了されるまで待機 srv.stop(); // サーバ動作ストップ return Application::EXIT_OK; } }; int _tmain(int argc, _TCHAR* argv[]) { MiniWebServer app; return app.run(argc, argv); }
サンプルソースではusing宣言を用いて、各クラスの名前空間の記述を省略していました。それでは、どれがPOCOのクラスが分かりにくいので、MiniWebServer.cppでは、名前空間も省略せずに記述しています。例えば、ServerApplicationを、Poco::Util::ServerApplicationとしています。