Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 liveuser 1
#!/usr/bin/php
2
<?php
3
 
4
#使用命名空間qbpwcf
5
namespace qbpwcf;
6
 
7
#匯入外部套件
8
include("/usr/lib/qbpwcf/allInOne.php");
9
 
10
#函式說明:
11
#建立php原生的socket tcp/ip server,進而實作webSocket
12
#回傳結果:
13
#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
14
#$result["error"],錯誤訊息陣列.
15
#$resutl["function"],當前執行的涵式名稱.
16
#$result["argu"],所使用的參數.
17
#必填參數:
18
#$conf["fileArgu"],字串,變數__FILE__的內容.
19
$conf["fileArgu"]=__FILE__;
20
#可省略參數:
21
#$conf["listenIp"],字串,要接聽的主機ip,預設為本機的ip.
22
#$conf["listenIp"]="169.254.1.1";
23
#$conf["listenPort"],字串,要接聽的port,預設為已使用port+1.
24
$conf["listenPort"]="8088";
25
#$conf["httpMode"],字串,是否要用http模式,預設為"false",不使用,若為"true"則要使用.
26
$conf["httpMode"]="true";
27
#$conf["processFuncs"],陣列,針對收到的訊息要呼叫的函式,會帶入一個參數陣列,array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
28
$conf["processFuncs"]=array("\qbpwcf\connect2devcom","\qbpwcf\help","\qbpwcf\getBuf","\qbpwcf\cmd2gw","\qbpwcf\getOnlineUsers","\qbpwcf\ping","\qbpwcf\checkSession");
29
#參考資料:
30
#http://php.net/manual/en/sockets.examples.php
31
#http://us3.php.net/manual/en/function.socket-select.php
32
#response should at least end with "\r"=>http://stackoverflow.com/questions/25739768/websocket-communication-between-chromeclient-and-hotspotserver-status-line
33
#response status code should be 101=>http://stackoverflow.com/questions/29829597/i-get-a-status-200-when-connecting-to-the-websocket-but-it-is-an-error
34
#webSocket實做=>http://srchea.com/build-a-real-time-application-using-html5-websockets
35
#webSocketServer實做=>http://www.cuelogic.com/blog/php-and-html5-websocket-server-and-client-communication/
36
#備註:
37
#僅能在命令列執行
38
$nativeSocketTcpIpServer=\qbpwcf\webSock::nativeSocketTcpIpServer($conf);
39
unset($conf);
40
 
41
#如果執行失敗
42
if($nativeSocketTcpIpServer["status"]==="false"){
43
 
44
	#印出結果
45
	var_dump($nativeSocketTcpIpServer);
46
 
47
	#結束執行
48
	exit;
49
 
50
	}#if end
51
 
52
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
53
#(重新)連線到 devcom
54
function connect2devcom(&$params){
55
 
56
	#如果是要建立跟 devcom 的連線
57
 
58
	#如果資料長度大於 "connect to devcom with:"
59
	if( strlen($params["data"]) > strlen("connect to devcom with:") ){
60
 
61
		#判斷開頭是否為 "connect to devcom with:"
62
		#涵式說明:
63
		#取得符合特定字首與字尾的字串
64
		#回傳的結果:
65
		#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
66
		#$result["function"],當前執行的函數名稱.
67
		#$result["error"],錯誤訊息陣列.
68
		#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
69
		#$result["returnString"],爲符合字首條件的字串內容。
70
		#$result["argu"],使用的參數.
71
		#必填參數:
72
		#$conf["checkString"],字串,要檢查的字串.
73
		$conf["checkString"]=$params["data"];
74
		#可省略參數:
75
		#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
76
		$conf["frontWord"]="connect to devcom with:";
77
		#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
78
		#$conf["tailWord"]="";
79
		#參考資料:
80
		#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
81
		$getMeetConditionsString=search::getMeetConditionsString($conf);
82
		unset($conf);
83
 
84
		#如果尋找出錯
85
		if($getMeetConditionsString["status"]==="false"){
86
 
87
			#印出結果
88
			var_dump($getMeetConditionsString);
89
 
90
			#結束執行
91
			exit;
92
 
93
			}#if end
94
 
95
		#如果沒找到
96
		if($getMeetConditionsString["founded"]==="false"){
97
 
98
			#讓程式繼續跑
99
			return false;
100
 
101
			}#if end
102
 
103
		#函式說明:
104
		#將字串特定關鍵字與其前面的內容剔除
105
		#回傳結果:
106
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
107
		#$result["error"],錯誤訊息陣列.
108
		#$result["warning"],警告訊息鎮列.
109
		#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
110
		#$result["function"],當前執行的函數名稱.
111
		#$result["oriStr"],要處理的原始字串內容.
112
		#$result["content"],處理好的的字串內容.	
113
		#必填的參數:
114
		#$conf["stringIn"],字串,要處理的字串.
115
		$conf["stringIn"]=$params["data"];
116
		#$conf["keyWord"],字串,特定字串.
117
		$conf["keyWord"]="connect to devcom with:";
118
		$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf);
119
		unset($conf);
120
 
121
		#如果處理出錯
122
		if($delStrBeforeKeyWord["status"]==="false"){
123
 
124
			#印出結果
125
			var_dump($delStrBeforeKeyWord);
126
 
127
			#結束執行
128
			exit;
129
 
130
			}#if end
131
 
132
		#如果關鍵字不存在
133
		if($delStrBeforeKeyWord["founded"]==="false"){
134
 
135
			#印出結果
136
			#var_dump($delStrBeforeKeyWord);
137
 
138
			#讓程式繼續執行
139
			return false;
140
 
141
			}#if end
142
 
143
		#取得使用的賬號與密碼
144
		$emailAndPass=$delStrBeforeKeyWord["content"];
145
 
146
		#分割信箱與密碼
147
		#涵式說明:
148
		#將固定格式的字串分開,並回傳分開的結果。
149
		#回傳結果:
150
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
151
		#$result["error"],錯誤訊息陣列
152
		#$result["function"],當前執行的函數名稱.
153
		#$result["argu"],使用的參數.
154
		#$result["oriStr"],要分割的原始字串內容
155
		#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
156
		#$result["dataCounts"],爲總共分成幾段
157
		#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
158
		#必填的參數:
159
		#$conf["stringIn"],字串,要處理的字串.
160
		$conf["stringIn"]=$emailAndPass;
161
		#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
162
		$conf["spiltSymbol"]=";";
163
		#可省略參數:
164
		#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
165
		$conf["allowEmptyStr"]="false";
166
		$spiltString=stringProcess::spiltString($conf);
167
		unset($conf);
168
 
169
		#如果分割失敗
170
		if($spiltString["status"]==="false"){
171
 
172
			#印出結果
173
			var_dump($spiltString);
174
 
175
			#結束執行
176
			exit;
177
 
178
			}#if end
179
 
180
		#如果分割失敗
181
		if($spiltString["found"]==="false"){
182
 
183
			#印出結果
184
			var_dump($spiltString);
185
 
186
			#讓程式繼續執行	
187
			return false;
188
 
189
			}#if end
190
 
191
		#如果沒有分成兩段
192
		if($spiltString["dataCounts"]!==2){
193
 
194
			#印出結果
195
			var_dump($spiltString);
196
 
197
			#讓程式繼續執行	
198
			return false;
199
 
200
			}#if end
201
 
202
		#email
203
		$email=$spiltString["dataArray"][0];
204
 
205
		#password
206
		$password=$spiltString["dataArray"][1];
207
 
208
		#取得server的ip
209
		#涵式說明:
210
		#依據提供查詢IP服務的網站取得伺服器對外的IP.
211
		#回傳的結果:
212
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
213
		#$result["function"],當前執行的函數名稱.
214
		#$result["error"],錯誤訊息陣列.
215
		#$result["content"],伺服端對外的IP.
216
		#必填參數:
217
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
218
		$conf["fileArgu"]=__FILE__;
219
		#備註:
220
		#需要有網站支援此服務.
221
		$getServerRealIP=csInformation::getServerRealIP($conf);
222
		unset($conf["conf"]);
223
 
224
		#如果執行錯誤
225
		if($getServerRealIP["status"]==="false")
226
		{
227
			#印出結果
228
			var_dump($getServerRealIP);
229
 
230
		}#if end
231
 
232
		#如果有取得對外IP
233
		if(isset($getServerRealIP["content"]))
234
		{
235
			#get server ip
236
			$serverIP=$getServerRealIP["content"];
237
		}
238
 
239
		#default is devel ip
240
		$serverIP="169.254.1.3";
241
 
242
		#判斷server的IP
243
		switch($serverIP)
244
		{
245
			#52.77.106.22 - real remote
246
			#172.31.28.13 - real local
247
			case "52.77.106.22":
248
			case "172.31.28.13":
249
 
250
				#real site url
251
				$cms_host="https://aesopower-cms.qbpwcf.org";
252
 
253
				#跳出迴圈
254
				break;
255
 
256
			#18.139.160.209 - test remote
257
			#172.31.23.224 - test local
258
			case "18.139.160.209":
259
			case "172.31.23.224":
260
 
261
				#test site url
262
				$cms_host="https://aesopower-cms-test.qbpwcf.org";
263
 
264
				#跳出迴圈
265
				break;
266
 
267
			#其他狀況為 devel site
268
			default:
269
 
270
				#devel site url
271
				$cms_host="https://aesopower-cms-sock-podman.qbpwcf.org";
272
 
273
 
274
		}#switch end
275
 
276
		#設置網址
277
		$cms_host=$cms_host."/verifyacct";
278
 
279
		#驗證賬號密碼是否正確
280
		#url=>cms_host/verifyacct
281
		#函式說明:
282
		#運行curl cmd
283
		#回傳結果:
284
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
285
		#$result["error"],錯誤訊息陣列.
286
		#$result["function"],當前執行的函式名稱.
287
		#$result["content"],取得的回應內容.
288
		#$result["cookie"],cookie檔案的位置與名稱.
289
		#$result["cmd"],執行的command.
290
		#$result["argu],使用的參數.
291
		#必填參數:
292
		#$conf["url"],字串,目標url.
293
		$conf["url"]=$cms_host;
294
		#$conf["fileArgu"],字串,變數__FILE__的內容.
295
		$conf["fileArgu"]=__FILE__;
296
		#可省略參數:
297
		#$conf["header"],字串陣列,要傳送的header.
298
		#$conf["header"]=array();
299
		#$conf["allowAnySSLcertificate"],字串,是否允許不可信任的SSL憑證,預設為"true".
300
		#$conf["allowAnySSLcertificate"]="";
301
		#$conf["postVar"],字串陣列,每個要傳送的post變數名稱(陣列的key值)與數值.
302
		$conf["postVar"]=array();
303
		$conf["postVar"]["identity"]=$email;
304
		$conf["postVar"]["password"]=$password;
305
		#$conf["rawPost"]="字串",要傳送的raw post內容.
306
		#$conf["rawPost"]="";
307
		#$conf["urlEncode"],字串,post的內容是否要url_encode,"true"代表要,預設為"false"代表不要.
308
		#$conf["urlEncode"]="false";
309
		#$conf["agent"],字串,user agent的名稱.
310
		#$conf["agent"]="";
311
		#$conf["cookie"],字串,cookie位置與檔案位置.
312
		#$conf["cookie"]="";
313
		#$conf["forceNewCookie"],字串,是否要重置cookie,"true"代表要,"false"代表不要,預設為"false".
314
		#$conf["forceNewCookie"]="";
315
		$curlCmd=catchWebContent::curlCmd($conf);
316
		unset($conf);
317
 
318
		#如果運行失敗
319
		if($curlCmd["status"]==="false")
320
		{
321
 
322
			#印出結果
323
			var_dump($curlCmd);
324
 
325
			#讓程式繼續執行
326
			return false;
327
 
328
		}#if end
329
 
330
		#取得回應
331
		$res=$curlCmd["content"];
332
 
333
		#decode回應
334
		$res=json_decode($res[0]);
335
 
336
		#如果驗證不通過
337
		if($res->status==="false"){
338
 
339
			#印出結果
340
			var_dump("驗證不通過");
341
 
342
			#初始化訊息
343
			$data="auth failed";
344
 
345
			var_dump($data);
346
 
347
			#json encode
348
			$data=json_encode($data);
349
 
350
			#函式說明:
351
			#加密 handshake 後要傳送的訊息 
352
			#必填參數:
353
			#$conf["text"],字串,要加密的訊息.
354
			$conf["text"]=$data; 
355
			$data=\qbpwcf\webSock::encode($conf);
356
			unset($conf);
357
 
358
			#告訴用戶
359
			socket_write($params["clientSock"],$data,strlen($data));
360
 
361
			#讓程式繼續跑
362
			return false;
363
 
364
			}#if end
365
 
366
		$conf=array();
367
		$conf["ip"]="127.0.0.1";
368
		$conf["port"]="7053";
369
		$conf["dbFile"]="/var/log/".$email.".db";
370
		$conf["timeout"]="480";
371
		$conf["email"]=$email;
372
		#參考資料
373
		#https://stackoverflow.com/questions/7415091/php-exec-hangs-doesnt-continue-to-next-line => prevernt hang
374
		$cmd="keepAliveTcp.php -ip ".$conf["ip"]." -port ".$conf["port"]." -dbFile ".$conf["dbFile"]." -timeout ".$conf["timeout"]." -email ".$conf["email"]." > /dev/null 2>&1 &";
375
		$output=array();
376
		$status=0;
377
		exec($cmd,$output,$status);
378
 
379
		#如果執行失敗
380
		if($status!==0){
381
 
382
			#印出結果
383
			var_dump("運行 ".$cmd." 指令失敗");
384
 
385
			#結束執行
386
			exit;
387
 
388
			}#if end
389
 
390
		#反之執行成功
391
		else{
392
 
393
			#設置對應的 devcomDbFile
394
			$params["clientInfo"]["devcomDbFile"]=$conf["dbFile"];
395
 
396
			#取得要傳送的資料
397
			$data=json_encode("Created db file:".$conf["dbFile"]); 
398
 
399
			#當內容長度大於 124
400
			if(strlen($data)>124){
401
 
402
				#取得部分資料
403
				$dp=substr($data,0,124)."&";
404
 
405
				#函式說明:
406
				#加密 handshake 後要傳送的訊息 
407
				#必填參數:
408
				#$conf["text"],字串,要加密的訊息.
409
				$conf["text"]=$dp; 
410
				$dp=\qbpwcf\webSock::encode($conf);
411
				unset($conf);
412
 
413
				#告訴用戶
414
				socket_write($params["clientSock"],$dp,strlen($dp));
415
 
416
				#取得剩餘的部分
417
				$data=substr($data,124);
418
 
419
				#設置剩餘的部分
420
				$params["clientInfo"]["buf"]=$data;
421
 
422
				#讓程式繼續執行
423
				return false;
424
 
425
				}#if end
426
 
427
			#函式說明:
428
			#加密 handshake 後要傳送的訊息 
429
			#必填參數:
430
			#$conf["text"],字串,要加密的訊息.
431
			$conf["text"]=$data; 
432
			$data=\qbpwcf\webSock::encode($conf);
433
			unset($conf);
434
 
435
			#告訴用戶
436
			socket_write($params["clientSock"],$data,strlen($data));
437
 
438
			}#else end
439
 
440
		}#if end
441
 
442
	#讓程式繼續執行
443
	return false;
444
 
445
	}#connect2devcom end
446
 
447
#提示用法
448
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
449
function help(&$params){
450
 
451
	#如果是要 查看用法 
452
 
453
	#如果資料為 "help"
454
	if( $params["data"]==="help" ){
455
 
456
		#說明
457
		$data=array();
458
		$data[]="help,本說明";
459
		$data[]="id?,查尋自己的id";
460
		$data[]="ids?,查尋在線的人除了自己有哪些";
461
		$data[]="talkTo?,目前在跟哪些人對話";
462
		$data[]="talkTo:[id],準備跟特定的人講話";
463
		$data[]="connect to devcom with:[email],用email/賬戶跟Devcom進行連線";
464
		$data[]="cmd2gw:[gwId]:[cmd],下達指令cmd給id為gwId的gw";
465
		$data[]="getOnlineUsers,取得在線使用者人數";
466
		$data=json_encode($data);
467
 
468
		#當內容長度大於 124
469
		if(strlen($data)>124){
470
 
471
			#取得部分資料
472
			$dp=substr($data,0,124)."&";
473
 
474
			#函式說明:
475
			#加密 handshake 後要傳送的訊息 
476
			#必填參數:
477
			#$conf["text"],字串,要加密的訊息.
478
			$conf["text"]=$dp; 
479
			$dp=\qbpwcf\webSock::encode($conf);
480
			unset($conf);
481
 
482
			#告訴用戶
483
			socket_write($params["clientSock"],$dp,strlen($dp));
484
 
485
			#取得剩餘的部分
486
			$data=substr($data,124);
487
 
488
			#設置對應的 devcomDbFile
489
			$params["clientInfo"]["buf"]=$data;
490
 
491
			#讓程式繼續執行
492
			return false;
493
 
494
			}#if end
495
 
496
		#函式說明:
497
		#加密 handshake 後要傳送的訊息 
498
		#必填參數:
499
		#$conf["text"],字串,要加密的訊息.
500
		$conf["text"]=$data; 
501
		$data=\qbpwcf\webSock::encode($conf);
502
		unset($conf);
503
 
504
		#告訴用戶
505
		socket_write($params["clientSock"],$data,strlen($data));
506
 
507
		}#if end
508
 
509
	#讓程式繼續執行
510
	return false;
511
 
512
	}#help end	
513
 
514
#取得 Buf 內容
515
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
516
function getBuf(&$params){
517
 
518
	#如果輸入的內容為 "get continue buf"
519
	if($params["data"]==="get continue buf"){
520
 
521
		#取得buf內容
522
		$data=$params["clientInfo"]["buf"];
523
 
524
		#當內容長度大於 124
525
		if(strlen($data)>124){
526
 
527
			#取得部分資料
528
			$dp=substr($data,0,124)."&";
529
 
530
			#函式說明:
531
			#加密 handshake 後要傳送的訊息 
532
			#必填參數:
533
			#$conf["text"],字串,要加密的訊息.
534
			$conf["text"]=$dp; 
535
			$dp=\qbpwcf\webSock::encode($conf);
536
			unset($conf);
537
 
538
			#告訴用戶
539
			socket_write($params["clientSock"],$dp,strlen($dp));
540
 
541
			#取得剩餘的部分
542
			$data=substr($data,124);
543
 
544
			#記錄剩下的 buf
545
			$params["clientInfo"]["buf"]=$data;
546
 
547
			#讓程式繼續執行
548
			return false;
549
 
550
			}#if end
551
 
552
		#函式說明:
553
		#加密 handshake 後要傳送的訊息 
554
		#必填參數:
555
		#$conf["text"],字串,要加密的訊息.
556
		$conf["text"]=$data; 
557
		$data=\qbpwcf\webSock::encode($conf);
558
		unset($conf);
559
 
560
		#告訴用戶
561
		socket_write($params["clientSock"],$data,strlen($data));
562
 
563
		#清空buf
564
		$params["clientInfo"]["buf"]='';
565
 
566
		#讓程式繼續執行
567
		return false;
568
 
569
		}#if end
570
 
571
	#讓程式繼續執行
572
	return false;
573
 
574
	}#function getBuf end
575
 
576
/*
577
#下達指令到gw
578
#預設參數:
579
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
580
#格式:
581
#cmd2gw:gwId:cmd
582
#ex:"cmd2gw:34:ID01=?"
583
*/
584
function cmd2gw(&$params)
585
{
586
	#如果資料長度大於 "cmd2gw:"
587
	if( strlen($params["data"]) > strlen("cmd2gw:") )
588
	{
589
		#判斷開頭是否為 "cmd2gw:"
590
		#涵式說明:
591
		#取得符合特定字首與字尾的字串
592
		#回傳的結果:
593
		#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
594
		#$result["function"],當前執行的函數名稱.
595
		#$result["error"],錯誤訊息陣列.
596
		#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
597
		#$result["returnString"],爲符合字首條件的字串內容。
598
		#$result["argu"],使用的參數.
599
		#必填參數:
600
		#$conf["checkString"],字串,要檢查的字串.
601
		$conf["checkString"]=$params["data"];
602
		#可省略參數:
603
		#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
604
		$conf["frontWord"]="cmd2gw:";
605
		#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
606
		#$conf["tailWord"]="";
607
		#參考資料:
608
		#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
609
		$getMeetConditionsString=search::getMeetConditionsString($conf);
610
		unset($conf);
611
 
612
		#如果尋找出錯
613
		if($getMeetConditionsString["status"]==="false")
614
		{
615
 
616
			#印出結果
617
			var_dump($getMeetConditionsString);
618
 
619
			#結束執行
620
			exit;
621
 
622
		}#if end
623
 
624
		#如果沒找到
625
		if($getMeetConditionsString["founded"]==="false")
626
		{
627
 
628
			#讓程式繼續跑
629
			return false;
630
 
631
		}#if end
632
 
633
		#判斷是否有認證過了
634
		if(!isset($params["clientInfo"]["devcomDbFile"]))
635
		{
636
			#初始化訊息
637
			$data="no permission";
638
 
639
			var_dump($data);
640
 
641
			#json encode
642
			$data=json_encode($data);
643
 
644
			#函式說明:
645
			#加密 handshake 後要傳送的訊息 
646
			#必填參數:
647
			#$conf["text"],字串,要加密的訊息.
648
			$conf["text"]=$data; 
649
			$data=\qbpwcf\webSock::encode($conf);
650
			unset($conf);
651
 
652
			#告訴用戶
653
			socket_write($params["clientSock"],$data,strlen($data));
654
 
655
			#讓程式繼續跑
656
			return false;
657
		}
658
 
659
		#判斷認證是否過期了,認證檔案是否存在.
660
		#涵式說明:
661
		#檢查多個檔案與資料夾是否存在.
662
		#回傳的結果:
663
		#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
664
		#$result["error"],錯誤訊息陣列.
665
		#$resutl["function"],當前執行的涵式名稱.
666
		#$result["argu"],使用的參數.
667
		#$result["allExist"],所有檔案皆存在的識別,"true"代表皆存在,"false"代表沒有全部都存在.
668
		#$result["varName"][$i],爲第$i個資料夾或檔案的路徑與名稱。
669
		#$result["varNameFullPath"][$i],爲第$i個資料夾或檔案的完整檔案系統路徑與名稱,如果不存在則代表路徑是網址.
670
		#$result["varNameWebPath"][$i],為第$i個資料夾或檔案的網址
671
		#$result["varExist"][$i],爲第$i個資料夾或檔案是否存在,"true"代表存在,"false"代表不存在。
672
		#必填參數:
673
		#$conf["fileArray"],陣列字串,要檢查是否存在的檔案有哪些,須爲一維陣列數值。
674
		$conf["fileArray"]=array($params["clientInfo"]["devcomDbFile"]);
675
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
676
		$conf["fileArgu"]=__FILE__;
677
		#可省略參數
678
		#$conf["disableWebSearch"],"字串",是否取消「當檔案找不到時,改用catchWebContent類別的wget函數來檢查檔案是否存在於網路上」的功能,"false"不取消,若要取消該功能請設為"true",若抓到的內容為空字串則會視為檔案不存在,預設為"true".
679
		#$conf["disableWebSearch"]="false";
680
		#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".
681
		#$conf["userDir"]="true";
682
		#參考資料來源:
683
		#http://php.net/manual/en/function.file-exists.php
684
		#http://php.net/manual/en/control-structures.foreach.php
685
		#備註:
686
		#函數file_exists檢查的路徑為檔案系統的路徑
687
		$checkMultiFileExist=fileAccess::checkMultiFileExist($conf);
688
		unset($conf);
689
 
690
		#如果出錯
691
		if($checkMultiFileExist["status"]==="false")
692
		{
693
 
694
			#印出結果
695
			var_dump($checkMultiFileExist);
696
 
697
			#結束執行
698
			exit;
699
 
700
		}#if end
701
 
702
		#如果db檔案不存在
703
		if($checkMultiFileExist["allExist"]=="false")
704
		{
705
			#初始化訊息
706
			$data="expired";
707
 
708
			var_dump($data);
709
 
710
			#json encode
711
			$data=json_encode($data);
712
 
713
			#函式說明:
714
			#加密 handshake 後要傳送的訊息 
715
			#必填參數:
716
			#$conf["text"],字串,要加密的訊息.
717
			$conf["text"]=$data; 
718
			$data=\qbpwcf\webSock::encode($conf);
719
			unset($conf);
720
 
721
			#告訴用戶
722
			socket_write($params["clientSock"],$data,strlen($data));
723
 
724
			#讓程式繼續跑
725
			return false;
726
 
727
			#讓程式繼續執行
728
			return;
729
 
730
		}#if end
731
 
732
		#函式說明:
733
		#將字串特定關鍵字與其前面的內容剔除
734
		#回傳結果:
735
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
736
		#$result["error"],錯誤訊息陣列.
737
		#$result["warning"],警告訊息鎮列.
738
		#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
739
		#$result["function"],當前執行的函數名稱.
740
		#$result["oriStr"],要處理的原始字串內容.
741
		#$result["content"],處理好的的字串內容.	
742
		#必填的參數:
743
		#$conf["stringIn"],字串,要處理的字串.
744
		$conf["stringIn"]=$params["data"];
745
		#$conf["keyWord"],字串,特定字串.
746
		$conf["keyWord"]="cmd2gw:";
747
		$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf);
748
		unset($conf);
749
 
750
		#如果處理出錯
751
		if($delStrBeforeKeyWord["status"]==="false")
752
		{
753
 
754
			#印出結果
755
			var_dump($delStrBeforeKeyWord);
756
 
757
			#結束執行
758
			exit;
759
 
760
		}#if end
761
 
762
		#如果關鍵字不存在
763
		if($delStrBeforeKeyWord["founded"]==="false")
764
		{
765
 
766
			#印出結果
767
			#var_dump($delStrBeforeKeyWord);
768
 
769
			#讓程式幾執行
770
			return false;
771
 
772
		}#if end
773
 
774
		#取得gwId與要執行的指令字串
775
		$idCmdStr=$delStrBeforeKeyWord["content"];
776
 
777
		#透過 $params["clientInfo"]["devcomDbFile"] 檔案來得知下指令的賬號 
778
 
779
		#透過 window.lms_menu.sel_id 來得之要對哪個 gw 下達指令
780
 
781
		#分割gwId與要執行的指令字串字串
782
		#涵式說明:
783
		#將固定格式的字串分開,並回傳分開的結果。
784
		#回傳結果:
785
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
786
		#$result["error"],錯誤訊息陣列
787
		#$result["function"],當前執行的函數名稱.
788
		#$result["argu"],使用的參數.
789
		#$result["oriStr"],要分割的原始字串內容
790
		#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
791
		#$result["dataCounts"],爲總共分成幾段
792
		#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
793
		#必填的參數:
794
		#$conf["stringIn"],字串,要處理的字串.
795
		$conf["stringIn"]=$idCmdStr;
796
		#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
797
		$conf["spiltSymbol"]=";";
798
		#可省略參數:
799
		#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
800
		$conf["allowEmptyStr"]="false";
801
		$spiltString=stringProcess::spiltString($conf);
802
		unset($conf);
803
 
804
		#如果分割失敗
805
		if($spiltString["status"]==="false"){
806
 
807
			#印出結果
808
			var_dump($spiltString);
809
 
810
			#結束執行
811
			exit;
812
 
813
			}#if end
814
 
815
		#如果分割失敗
816
		if($spiltString["found"]==="false"){
817
 
818
			#印出結果
819
			var_dump($spiltString);
820
 
821
			#讓程式繼續執行	
822
			return false;
823
 
824
			}#if end
825
 
826
		#如果沒有分成兩段
827
		if($spiltString["dataCounts"]!==2){
828
 
829
			#印出結果
830
			var_dump($spiltString);
831
 
832
			#讓程式繼續執行	
833
			return false;
834
 
835
			}#if end
836
 
837
		#gwId
838
		$gwId=$spiltString["dataArray"][0];
839
 
840
		#cmd
841
		$cmd=$spiltString["dataArray"][1];
842
 
843
		#取得資料庫設定檔案內容
844
		#涵式說明:
845
		#解析PHP檔案裡面的變數.
846
		#回傳結果:
847
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
848
		#$result["error"],錯誤訊息.
849
		#$result["function"],當前執行的函數名稱.
850
		#$result["argu"],所使用的參數.
851
		#$result["content"],找到的變數內容陣列.
852
		#$result["content"]["value"],依找到變數順序的數值.
853
		#$result["content"]["struc"],依找到變數順序的階層結構.
854
		#$result["content"]["direct],變數名稱對應的數值內容.
855
		#必填參數:
856
		#$conf["file"],字串,檔案的路徑與名稱.
857
		$conf["file"]="/var/www/html/latest/application/config/database.php";
858
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
859
		$conf["fileArgu"]=__FILE__;
860
		#$conf["varName"],字串陣列,要搜尋的變數名稱,例如要搜尋變數$email則輸入"email".
861
		$conf["varName"]=array("db['default']['hostname']","db['default']['port']","db['default']['username']","db['default']['password']","db['default']['database']");
862
		#參考資料:
863
		#https://www.php.net/manual/en/function.parse-str.php
864
		$parseVaraiableInPHPfile=fileAccess::parseVaraiableInPHPfile($conf);
865
		unset($conf);
866
 
867
		#如果解析出錯
868
		if($parseVaraiableInPHPfile["status"]==="false")
869
		{
870
			#印出結果
871
			var_dump($parseVaraiableInPHPfile);
872
 
873
			#讓程式繼續執行
874
			return false;
875
 
876
		}#if end
877
 
878
		#取得 db host
879
		$dbHost=$parseVaraiableInPHPfile["content"]["direct"]["db['default']['hostname']"];
880
 
881
		#取得 db port
882
		$dbPort=$parseVaraiableInPHPfile["content"]["direct"]["db['default']['port']"];
883
 
884
		#取得 db user name
885
		$dbUser=$parseVaraiableInPHPfile["content"]["direct"]["db['default']['username']"];
886
 
887
		#取得 db password
888
		$dbPassword=$parseVaraiableInPHPfile["content"]["direct"]["db['default']['password']"];
889
 
890
		#取得 db name
891
		$dbName=$parseVaraiableInPHPfile["content"]["direct"]["db['default']['database']"];
892
 
893
		#用 gwId 來查尋 gsn,lanmac,imi
894
		#涵式說明:
895
		#一次取得資料庫、表的資料
896
		#回傳的結果
897
		#$result["status"],執行結果"true"為成功;"false"為執行失敗。
898
		#$result["error"],錯誤訊息陣列。
899
		#$result["function"],當前執行的漢書名稱.
900
		#$result["argu"],使用的參數.
901
		#$result["dataColumnName"],抓取的資料欄位名稱陣列.
902
			#$result["dataColumnName"][$i]代表第$i+1個欄位名稱
903
		#$result["dataContent"],爲資料的內容。
904
		#$result["dataContent"][$conf["WhereColumnName"][$i]][$dataSetNum]
905
			#$dataSetNum 爲第$dataSetNum+1筆資料
906
			#$conf["WhereColumnName"][$i] 爲第 $i+1 個欄位的名稱
907
		#$result["dataCount"],爲取得的資料筆數。
908
		#$result["sql"],執行的sql字串.
909
		#必填的參數:
910
		$conf["dbAddress"]=$dbHost;#爲dbServer的位置。
911
		$conf["dbAccount"]=$dbUser;#爲登入dbServer的帳號。
912
		$conf["dbName"]=$dbName;#爲要存取的資料庫名稱
913
		$conf["tableName"]="device";#爲要存取的資料表名稱
914
		$conf["columnYouWant"]=array("lanmac","telcom_imi","telcom_gsn");#你想要的欄位!,若設為「array("*")」則代表全部欄位.
915
		#可省略的參數:
916
		$conf["dbPassword"]=$dbPassword;#爲要存取dbServer的密碼
917
		#$conf["dbPort"],字串,爲連線到mysql-Server時要使用的port,可省略,若省略則代表使用預設的3306 port.
918
		$conf["dbPort"]=$dbPort;
919
		$conf["WhereColumnName"]=array("id");#用於判斷語句的欄位項目陣列。
920
		$conf["WhereColumnValue"]=array($gwId);#用於判斷語句的欄位數值陣列,若與LIKE搭配,則可以在關鍵自字串的左右名加上「%」符號,這樣就可以搜尋具有該字串的內容。
921
		#$conf["WhereColumnCombine"]=array("");#用於判斷語句當中需要()起來的判斷式,須爲陣列值,"s"代表「(」,"e"代表「)」 ,若無則須設爲""。
922
		#$conf["WhereColumnOperator"]=array("");#用於判斷語句的比較符號陣列,可以用的符號有「"="、"!="、">"、"<"、"LIKE"、"NOT LIKE"」,預設都爲「=」。
923
		#$conf["WhereColumnAndOr"]=array("");#用於判斷語句條件之間成立的條件是AND還是OR,須爲陣列值。其數量應爲要判斷的欄位數量減一。
924
		#$conf["whereIn"],二維字串陣列,為每個in語句的內容,特定欄位數值等於陣列元素之一。array(array("colName",array("a","b","c")));代表欄位colName的值為a,b,c三者之一.
925
		#$conf["whereIn"]=array(array("colName",array("a","b","c")));
926
		#$conf["whereNotIn"],二維字串陣列,為每個not in語句的內容,array(array("colName",array("a","b","c")));代表欄位colName的值不為a,b,c三者之一.
927
		#$conf["whereNotIn"]=array(array("colName",array("a","b","c")));
928
		#$conf["orderItem"]="";#爲排序的項目依據,若要用隨機抽樣,可以用"rand()",可省略。
929
		#$conf["ascORdesc"]="";#爲要低增還是遞減排序,asc爲遞增;desc爲遞減。
930
		#$conf["numberStart"]="0";#為從第幾筆開始讀取,預設為0,代筆第一筆。
931
		#$conf["numLimit"]="30";#為要取幾筆資料,可以省略,省略則表示不限制數目。
932
		#$conf["groupBy"]=array("");#爲要以哪幾個欄爲作爲分羣的依據(欄位相同的數值僅會取出一筆)。
933
		$fastGetDbData=db::fastGetDbData($conf);
934
		unset($conf);
935
 
936
		#debug
937
		#$var_dump($fastGetDbData);
938
 
939
		#如果執行失敗
940
		if($fastGetDbData["status"]==="false")
941
		{
942
			#印出結果
943
			var_dump($fastGetDbData);
944
 
945
			#讓程式繼續執行
946
			exit;
947
 
948
		}#if end
949
 
950
		#如果沒有符合的資料
951
		if($fastGetDbData["dataCount"]===0)
952
		{
953
			#印出結果
954
			var_dump($fastGetDbData);
955
 
956
			#讓程式繼續執行
957
			return false;
958
 
959
		}#if end
960
 
961
		#取得devcom db檔案
962
		$devcomDbFile=$params["clientInfo"]["devcomDbFile"];
963
 
964
		#函式說明:
965
		#依據行號分隔抓取檔案的內容,結果會回傳一個陣列
966
		#回傳的變數說明:
967
		#$result["status"],執行是否成功,"true"代表成功;"fasle"代表失敗.
968
		#$result["error"],錯誤訊息提示.
969
		#$result["warning"],警告訊息.
970
		#$result["function"],當前執行的函數名稱.
971
		#$result["fileContent"],爲檔案的內容陣列.
972
		#$result["lineCount"],爲檔案內容總共的行數.
973
		#$result["fullContent"],為檔案的完整內容.
974
		#$result["base64data"],為檔案的base64內容.
975
		#$result["mimeType"],為檔案的mime type.
976
		#必填的參數:
977
		#$conf["filePositionAndName"],字串,爲檔案的位置以及名稱.
978
		$conf["filePositionAndName"]=$devcomDbFile;
979
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
980
		$conf["fileArgu"]=__FILE__;
981
		#參考資料:
982
		#file(),取得檔案內容的行數.
983
		#file=>http:#php.net/manual/en/function.file.php
984
		#rtrim(),剔除透過file()取得每行內容結尾的換行符號.
985
		#filesize=>http://php.net/manual/en/function.filesize.php
986
		$getFileContent=fileAccess::getFileContent($conf);
987
		unset($conf);
988
 
989
		#如果執行失敗
990
		if($getFileContent["status"]==="false")
991
		{
992
			#印出結果
993
			var_dump($getFileContent);
994
 
995
			#讓程式繼續執行
996
			exit;
997
 
998
		}#if end
999
 
1000
		#初始化儲存每列的內容
1001
		$lineInDb=array();
1002
 
1003
		#如果沒有第一行內容
1004
		if(!isset($getFileContent["fileContent"][0]))
1005
		{
1006
			#印出結果
1007
			var_dump($getFileContent);
1008
 
1009
			#讓程式繼續執行
1010
			exit;
1011
		}
1012
 
1013
		#取得第一行的內容
1014
		$firstLine=$getFileContent["fileContent"][0];
1015
 
1016
		#解析第一行的內容,將換行符號剔除
1017
		$firstLine=json_decode(trim($firstLine));
1018
 
1019
		#更新 last_action_time
1020
		$firstLine->last_action_time=time(0);
1021
 
1022
		#更新第一行的內容
1023
		$lineInDb[]=json_encode($firstLine);
1024
 
1025
		#有幾行就執行幾次
1026
		for($i=1;$i<$getFileContent["lineCount"];$i++)
1027
		{
1028
			#記錄內容
1029
			$lineInDb[]=$getFileContent["fileContent"][$i];
1030
 
1031
		}#for end
1032
 
1033
		#初始化末行的指令
1034
		$lastLine=array();
1035
 
1036
		#設定末行的指令類型為"tgw"
1037
		$lastLine["type"]="tgw";
1038
 
1039
		#設定末行的指令內容
1040
		$lastLine["data"]=$cmd;
1041
 
1042
		#設定末行的gw id
1043
		$lastLine["gwId"]=$gwId;
1044
 
1045
		#新增末行的指令
1046
		$lineInDb[]=json_encode($lastLine);
1047
 
1048
		#回寫內容到 $devcomDbFile
1049
		#涵式說明:
1050
		#將多行字串寫入到檔案
1051
		#回傳的結果:
1052
		#$result["status"],"true"表示檔案寫入成功,"false"表示檔案寫入失敗.
1053
		#$result["error"],錯誤訊息陣列.
1054
		#$result["function"],當前執行函數的名稱.
1055
		#必填的參數:
1056
		#$conf["fileName"],字串,爲要編輯的檔案名稱
1057
		$conf["fileName"]=$devcomDbFile;
1058
		#$conf["inputString"],字串陣列,爲要寫入到 $conf["fileName"] 裏面的內容
1059
			#$conf["inputString"][$i] 代表第 $i+1 行。
1060
		$conf["inputString"]=$lineInDb;
1061
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
1062
		$conf["fileArgu"]=__FILE__;
1063
		#可省略的參數:
1064
		#$conf["writeMethod"]="a";#爲檔案撰寫的方式,可省略,是複寫'a'還是,重新寫入'w',預設爲'w',重新寫入。
1065
		$writeMultiLine=fileAccess::writeMultiLine($conf);
1066
		unset($conf);
1067
 
1068
		#如果執行失敗
1069
		if($writeMultiLine["status"]==="false")
1070
		{
1071
			#印出結果
1072
			var_dump($$writeMultiLine);
1073
 
1074
			#讓程式繼續執行
1075
			exit;
1076
 
1077
		}#if end
1078
 
1079
		#提示指令已經進入佇列
1080
		$data=json_encode("指令 ".$cmd." 送往id為 ".$gwId." 的gw 已經進入佇列");
1081
 
1082
		#函式說明:
1083
		#加密 handshake 後要傳送的訊息 
1084
		#必填參數:
1085
		#$conf["text"],字串,要加密的訊息.
1086
		$conf["text"]=$data; 
1087
		$data=\qbpwcf\webSock::encode($conf);
1088
		unset($conf);
1089
 
1090
		#告訴用戶
1091
		socket_write($params["clientSock"],$data,strlen($data));
1092
 
1093
	}#if end
1094
 
1095
	#讓程式繼續執行
1096
	return false;
1097
 
1098
	}#function cmd2gw end
1099
 
1100
/*
1101
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
1102
*/
1103
function getOnlineUsers(&$params)
1104
{
1105
	#如果資料內容等於 "getOnlineUsers"
1106
	if($params["data"]==="getOnlineUsers")
1107
	{
1108
		#get client sock
1109
		$clientSock=&$params["clientSock"];
1110
 
1111
		#預設在線的使用者人數為0
1112
		$onlineUserCount=0;
1113
 
1114
		#針對每個連線
1115
		foreach($params["allConn"] as $index=>$conn)
1116
		{
1117
			#如果存在id
1118
			if($conn["id"]!==null)
1119
			{
1120
				#計數+1
1121
				$onlineUserCount++;
1122
			}#if end
1123
 
1124
		}#foreach end
1125
 
1126
		#提示指令已經進入佇列
1127
		$data=json_encode("目前在線使用者人數為:".$onlineUserCount);
1128
 
1129
		#函式說明:
1130
		#加密 handshake 後要傳送的訊息 
1131
		#必填參數:
1132
		#$conf["text"],字串,要加密的訊息.
1133
		$conf["text"]=$data; 
1134
		$data=\qbpwcf\webSock::encode($conf);
1135
		unset($conf);
1136
 
1137
		#告訴用戶
1138
		socket_write($params["clientSock"],$data,strlen($data));
1139
 
1140
	}#if end
1141
 
1142
	#讓程式繼續執行
1143
	return false;
1144
}
1145
 
1146
/*
1147
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
1148
*/
1149
function ping(&$params)
1150
{
1151
	#如果資料內容等於 "ping"
1152
	if($params["data"]==="ping")
1153
	{
1154
		var_dump('set last ping time');
1155
 
1156
		//記錄最後一次 ping 的時間
1157
		$params["clientInfo"]["lastPingTime"]=time(0);
1158
 
1159
	}#if end
1160
 
1161
	#針對每個用戶
1162
	foreach($params["allConn"] as $index=>$client)
1163
	{
1164
		#如果有最後一次 ping 的時間
1165
		if(isset($client["lastPingTime"]))
1166
		{
1167
			#如果最後一次 ping 的時間距離現在超過 5 秒鐘
1168
			if(time(0)-$client["lastPingTime"]>5)
1169
			{
1170
				#關閉與用戶之間的連線
1171
				socket_close($client["connect"]);
1172
 
1173
				#移除在 server 上的記錄
1174
				unset($params["allConn"][$index]);
1175
 
1176
			}#if end
1177
 
1178
		}#if end
1179
 
1180
	}#foreach end
1181
 
1182
	#讓程式繼續執行
1183
	return false;
1184
}
1185
 
1186
/*
1187
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
1188
#顯示 session 變數的內容
1189
*/
1190
function checkSession(&$params)
1191
{
1192
	var_dump($params);
1193
 
1194
	#讓程式繼續執行
1195
	return false;
1196
}
1197
 
1198
?>