Subversion Repositories php-qbpwcf

Rev

Rev 368 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
368 liveuser 1
<?php
2
 
3
/*
4
 
5
        QBPWCF, Quick Build PHP website Component base on Fedora Linux.
6
    Copyright (C) 2014~2026 MIN ZHI, CHEN
7
 
8
    This file is part of QBPWCF.
9
 
10
    QBPWCF is free software: you can redistribute it and/or modify
11
    it under the terms of the GNU General Public License as published by
12
    the Free Software Foundation, either version 3 of the License, or
13
    (at your option) any later version.
14
 
15
    QBPWCF is distributed in the hope that it will be useful,
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
    GNU General Public License for more details.
19
 
20
    You should have received a copy of the GNU General Public License
21
    along with QBPWCF.  If not, see <http://www.gnu.org/licenses/>.
22
 
23
*/
24
 
25
#使用命名空間qbpwcf
26
namespace qbpwcf;
27
 
28
#assets dir
29
$assetsDir="assets of resource::server_20260604-1";
30
 
31
#server 端的指令
32
$server_cmd=array("php -f server.php");
33
 
34
#clent 端的指令
35
$client_cmd=array("php -f client.php");
36
 
37
#working dir
38
$workingDir=pathinfo(__FILE__)["dirname"]."/../".$assetsDir;
39
 
40
#server端log的開頭識別
41
$serverLogHead="server:";
42
 
43
#client端log的開頭識別
44
$clientLogHead="client:";
45
 
46
#先執行 server 端,再執行 client 端.
47
 
48
#運行server端程式
49
#函式說明:
50
#透過proc來多執行序運作.
51
#回傳結果:
52
#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
53
#$reuslt["error"],執行不正常結束的錯訊息陣列.
54
#$result["function"],當前執行的函式名稱.
55
#$result["argu"],使用的參數.
56
#$result["content"],陣列,每個元素為其指令執行的結果訊息陣列,key為"status"代表執行是否正常的識別;key為"statusCode"代表程式結束後回傳給對應executeBy程式的數值,若為"?"則代表程序尚未結束,若為整數0,則代表順利執行結束,可透過proc_update函式進行資訊的更新與取得;key為"content"代表標準輸出,若為resource,則代表為pipe;key為"error"代表非標準輸出,若為resource,則代表為pipe;key為"input"代表成功輸入的指令;key為"process"代表該程序經proc_open後的process source;key為"proc_get_status"代表程序的資訊.
57
#必填參數:
58
#$conf["cmds"],字串陣列,每個元素代表單一程序要執行的指令與參數.
59
$conf["cmds"]=$server_cmd;
60
#可省略參數:
61
#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
62
$conf["wait"]="false";
63
#$conf["timeout"],字串陣列,每個元素代表單一程序執行的最大等待秒數,超過後將會強迫停止執行,僅當wait參數為"true"時生效.
64
#$conf["timeout"]=array("10");
65
#$conf["workingDir"],字串陣列,個別程式執行時的家目錄,預設不指定.
66
$conf["workingDir"]=array($workingDir);
67
#$conf["envs"],2維字串陣列,每個元素代表個別程式執行時的指定環境變數,key變數名稱;value為變數內容.預設為array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
68
#$conf["envs"]=array(array("key"=>"value"));
69
#$conf["executeBy"],字串陣列,每個元素代表個別指令要用什麼程式執行,預設為"bash".
70
#$conf["executeBy"]=array("bash");
71
#參考資料:
72
#https://www.php.net/manual/en/function.proc-open.php
73
#https://www.php.net/manual/en/function.proc-get-status.php
74
#https://www.php.net/manual/en/function.proc-terminate.php
75
#備註:
76
#當wait參數為"true"時,會自動解析stdout與stderr,因此不用再透過 self::proc_update 來更新.
77
#當wait參數不為"true"時,若需要取得當下的執行狀況,請使用 self::proc_update 來更新.
78
$proc_s=threads::proc($conf);
79
unset($conf);
80
 
81
#如果執行異常
82
if($proc_s["status"]==="false"){
83
 
84
	#debug
85
	var_dump($proc_s);
86
 
87
	#結束執行,回傳shell 1.
88
	exit(1);
89
 
90
	}#if end
91
 
92
#如果程序不是持續運行中
93
if($proc_s["content"][0]["statusCode"]!=="?"){
94
 
95
	#debug
96
	var_dump($proc_s);
97
 
98
	#結束執行,回傳shell 1.
99
	exit(1);
100
 
101
	}#if end
102
 
103
#取得 server.php 的標準輸出
104
$serverStdOut=&$proc_s["content"][0]["content"];
105
 
106
#取得 server.php 的錯誤輸出
107
$serverErrOut=&$proc_s["content"][0]["error"];
108
 
109
#提示 server 運行中且提供 pid
110
echo $serverLogHead."server(pid:".$proc_s["content"][0]["proc_get_status"]["pid"].") is running....".PHP_EOL;
111
 
112
#debug
113
#var_dump(__LINE__,$serverStdOut,$serverErrOut);exit;
114
 
115
#運行client端程式
116
#函式說明:
117
#透過proc來多執行序運作.
118
#回傳結果:
119
#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
120
#$reuslt["error"],執行不正常結束的錯訊息陣列.
121
#$result["function"],當前執行的函式名稱.
122
#$result["argu"],使用的參數.
123
#$result["content"],陣列,每個元素為其指令執行的結果訊息陣列,key為"status"代表執行是否正常的識別;key為"statusCode"代表程式結束後回傳給對應executeBy程式的數值,若為"?"則代表程序尚未結束,若為整數0,則代表順利執行結束,可透過proc_update函式進行資訊的更新與取得;key為"content"代表標準輸出,若為resource,則代表為pipe;key為"error"代表非標準輸出,若為resource,則代表為pipe;key為"input"代表成功輸入的指令;key為"process"代表該程序經proc_open後的process source;key為"proc_get_status"代表程序的資訊.
124
#必填參數:
125
#$conf["cmds"],字串陣列,每個元素代表單一程序要執行的指令與參數.
126
$conf["cmds"]=$client_cmd;
127
#可省略參數:
128
#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
129
$conf["wait"]="false";
130
#$conf["timeout"],字串陣列,每個元素代表單一程序執行的最大等待秒數,超過後將會強迫停止執行,僅當wait參數為"true"時生效.
131
#$conf["timeout"]=array("10");
132
#$conf["workingDir"],字串陣列,個別程式執行時的家目錄,預設不指定.
133
$conf["workingDir"]=array($workingDir);
134
#$conf["envs"],2維字串陣列,每個元素代表個別程式執行時的指定環境變數,key變數名稱;value為變數內容.預設為array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
135
#$conf["envs"]=array(array("key"=>"value"));
136
#$conf["executeBy"],字串陣列,每個元素代表個別指令要用什麼程式執行,預設為"bash".
137
#$conf["executeBy"]=array("bash");
138
#參考資料:
139
#https://www.php.net/manual/en/function.proc-open.php
140
#https://www.php.net/manual/en/function.proc-get-status.php
141
#https://www.php.net/manual/en/function.proc-terminate.php
142
#備註:
143
#當wait參數為"true"時,會自動解析stdout與stderr,因此不用再透過 self::proc_update 來更新.
144
#當wait參數不為"true"時,若需要取得當下的執行狀況,請使用 self::proc_update 來更新.
145
$proc_c=threads::proc($conf);
146
unset($conf);
147
 
148
#如果執行異常
149
if($proc_c["status"]==="false"){
150
 
151
	#debug
152
	var_dump($proc_c);
153
 
154
	#結束執行,回傳shell 1.
155
	exit(1);
156
 
157
	}#if end
158
 
159
#取得 client.php 的標準輸出
160
$clientStdOut=&$proc_c["content"][0]["content"];
161
 
162
#取得 client.php 的錯誤輸出
163
$clientErrOut=&$proc_c["content"][0]["error"];
164
 
165
#提示 client 運行中且提供 pid
166
echo $clientLogHead."client(pid:".$proc_c["content"][0]["proc_get_status"]["pid"].") is running....".PHP_EOL;
167
 
383 liveuser 168
#設置要監控的 stream 陣列資訊
169
$stream_r=array();
170
$stream_r["serverStdOut"]=array();
171
$stream_r["serverStdOut"]["stream"]=$serverStdOut;
172
$stream_r["serverStdOut"]["alive"]=true;
173
$stream_r["serverErrOut"]=array();
174
$stream_r["serverErrOut"]["stream"]=$serverErrOut;
175
$stream_r["serverErrOut"]["alive"]=true;
176
$stream_r["clientStdOut"]=array();
177
$stream_r["clientStdOut"]["stream"]=$clientStdOut;
178
$stream_r["clientStdOut"]["alive"]=true;
179
$stream_r["clientErrOut"]=array();
180
$stream_r["clientErrOut"]["stream"]=$clientErrOut;
181
$stream_r["clientErrOut"]["alive"]=true;
368 liveuser 182
 
383 liveuser 183
#設置預設下個訊息開頭不要換行
184
$eolAtStart=false;
368 liveuser 185
 
186
#無窮迴圈
187
while(true){
188
 
383 liveuser 189
	#針對每個 stream
190
	foreach($stream_r as $name=>$info){
368 liveuser 191
 
383 liveuser 192
		#如果通道是開啟的
193
		if($info["alive"]){
368 liveuser 194
 
383 liveuser 195
			#確認是否尚未關閉
196
			if(!feof($info["stream"])){
368 liveuser 197
 
383 liveuser 198
				#讀取訊息
199
				$msg=fread($info["stream"],2048);
368 liveuser 200
 
383 liveuser 201
				#如果有訊息
202
				if(!empty($msg)){
203
 
204
					#如果開頭要換行
205
					if($eolAtStart){
368 liveuser 206
 
383 liveuser 207
						#輸出換行符號
208
						echo PHP_EOL;
368 liveuser 209
 
383 liveuser 210
						#設置下個訊息開頭不用換行的識別
211
						$eolAtStart=false;
368 liveuser 212
 
383 liveuser 213
						}#if end
214
 
215
					#echo message.
216
					echo $name.":".$msg.PHP_EOL;
217
 
218
					}#if end
219
 
220
				}#if end
221
 
222
			#反之
223
			else{
224
 
225
				#設置通道已經關閉的識別
226
				$stream_r[$name]["alive"]=false;
227
 
228
				#如果開頭要換行
229
				if($eolAtStart){
230
 
231
					#輸出換行符號
232
					echo PHP_EOL;
368 liveuser 233
 
383 liveuser 234
					#設置下個訊息開頭不用換行的識別
235
					$eolAtStart=false;
368 liveuser 236
 
383 liveuser 237
					}#if end
238
 
239
				#提示 server 訊息通道已經關閉 
240
				echo $name.":channel closed".PHP_EOL;
368 liveuser 241
 
383 liveuser 242
				}#else end
368 liveuser 243
 
383 liveuser 244
			}#if end
245
 
246
		#反之
247
		else{
248
 
249
			#移除已經掰掰的通道
250
			unset($stream_r[$name]);
251
 
252
			}#else end
368 liveuser 253
 
383 liveuser 254
		}#foreach end
368 liveuser 255
 
383 liveuser 256
	#如果已經沒有要監控的通道存在
257
	if(empty($stream_r)){
258
 
259
		#跳出 while
260
		break;
261
 
368 liveuser 262
		}#if end
263
 
383 liveuser 264
	#提示沒有訊息
265
	echo ".";
368 liveuser 266
 
383 liveuser 267
	#設置下個訊息開頭要換行
268
	$eolAtStart=true;
368 liveuser 269
 
383 liveuser 270
	#休息1秒鐘
271
	sleep(1);
272
 
273
	}#while end
368 liveuser 274
 
383 liveuser 275
#break point
276
exit;
368 liveuser 277
 
278
?>