使用 acl_cpp 的 HttpServlet 類及服務器框架編寫WEB服務器程序

 

      在 《用C++實現相似於JAVA HttpServlet 的編程接口 》 文章中講了如何用 HttpServlet 等相關類編寫 CGI 程序,因而有網友提出了 CGI 程序低效性,不錯,確實 CGI 程序的進程開銷是比較大的,本文就將說明依然是這些 HTTP 相關的類,若是在使用 acl_cpp/src/master 下的服務器框架類的條件下,能夠很是方便地轉爲服務器程序。如今依然是使用 《用C++實現相似於JAVA HttpServlet 的編程接口 》示例中的 http_servlet 類,只是稍微修改一下 main 函數,就變成下面的情形:編程

 

 

//////////////////////////////////////////////////////////////////////////

class master_service : public acl::master_proc
{
public:
	master_service() {}
	~master_service() {}
protected:
	// 基類虛函數,當接收到一個 HTTP 客戶端請求時,服務器
	// 框架回調此函數將鏈接流傳入
	virtual void on_accept(acl::socket_stream* stream)
	{
		// HttpServlet 的子類實例
		http_servlet servlet("127.0.0.1:11211");
		servlet.setLocalCharset("gb2312");  // 設置本地字符集
		servlet.doRun(stream);  // 開始處理瀏覽器請求過程
	}
};

//////////////////////////////////////////////////////////////////////////

int main(int argc, char* argv[])
{
	acl::acl_cpp_init();  // 初始化 acl_cpp 庫
	master_service service;  // 半駐留進程池服務類對象

	// 開始運行

	if (argc >= 2 && strcmp(argv[1], "alone") == 0)
	{
		// 當在手工調試時通常採用此方式
		printf("listen: 127.0.0.1:8888 ...\r\n");
		service.run_alone("127.0.0.1:8888", NULL, 1);  // 單獨運行方式
	}
	else  // 生產環境中以半駐留進程池模式運行
		service.run_daemon(argc, argv);  // acl_master 控制模式運行

	return 0;
}

 

      上面的例子是一個結合 HttpServlet 類及 master_service 進程池服務類的 HTTP 服務器程序,關於進程池的例子,能夠先結合本人原來寫過的基於C語言庫 acl 的一篇文章《快速建立你的服務器程序--single進程池模型 》。瀏覽器

 

      不只能夠很是容易地將 HttpServlet 寫成進程池方式,同時還能夠結合 acl_cpp 的線程池框架模板,將 HttpServlet 類實現爲半駐留線程池實例,下面就顯示了這一過程:服務器

 

class master_threads_test : public acl::master_threads
{
public:
	master_threads_test() {}

	~master_threads_test() {}

protected:
	// 基類純虛函數:當客戶端鏈接有數據可讀或關閉時回調此函數,返回 true 表示
	// 繼續與客戶端保持長鏈接,不然表示須要關閉客戶端鏈接
	virtual bool thread_on_read(acl::socket_stream* stream)
	{
		// HttpServlet 的子類實例
		http_servlet servlet;
		servlet.setLocalCharset("gb2312");  // 設置本地字符集
		servlet.doRun(「127.0.0.1:11211」, stream);  // 開始處理瀏覽器請求過程,同時設置 memcached 的監聽地址及客戶端鏈接流
	}

	// 基類虛函數:當接收到一個客戶端請求時,調用此函數,容許
	// 子類事先對客戶端鏈接進行處理,返回 true 表示繼續,不然
	// 要求關閉該客戶端鏈接
	virtual bool thread_on_accept(acl::socket_stream*)
	{
		return true;  // 返回 true 以容許服務器框架繼續調用 thread_on_read 過程
	}
};

// 字符串類配置參數項

static char *var_cfg_debug_msg;

static acl::master_str_tbl var_conf_str_tab[] = {
	{ "debug_msg", "test_msg", &var_cfg_debug_msg },

	{ 0, 0, 0 }
};

// 布爾配置參數項
static int  var_cfg_debug_enable;
static int  var_cfg_keep_alive;
static int  var_cfg_loop;

static acl::master_bool_tbl var_conf_bool_tab[] = {
	{ "debug_enable", 1, &var_cfg_debug_enable },
	{ "keep_alive", 1, &var_cfg_keep_alive },
	{ "loop_read", 1, &var_cfg_loop },

	{ 0, 0, 0 }
};

// 整數配置參數項
static int  var_cfg_io_timeout;

static acl::master_int_tbl var_conf_int_tab[] = {
	{ "io_timeout", 120, &var_cfg_io_timeout, 0, 0 },

	{ 0, 0 , 0 , 0, 0 }
};

int main(int argc, char* argv[])
{
	master_threads_test mt;  // 半駐留線程池服務器實例

	// 設置配置參數表
	mt.set_cfg_int(var_conf_int_tab);
	mt.set_cfg_int64(NULL);
	mt.set_cfg_str(var_conf_str_tab);
	mt.set_cfg_bool(var_conf_bool_tab);

	// 開始運行

	if (argc >= 2 && strcmp(argv[1], "alone") == 0)
	{
		// 當在手工調試時通常採用此方式
		printf("listen: 127.0.0.1:8888\r\n");
		mt.run_alone("127.0.0.1:8888", NULL, 2, 10);  // 單獨運行方式
	}
	else  // 生產環境中以半駐留線程池模式運行
		mt.run_daemon(argc, argv);  // acl_master 控制模式運行
	return 0;
}

 

      該例子顯示了一個基於線程池服務器模型的WEB實例,能夠依然使用了文章 《用C++實現相似於JAVA HttpServlet 的編程接口 》示例中的 http_servlet 類,但採用的是由文章 《 開發多線程進程池服務器程序---acl 服務器框架應用 》所介紹的多進程多線程服務器框架模板。多線程

 

     我的微博:http://weibo.com/zsxxsz框架

     參考:socket

     使用 acl::master_proc 類編寫多進程服務器程序memcached

     使用 acl::master_threads 類編寫多進程多線程服務器程序函數

       acl 下載oop

       原文地址 spa

       更多文章

       QQ 羣:242722074

相關文章
相關標籤/搜索