1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
|
--------------------------- main.cpp ----------------------------------
#include "stdafx.h"
#include "master_service.h"
int
main(
int
argc,
char
* argv[])
{
// 初始化 acl 庫
acl::acl_cpp_init();
master_service& ms = acl::singleton2<master_service>::get_instance();
// 設置配置參數表
ms.set_cfg_int(var_conf_int_tab);
ms.set_cfg_int64(var_conf_int64_tab);
ms.set_cfg_str(var_conf_str_tab);
ms.set_cfg_bool(var_conf_bool_tab);
// 開始運行
if
(argc >= 2 &&
strcmp
(argv[1],
"alone"
) == 0)
{
const
char
* addr =
":8888"
;
printf
(
"listen on: %s\r\n"
, addr);
ms.run_alone(addr, NULL, 0, 256);
// 單獨運行方式
}
else
ms.run_daemon(argc, argv);
// acl_master 控制模式運行
return
0;
}
--------------------------- master_service.cpp ----------------------------------
#include "stdafx.h"
#include "master_service.h"
////////////////////////////////////////////////////////////////////////////////
// 配置內容項
char
*var_cfg_str;
acl::master_str_tbl var_conf_str_tab[] = {
{
"str"
,
"test_msg"
, &var_cfg_str },
{ 0, 0, 0 }
};
int
var_cfg_bool;
acl::master_bool_tbl var_conf_bool_tab[] = {
{
"bool"
, 1, &var_cfg_bool },
{ 0, 0, 0 }
};
int
var_cfg_buf_size;
acl::master_int_tbl var_conf_int_tab[] = {
{
"buf_size"
, 1024, &var_cfg_buf_size, 0, 0 },
{ 0, 0 , 0 , 0, 0 }
};
long
long
int
var_cfg_int64;
acl::master_int64_tbl var_conf_int64_tab[] = {
{
"int64"
, 120, &var_cfg_int64, 0, 0 },
{ 0, 0 , 0 , 0, 0 }
};
////////////////////////////////////////////////////////////////////////////////
master_service::master_service()
: res_buf_(NULL)
{
}
master_service::~master_service()
{
if
(res_buf_)
acl_myfree(res_buf_);
}
bool
master_service::thread_on_read(acl::socket_stream* stream)
{
logger(
"thread id: %lu"
, acl_pthread_self());
acl::http_response res(stream);
// 響應數據體爲 xml 格式
res.response_header().set_content_type(
"text/html"
);
// 讀 HTTP 請求頭
if
(res.read_header() ==
false
)
return
false
;
acl::string buf;
// 讀 HTTP 請求體數據
if
(res.get_body(buf) ==
false
)
return
false
;
acl::http_client* client = res.get_client();
// 判斷客戶端是否但願保持長鏈接
bool
keep_alive = client->keep_alive();
// 返回數據給客戶端
res.response_header()
.set_status(200)
.set_keep_alive(keep_alive)
.set_content_length(var_cfg_buf_size);
if
(res.response(res_buf_, var_cfg_buf_size) ==
false
)
return
false
;
return
keep_alive ?
true
:
false
;
}
bool
master_service::thread_on_accept(acl::socket_stream* conn)
{
if
(0)
acl_tcp_so_linger(conn->sock_handle(), 1, 0);
logger(
"thread id: %lu"
, acl_pthread_self());
return
true
;
}
bool
master_service::thread_on_timeout(acl::socket_stream*)
{
return
false
;
}
void
master_service::thread_on_close(acl::socket_stream*)
{
logger(
"thread id: %lu"
, acl_pthread_self());
}
void
master_service::thread_on_init()
{
}
void
master_service::thread_on_exit()
{
}
void
master_service::proc_on_init()
{
logger(
"thread id: %lu"
, acl_pthread_self());
if
(var_cfg_buf_size <= 0)
var_cfg_buf_size = 1024;
res_buf_ = (
char
*) acl_mymalloc(var_cfg_buf_size + 1);
int
i;
for
(i = 0; i < var_cfg_buf_size; i++)
res_buf_[i] =
'X'
;
res_buf_[i] = 0;
}
void
master_service::proc_on_exit()
{
}
------------------------------- master_service.h -------------------------------
#pragma once
#include "acl_cpp/master/master_threads.hpp"
#include "acl_cpp/master/master_conf.hpp"
////////////////////////////////////////////////////////////////////////////////
// 配置內容項
extern
char
*var_cfg_str;
extern
acl::master_str_tbl var_conf_str_tab[];
extern
int
var_cfg_bool;
extern
acl::master_bool_tbl var_conf_bool_tab[];
extern
int
var_cfg_buf_size;
extern
acl::master_int_tbl var_conf_int_tab[];
extern
long
long
int
var_cfg_int64;
extern
acl::master_int64_tbl var_conf_int64_tab[];
////////////////////////////////////////////////////////////////////////////////
//class acl::socket_stream;
class
master_service :
public
acl::master_threads
{
public
:
master_service();
~master_service();
protected
:
/**
* 純虛函數:當某個客戶端鏈接有數據可讀或關閉或出錯時調用此函數
* @param stream {socket_stream*}
* @return {bool} 返回 false 則表示當函數返回後須要關閉鏈接,
* 不然表示須要保持長鏈接,若是該流出錯,則應用應該返回 false
*/
virtual
bool
thread_on_read(acl::socket_stream* stream);
/**
* 當線程池中的某個線程得到一個鏈接時的回調函數,
* 子類能夠作一些初始化工做
* @param stream {socket_stream*}
* @return {bool} 若是返回 false 則表示子類要求關閉鏈接,而不
* 必將該鏈接再傳遞至 thread_main 過程
*/
virtual
bool
thread_on_accept(acl::socket_stream* stream);
/**
* 當某個網絡鏈接的 IO 讀寫超時時的回調函數,若是該函數返回 true 則表示繼續等待下一次
* 讀寫,不然則但願關閉該鏈接
* @param stream {socket_stream*}
* @return {bool} 若是返回 false 則表示子類要求關閉鏈接,而不
* 必將該鏈接再傳遞至 thread_main 過程
*/
virtual
bool
thread_on_timeout(acl::socket_stream* stream);
/**
* 當與某個線程綁定的鏈接關閉時的回調函數
* @param stream {socket_stream*}
*/
virtual
void
thread_on_close(acl::socket_stream* stream);
/**
* 當線程池中一個新線程被建立時的回調函數
*/
virtual
void
thread_on_init();
/**
* 當線程池中一個線程退出時的回調函數
*/
virtual
void
thread_on_exit();
/**
* 當進程切換用戶身份後調用的回調函數,此函數被調用時,進程
* 的權限爲普通受限級別
*/
virtual
void
proc_on_init();
/**
* 當進程退出前調用的回調函數
*/
virtual
void
proc_on_exit();
private
:
char
* res_buf_;
};
----------------------------- stdafx.h ---------------------------------------
// stdafx.h : 標準系統包含文件的包含文件,
// 或是經常使用但不常更改的項目特定的包含文件
//
#pragma once
//#include <iostream>
//#include <tchar.h>
// TODO: 在此處引用程序要求的附加頭文件
#include "lib_acl.h"
#include "acl_cpp/lib_acl.hpp"
|