Subversion Repositories php-qbpwcf

Rev

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

Rev Author Line No. Line
3 liveuser 1
<?php
2
 
3
/*
4
 
5
	QBPWCF, Quick Build PHP website Component base on Fedora Linux.
239 liveuser 6
    Copyright (C) 2014~2026 MIN ZHI, CHEN
3 liveuser 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
namespace qbpwcf;
226 liveuser 26
 
3 liveuser 27
#import all lib by composer(include ratchet)
28
require 'composer/vendor/autoload.php';
29
 
30
#使用 Ratchet\MessageComponentInterface 界面
31
use Ratchet\MessageComponentInterface;
32
 
33
#使用 Ratchet\ConnectionInterface 界面
34
use Ratchet\ConnectionInterface;
35
 
36
#用 Chat 類別來實作 MessageComponentInterface 界面
37
class Chat implements MessageComponentInterface{
226 liveuser 38
 
3 liveuser 39
	#初始化儲存使用者資訊的陣列
226 liveuser 40
	private $connInfo=array();
41
 
3 liveuser 42
	#初始化儲存未傳送出去的留言訊息
43
	#"fromId",訊息來源的id
44
	#"toId",訊息目的的id
45
	#"fromUserId",訊息來源的userId
46
	#"toUserId",訊息目標的userId
47
	#"msg",傳送的訊息
48
	private $unSendMsg=array();
226 liveuser 49
 
3 liveuser 50
	#初始化一開始尚未能夠連線到資料庫
51
	private static $dbTouchable=false;
226 liveuser 52
 
3 liveuser 53
	#初始化db的位置
226 liveuser 54
	public static $dbAddress="localhost";
55
 
3 liveuser 56
	#初始化連線db用的帳戶
57
	public static $dbAccount="root";
226 liveuser 58
 
3 liveuser 59
	#初始化連線的db名稱
60
	public static $dbName="test";
226 liveuser 61
 
3 liveuser 62
	#初始化連線db時用的密碼
63
	public static $dbPassword="";
226 liveuser 64
 
3 liveuser 65
	#初始化連線db的哪個資料表
66
	public static $memberTableName="member";
226 liveuser 67
 
3 liveuser 68
	#初始化登入時用來驗證帳號的資料表欄位名稱
69
	public static $accountCol="account";
226 liveuser 70
 
3 liveuser 71
	#初始化登入時用來驗證密碼的資料表欄位名稱,設為""代表不用密碼來認證
72
	public static $passwordCol="password";
226 liveuser 73
 
3 liveuser 74
	#建構子
75
	public function __construct(){
226 liveuser 76
 
3 liveuser 77
		#如果尚未可以上資料庫
78
		if(!(self::$dbTouchable)){
226 liveuser 79
 
3 liveuser 80
			#嘗試連線到目標資料庫.資料表
81
			#涵式說明:
82
			#一次取得資料庫、表的資料
83
			#回傳的結果
84
			#$result["status"],執行結果"true"為成功;"false"為執行失敗。
85
			#$result["error"],錯誤訊息陣列。
86
			#$result["function"],當前執行的漢書名稱.
87
			#$result["dataColumnName"],抓取的資料欄位名稱陣列.
88
				#$result["dataColumnName"][$i]代表第$i+1個欄位名稱
89
			#$result["dataContent"],爲資料的內容。
90
			#$result["dataContent"][$conf["WhereColumnName"][$i]][$dataSetNum]
91
				#$dataSetNum 爲第$dataSetNum+1筆資料
92
				#$conf["WhereColumnName"][$i] 爲第 $i+1 個欄位的名稱
93
			#$result["dataCount"],爲取得的資料筆數。
94
			#$result["sql"],執行的sql字串.
95
			#必填的參數:
96
			$conf["db::fastGetDbData"]["dbAddress"]=self::$dbAddress;#爲dbServer的位置。
97
			$conf["db::fastGetDbData"]["dbAccount"]=self::$dbAccount;#爲登入dbServer的帳號。
98
			$conf["db::fastGetDbData"]["dbName"]=self::$dbName;#爲要存取的資料庫名稱
99
			$conf["db::fastGetDbData"]["tableName"]=self::$memberTableName;#爲要存取的資料表名稱
100
			$conf["db::fastGetDbData"]["columnYouWant"]=array("id",self::$accountCol);#你想要的欄位!,若設為「array("*")」則代表全部欄位.
226 liveuser 101
 
3 liveuser 102
			#如果 $passwordCol 不為空
103
			if(self::$passwordCol!=""){
226 liveuser 104
 
3 liveuser 105
				#加上密碼欄位
106
				$conf["db::fastGetDbData"]["columnYouWant"][]=self::$passwordCol;
226 liveuser 107
 
3 liveuser 108
				}#if end
226 liveuser 109
 
3 liveuser 110
			#可省略的參數:
111
			$conf["db::fastGetDbData"]["dbPassword"]=self::$dbPassword;#爲要存取dbServer的密碼
112
			#$conf["db::fastGetDbData"]["WhereColumnName"]=array("account","password");#用於判斷語句的欄位項目陣列。
113
			#$conf["db::fastGetDbData"]["WhereColumnValue"]=array($ac,$pw);#用於判斷語句的欄位數值陣列,若與LIKE搭配,則可以在關鍵自字串的左右名加上「%」符號,這樣就可以搜尋具有該字串的內容。
114
			#$conf["WhereColumnCombine"]=array("");#用於判斷語句當中需要()起來的判斷式,須爲陣列值,"s"代表「(」,"e"代表「)」 ,若無則須設爲""。
115
			#$conf["WhereColumnOperator"]=array("");#用於判斷語句的比較符號陣列,可以用的符號有「"="、"!="、">"、"<"、"LIKE"、"NOT LIKE"」,預設都爲「=」。
116
			#$conf["WhereColumnAndOr"]=array("");#用於判斷語句條件之間成立的條件是AND還是OR,須爲陣列值。其數量應爲要判斷的欄位數量減一。
117
			#$conf["orderItem"]="";#爲排序的項目依據,若要用隨機抽樣,可以用"rand()",可省略。
118
			#$conf["ascORdesc"]="";#爲要低增還是遞減排序,asc爲遞增;desc爲遞減。
119
			#$conf["numberStart"]="0";#為從第幾筆開始讀取,預設為0,代筆第一筆。
120
			$conf["db::fastGetDbData"]["numLimit"]="1";#為要取幾筆資料,可以省略,省略則表示不限制數目。
121
			#$conf["groupBy"]=array("");#爲要以哪幾個欄爲作爲分羣的依據(欄位相同的數值僅會取出一筆)。
122
			#備註:
123
			#建議在查詢資料前,能夠檢查是否每個欄位都存在.
124
			$fastGetDbData=db::fastGetDbData($conf["db::fastGetDbData"]);
125
			unset($conf["db::fastGetDbData"]);
226 liveuser 126
 
3 liveuser 127
			#如果取得資料失敗
128
			if($fastGetDbData["status"]==="false"){
226 liveuser 129
 
3 liveuser 130
				#設置執行失敗
131
				$result["status"]="false";
226 liveuser 132
 
3 liveuser 133
				#設置執行錯誤訊息
134
				$result["error"]=$fastGetDbData;
226 liveuser 135
 
3 liveuser 136
				#印出debug訊息
137
				var_dump($result);
226 liveuser 138
 
3 liveuser 139
				#結束程式
140
				exit;
226 liveuser 141
 
3 liveuser 142
				}#if end
226 liveuser 143
 
3 liveuser 144
			#連線成功,將self::dbTouchable設為true
145
			self::$dbTouchable=true;
226 liveuser 146
 
3 liveuser 147
			}#if end
226 liveuser 148
 
323 liveuser 149
		$this->clients = new \SplObjectStorage;
226 liveuser 150
 
3 liveuser 151
		}#funciton __construct end
226 liveuser 152
 
3 liveuser 153
	#當用戶與伺服器建立連線時
323 liveuser 154
	public function onOpen(ConnectionInterface $conn){
226 liveuser 155
 
3 liveuser 156
		// Store the new connection to send messages to later
323 liveuser 157
		$this->clients->attach($conn);
3 liveuser 158
 
159
		#提示server有clent連上web socket.
323 liveuser 160
		echo "New connection! ({$conn->resourceId})\n";
226 liveuser 161
 
3 liveuser 162
		#用client的id為index來儲存額外的資訊
323 liveuser 163
		#元素 "conn" 代表已經建立連線的ConnectionInterface物件
164
		#元素 "talkTo" 代表要跟誰講話
3 liveuser 165
		#元素 "userId" 代表辨識使用者的id
166
		#元素 "loigin=array("ac","pw")" 代表client輸入的帳號與密碼
323 liveuser 167
		 #$this->connInfo[$conn->resourceId]=array("conn"=>$conn,"talkTo"=>array(),"userId"=>"","login"=>array("ac"=>"","pw"=>""),"type"=>"");
168
		$this->connInfo[$conn->resourceId]=array("conn"=>$conn,"talkTo"=>array(),"userId"=>"","login"=>array("ac"=>"","pw"=>""));
226 liveuser 169
 
170
		#提示登入
3 liveuser 171
		$conn->send(json_encode("Please input your account! ex:account:ws1"));
226 liveuser 172
 
3 liveuser 173
		}#function onOpen end
174
 
175
	#當伺服器收到訊息時
323 liveuser 176
	public function onMessage(ConnectionInterface $from, $msg){
226 liveuser 177
 
3 liveuser 178
		#如果該連線沒有使用者id
179
		if($this->connInfo[$from->resourceId]["userId"]===""){
226 liveuser 180
 
3 liveuser 181
			#如果尚未輸入帳戶
182
			if($this->connInfo[$from->resourceId]["login"]["ac"]===""){
226 liveuser 183
 
3 liveuser 184
				#如果 $msg 長度大於 "account:"
185
				if(strlen($msg) > strlen("account:")){
226 liveuser 186
 
3 liveuser 187
					#檢查有無前置字元 "account:"
188
					#函式說明:
189
					#將字串特定關鍵字與其前面的內容剔除
190
					#回傳結果:
191
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
192
					#$result["error"],錯誤訊息陣列.
193
					#$result["warning"],警告訊息鎮列.
194
					#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
195
					#$result["function"],當前執行的函數名稱.
196
					#$result["oriStr"],要處理的原始字串內容.
197
					#$result["content"],處理好的的字串內容.
198
					#必填的參數:
199
					$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$msg;#要處理的字串.
200
					$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="account:";#特定字串.
201
					$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
202
					unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 203
 
3 liveuser 204
					#如果移除前置字元失敗
205
					if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 206
 
3 liveuser 207
						#設置執行失敗
208
						$result["status"]="false";
226 liveuser 209
 
3 liveuser 210
						#設置執行錯誤訊息
211
						$result["error"]=$delStrBeforeKeyWord;
226 liveuser 212
 
3 liveuser 213
						#回傳結果
214
						return $result;
226 liveuser 215
 
3 liveuser 216
						}#if end
226 liveuser 217
 
3 liveuser 218
					#如果有符合條件的前置字元
219
					if($delStrBeforeKeyWord["founded"]==="true"){
226 liveuser 220
 
3 liveuser 221
						#儲存帳戶
222
						$this->connInfo[$from->resourceId]["login"]["ac"]=$delStrBeforeKeyWord["content"];
226 liveuser 223
 
3 liveuser 224
						}#if end
226 liveuser 225
 
226
					#反之代表格式錯誤
3 liveuser 227
					else{
226 liveuser 228
 
3 liveuser 229
						#提示輸入帳戶
230
						$from->send(json_encode("Please input your account! ex:account:ws1"));
226 liveuser 231
 
3 liveuser 232
						#結束程式
233
						return true;
226 liveuser 234
 
3 liveuser 235
						}#else end
226 liveuser 236
 
3 liveuser 237
					}#if end
226 liveuser 238
 
3 liveuser 239
				#反之代表輸入錯誤格式的account
240
				else{
226 liveuser 241
 
242
					#提示輸入帳號
3 liveuser 243
					$from->send(json_encode("Please input your account! ex:account:ws1"));
226 liveuser 244
 
3 liveuser 245
					#結束程式
246
					return true;
226 liveuser 247
 
3 liveuser 248
					}#else end
226 liveuser 249
 
3 liveuser 250
				}#if end
226 liveuser 251
 
3 liveuser 252
			#如果有設置密碼欄位
253
			if(self::$passwordCol!==""){
226 liveuser 254
 
3 liveuser 255
				#如果尚未輸入密碼
256
				if($this->connInfo[$from->resourceId]["login"]["pw"]===""){
226 liveuser 257
 
3 liveuser 258
					#$msg 長度大於 "password:"
259
					if(strlen($msg) > strlen("password:")){
226 liveuser 260
 
3 liveuser 261
						#檢查有無前置字元 "password:"
262
						#函式說明:
263
						#將字串特定關鍵字與其前面的內容剔除
264
						#回傳結果:
265
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
266
						#$result["error"],錯誤訊息陣列.
267
						#$result["warning"],警告訊息鎮列.
268
						#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
269
						#$result["function"],當前執行的函數名稱.
270
						#$result["oriStr"],要處理的原始字串內容.
271
						#$result["content"],處理好的的字串內容.
272
						#必填的參數:
273
						$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$msg;#要處理的字串.
274
						$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="password:";#特定字串.
275
						$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
276
						unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 277
 
3 liveuser 278
						#如果移除前置字元失敗
279
						if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 280
 
3 liveuser 281
							#設置執行失敗
282
							$result["status"]="false";
226 liveuser 283
 
3 liveuser 284
							#設置執行錯誤訊息
285
							$result["error"]=$delStrBeforeKeyWord;
226 liveuser 286
 
3 liveuser 287
							#回傳結果
288
							return $result;
226 liveuser 289
 
3 liveuser 290
							}#if end
226 liveuser 291
 
3 liveuser 292
						#如果有符合條件的前置字元
293
						if($delStrBeforeKeyWord["founded"]==="true"){
226 liveuser 294
 
3 liveuser 295
							#儲存密碼
296
							$this->connInfo[$from->resourceId]["login"]["pw"]=$delStrBeforeKeyWord["content"];
226 liveuser 297
 
3 liveuser 298
							}#if end
226 liveuser 299
 
3 liveuser 300
						#反之代表格式錯誤
301
						else{
226 liveuser 302
 
3 liveuser 303
							#提示輸入密碼
304
							$from->send(json_encode("Please input your password! ex:password:ws1"));
226 liveuser 305
 
3 liveuser 306
							#結束程式
307
							return true;
226 liveuser 308
 
3 liveuser 309
							}#else end
226 liveuser 310
 
3 liveuser 311
						}#if end
226 liveuser 312
 
3 liveuser 313
					#反之代表格式錯誤
314
					else{
226 liveuser 315
 
316
						#提示輸入密碼
3 liveuser 317
						$from->send(json_encode("Please input your password! ex:password:ws1"));
226 liveuser 318
 
3 liveuser 319
						#結束程式
320
						return true;
226 liveuser 321
 
3 liveuser 322
						}#else end
226 liveuser 323
 
3 liveuser 324
					}#if end
226 liveuser 325
 
3 liveuser 326
				}#if end
226 liveuser 327
 
3 liveuser 328
			#如果已經輸入帳號了
329
			if($this->connInfo[$from->resourceId]["login"]["ac"]!=""){
226 liveuser 330
 
3 liveuser 331
				#設置可以進行驗證
332
				$startAuth=true;
226 liveuser 333
 
3 liveuser 334
				#另存帳號
335
				$ac=$this->connInfo[$from->resourceId]["login"]["ac"];
226 liveuser 336
 
3 liveuser 337
				#初始化密碼
338
				$pw="";
226 liveuser 339
 
3 liveuser 340
				#如果有設置密碼欄位
341
				if(self::$passwordCol!==""){
226 liveuser 342
 
3 liveuser 343
					#如果client已經輸入密碼了
344
					if($this->connInfo[$from->resourceId]["login"]["pw"]!=""){
226 liveuser 345
 
3 liveuser 346
						#另存密碼
347
						$pw=md5($this->connInfo[$from->resourceId]["login"]["pw"]);
226 liveuser 348
 
3 liveuser 349
						}#if end
226 liveuser 350
 
3 liveuser 351
					#反之
352
					else{
226 liveuser 353
 
3 liveuser 354
						#設置尚不能進行認證
355
						$startAuth=false;
226 liveuser 356
 
3 liveuser 357
						}#else end
226 liveuser 358
 
3 liveuser 359
					}#if end
226 liveuser 360
 
3 liveuser 361
				#如果尚不能進行驗證
362
				if(!$startAuth){
226 liveuser 363
 
3 liveuser 364
					#結束程式
365
					return true;
226 liveuser 366
 
3 liveuser 367
					}#if end
226 liveuser 368
 
3 liveuser 369
				#檢查有無符合的帳戶密碼
370
				#涵式說明:
371
				#一次取得資料庫、表的資料
372
				#回傳的結果
373
				#$result["status"],執行結果"true"為成功;"false"為執行失敗。
374
				#$result["error"],錯誤訊息陣列。
375
				#$result["function"],當前執行的漢書名稱.
376
				#$result["dataColumnName"],抓取的資料欄位名稱陣列.
377
					#$result["dataColumnName"][$i]代表第$i+1個欄位名稱
378
				#$result["dataContent"],爲資料的內容。
379
				#$result["dataContent"][$conf["WhereColumnName"][$i]][$dataSetNum]
380
					#$dataSetNum 爲第$dataSetNum+1筆資料
381
					#$conf["WhereColumnName"][$i] 爲第 $i+1 個欄位的名稱
382
				#$result["dataCount"],爲取得的資料筆數。
383
				#$result["sql"],執行的sql字串.
384
				#必填的參數:
385
				$conf["db::fastGetDbData"]["dbAddress"]=self::$dbAddress;#爲dbServer的位置。
386
				$conf["db::fastGetDbData"]["dbAccount"]=self::$dbAccount;#爲登入dbServer的帳號。
387
				$conf["db::fastGetDbData"]["dbName"]=self::$dbName;#爲要存取的資料庫名稱
388
				$conf["db::fastGetDbData"]["tableName"]=self::$memberTableName;#爲要存取的資料表名稱
389
				$conf["db::fastGetDbData"]["columnYouWant"]=array("id");#你想要的欄位!,若設為「array("*")」則代表全部欄位.
390
				#可省略的參數:
391
				$conf["db::fastGetDbData"]["dbPassword"]=self::$dbPassword;#爲要存取dbServer的密碼
392
				$conf["db::fastGetDbData"]["WhereColumnName"]=array(self::$accountCol);#用於判斷語句的欄位項目陣列。
393
				$conf["db::fastGetDbData"]["WhereColumnValue"]=array($ac);#用於判斷語句的欄位數值陣列,若與LIKE搭配,則可以在關鍵自字串的左右名加上「%」符號,這樣就可以搜尋具有該字串的內容。
226 liveuser 394
 
3 liveuser 395
				#如果有輸入密碼
396
				if($pw!==""){
226 liveuser 397
 
3 liveuser 398
					#新增要判斷 self::$password 欄位,是否有於 $pw
399
					$conf["db::fastGetDbData"]["WhereColumnName"][]=self::$passwordCol;
400
					$conf["db::fastGetDbData"]["WhereColumnValue"][]=$pw;
226 liveuser 401
 
3 liveuser 402
					}#if end
226 liveuser 403
 
3 liveuser 404
				#$conf["WhereColumnCombine"]=array("");#用於判斷語句當中需要()起來的判斷式,須爲陣列值,"s"代表「(」,"e"代表「)」 ,若無則須設爲""。
405
				#$conf["WhereColumnOperator"]=array("");#用於判斷語句的比較符號陣列,可以用的符號有「"="、"!="、">"、"<"、"LIKE"、"NOT LIKE"」,預設都爲「=」。
406
				#$conf["WhereColumnAndOr"]=array("");#用於判斷語句條件之間成立的條件是AND還是OR,須爲陣列值。其數量應爲要判斷的欄位數量減一。
407
				#$conf["orderItem"]="";#爲排序的項目依據,若要用隨機抽樣,可以用"rand()",可省略。
408
				#$conf["ascORdesc"]="";#爲要低增還是遞減排序,asc爲遞增;desc爲遞減。
409
				#$conf["numberStart"]="0";#為從第幾筆開始讀取,預設為0,代筆第一筆。
410
				$conf["db::fastGetDbData"]["numLimit"]="1";#為要取幾筆資料,可以省略,省略則表示不限制數目。
411
				#$conf["groupBy"]=array("");#爲要以哪幾個欄爲作爲分羣的依據(欄位相同的數值僅會取出一筆)。
412
				#備註:
413
				#建議在查詢資料前,能夠檢查是否每個欄位都存在.
414
				$fastGetDbData=db::fastGetDbData($conf["db::fastGetDbData"]);
415
				unset($conf["db::fastGetDbData"]);
226 liveuser 416
 
3 liveuser 417
				#如果取得資料失敗
418
				if($fastGetDbData["status"]==="false"){
226 liveuser 419
 
3 liveuser 420
					#設置執行失敗
421
					$result["status"]="false";
226 liveuser 422
 
3 liveuser 423
					#設置執行錯誤訊息
424
					$result["error"]=$fastGetDbData;
226 liveuser 425
 
3 liveuser 426
					#印出結果
427
					#var_dump($result);
226 liveuser 428
 
3 liveuser 429
					#提示server有資料庫錯誤
430
					echo "dbError!";
226 liveuser 431
 
3 liveuser 432
					#結束程式
433
					exit;
226 liveuser 434
 
3 liveuser 435
					}#if end
226 liveuser 436
 
3 liveuser 437
				#如果沒有一筆資料
438
				if($fastGetDbData["dataCount"]!==1){
226 liveuser 439
 
3 liveuser 440
					#代表登入失敗
226 liveuser 441
 
3 liveuser 442
					#清空登入用的帳戶
443
					$this->connInfo[$from->resourceId]["login"]["ac"]="";
226 liveuser 444
 
3 liveuser 445
					#清空登入用的密碼
446
					$this->connInfo[$from->resourceId]["login"]["pw"]="";
226 liveuser 447
 
448
					#提示登入失敗
3 liveuser 449
					$from->send(json_encode("Login failed, please input account. ex:account:ws1"));
226 liveuser 450
 
3 liveuser 451
					#執行到這即可
452
					return true;
226 liveuser 453
 
3 liveuser 454
					}#if end
226 liveuser 455
 
3 liveuser 456
				#反之代表帳戶資訊正確
457
				else{
226 liveuser 458
 
3 liveuser 459
					#設置 $myUserId
460
					$myUserId=$this->connInfo[$from->resourceId]["userId"]=$fastGetDbData["dataContent"]["id"][0];
226 liveuser 461
 
3 liveuser 462
					#設置 $myId
463
					$myId=$from->resourceId;
226 liveuser 464
 
3 liveuser 465
					#提示登入成功
466
					$from->send(json_encode("Login successfully!"));
226 liveuser 467
 
3 liveuser 468
					#檢查是否有訊息是要給自己的
469
					foreach($this->unSendMsg as $index => $historyMsg){
226 liveuser 470
 
3 liveuser 471
						#如果有要給自己的訊息
472
						if($myUserId===$historyMsg["toUserId"]){
226 liveuser 473
 
3 liveuser 474
							#接收別人給的留言
475
							$from->send(json_encode($historyMsg["msg"]));
226 liveuser 476
 
3 liveuser 477
							#有幾個人在線上就執行幾次
478
							foreach($this->connInfo as $toId => $cInfo){
226 liveuser 479
 
3 liveuser 480
								#如果是自己
481
								if($myId===$toId ){
226 liveuser 482
 
3 liveuser 483
									#跳過
484
									continue;
226 liveuser 485
 
3 liveuser 486
									}#if end
226 liveuser 487
 
3 liveuser 488
								#如果留言的對象有在線上
489
								if($historyMsg["fromUserId"]===$cInfo["userId"]){
226 liveuser 490
 
3 liveuser 491
									#檢查對方是否已經在自己的通話清單裡面了
226 liveuser 492
 
3 liveuser 493
									#初始化要將對方加到自己的對話清單裡面
494
									$add=false;
226 liveuser 495
 
3 liveuser 496
									#根據自己的每個通話對象
497
									foreach($this->connInfo[$myId]["talkTo"] as $myToIndex=>$myToCinfo ){
226 liveuser 498
 
3 liveuser 499
										#如果對對方已經存在於自己的對話清單裡面了
500
										if($myToCinfo["userId"]===$historyMsg["fromUserId"] && $myId===$historyMsg["fromId"]){
226 liveuser 501
 
3 liveuser 502
											#設置不要將對方加到自己的對話清單裡面
503
											$add=false;
226 liveuser 504
 
3 liveuser 505
											#跳出foreach
506
											break;
226 liveuser 507
 
3 liveuser 508
											}#if end
226 liveuser 509
 
3 liveuser 510
										}#foreach end
226 liveuser 511
 
3 liveuser 512
									#如果要將對方加到自己的對話清單裡面
513
									if($add){
226 liveuser 514
 
3 liveuser 515
										#將對方加到自己的talkTo清單裡面
516
										$this->connInfo[$myId]["talkTo"][]=array("id"=>$toId,"userId"=>$historyMsg["fromUserId"]);
226 liveuser 517
 
3 liveuser 518
										}#if end
226 liveuser 519
 
3 liveuser 520
									#檢查自己有沒有在對方talkTo清單裡面
226 liveuser 521
 
3 liveuser 522
									#假設對方需要加自己到對話清單裡面
523
									$add=true;
226 liveuser 524
 
3 liveuser 525
									#檢查通話對象能否跟自己對話
226 liveuser 526
 
3 liveuser 527
									#依據對方每個通話的對象
528
									foreach($this->connInfo[$toId]["talkTo"] as $talkToIndex=>$talkToCinfo){
226 liveuser 529
 
3 liveuser 530
										#如果自己的userId已經在對方的對話清單裡面了
531
										if($myUserId===$talkToCinfo["userId"]){
226 liveuser 532
 
3 liveuser 533
											#如果對方對話userId對應的id不在線上
534
											if(!isset($this->connInfo[$toId])){
226 liveuser 535
 
3 liveuser 536
												#檢查對方對話清單是否已經含有自己的id與userId了
226 liveuser 537
 
3 liveuser 538
												#假設對方對話清單沒有自己的id與userId
539
												$update=true;
226 liveuser 540
 
3 liveuser 541
												#依據對方每個通話的對象
542
												foreach($this->connInfo[$toId]["talkTo"] as $ceToIndex=>$ceToCinfo){
226 liveuser 543
 
544
													#如果對方對話清單已經含有自己的id與userId了
3 liveuser 545
													if($ceToCinfo["id"]===$myId && $ceToCinfo["userId"]===$myUserId){
226 liveuser 546
 
3 liveuser 547
														#設置不需要更新
548
														$update=false;
226 liveuser 549
 
3 liveuser 550
														#設置對方不需要加自己到對話清單裡面
551
														$add=false;
226 liveuser 552
 
3 liveuser 553
														}#if end
226 liveuser 554
 
3 liveuser 555
													}#foreach end
226 liveuser 556
 
3 liveuser 557
												#如果對方對話清單沒有自己的id與userId
558
												if($update){
226 liveuser 559
 
3 liveuser 560
													#將自己在對方對話清單裡面的id改成現在的id
561
													$this->connInfo[$toId]["talkTo"][$talkToIndex]["id"]=$myId;
226 liveuser 562
 
3 liveuser 563
													}#if end
226 liveuser 564
 
3 liveuser 565
												#反之對方對話清單已經有自己的id與userId
566
												else{
226 liveuser 567
 
3 liveuser 568
													#移除對方該已經斷線的對話id
569
													unset($this->connInfo[$toId]["talkTo"][$talkToIndex]);
226 liveuser 570
 
3 liveuser 571
													}#else end
226 liveuser 572
 
3 liveuser 573
												}#if end
226 liveuser 574
 
3 liveuser 575
											}#if end
226 liveuser 576
 
3 liveuser 577
										}#foreach end
226 liveuser 578
 
3 liveuser 579
									#如果對方需要加自己到對話清單裡面
580
									if($add){
226 liveuser 581
 
3 liveuser 582
										#讓通話對象也可以傳送訊息回來
583
										$this->connInfo[$toId]["talkTo"][]=array("id"=>$myId,"userId"=>$myUserId);
226 liveuser 584
 
3 liveuser 585
										}#if end
226 liveuser 586
 
3 liveuser 587
									}#if end
226 liveuser 588
 
3 liveuser 589
								}#foreach end
226 liveuser 590
 
3 liveuser 591
							#移除留言紀錄
592
							unset($this->unSendMsg[$index]);
226 liveuser 593
 
3 liveuser 594
							}#if end
226 liveuser 595
 
3 liveuser 596
						}#foreach end
226 liveuser 597
 
3 liveuser 598
					#檢查線上是否有人想跟我對話
226 liveuser 599
 
3 liveuser 600
					#有幾個人在線上就執行幾次
601
					foreach($this->connInfo as $toId => $cInfo){
226 liveuser 602
 
3 liveuser 603
						#如果是自己
604
						if($myId===$toId){
226 liveuser 605
 
3 liveuser 606
							#跳過
607
							continue;
226 liveuser 608
 
3 liveuser 609
							}#if end
226 liveuser 610
 
3 liveuser 611
						#該cliet目前再跟幾個人通話,就執行幾次
612
						foreach($cInfo["talkTo"] as $tIndex=>$tInfo){
226 liveuser 613
 
3 liveuser 614
							#如果自己的userId在對方的對話清單裡面
615
							if($myUserId===$tInfo["userId"]){
226 liveuser 616
 
3 liveuser 617
								#假設自己需要被對方加到對話清單裡面
618
								$add=true;
226 liveuser 619
 
3 liveuser 620
								#檢查自己是否已經在對方的對話清單裡面
226 liveuser 621
 
3 liveuser 622
								#對方有幾個通話對象就執行幾次
623
								foreach($this->connInfo[$toId]["talkTo"] as $toIndex=>$toCinfo){
226 liveuser 624
 
3 liveuser 625
									#如果自己已經在對方的對話清單裡面
626
									if($myUserId===$toCinfo["userId"] && $myId===$toCinfo["id"]){
226 liveuser 627
 
3 liveuser 628
										#設置自己不需要被對方加到對話清單裡面
629
										$add=false;
226 liveuser 630
 
3 liveuser 631
										#跳出迴圈
632
										break;
226 liveuser 633
 
3 liveuser 634
										}#if end
226 liveuser 635
 
3 liveuser 636
									}#foreach end
226 liveuser 637
 
3 liveuser 638
								#另存針對自己userId的連線id
639
								$oneIdOfMyUserid=$this->connInfo[$toId]["talkTo"][$tIndex]["id"];
226 liveuser 640
 
3 liveuser 641
								#如果對方對話清單裡面的用戶id不在線
642
								if(!isset($this->connInfo[$oneIdOfMyUserid])){
226 liveuser 643
 
3 liveuser 644
									#假設要將自己在對方對話清單裡面的id改成現在的id
645
									$update=true;
226 liveuser 646
 
3 liveuser 647
									#自己不需要被對方加到對話清單裡面
648
									$add=false;
226 liveuser 649
 
3 liveuser 650
									#檢查自己的id是否已經在對方的對話id裡面
651
									foreach($this->connInfo[$toId]["talkTo"] as $ceIndex=>$ceInfo){
226 liveuser 652
 
3 liveuser 653
										#如果自己的id已經在對方的對話清單裡面
654
										if($myId===$ceInfo["id"]){
226 liveuser 655
 
3 liveuser 656
											#設置不要將自己在對方對話清單裡面的id改成現在的id(可以移除該對話id)
657
											$update=false;
226 liveuser 658
 
3 liveuser 659
											#跳出迴圈
660
											break;
226 liveuser 661
 
3 liveuser 662
											}#if end
226 liveuser 663
 
3 liveuser 664
										}#foreach end
226 liveuser 665
 
3 liveuser 666
									#如果要將自己在對方對話清單裡面的id改成現在的id
667
									if($update){
226 liveuser 668
 
3 liveuser 669
										#將自己在對方對話清單裡面的id改成現在的id
670
										$this->connInfo[$toId]["talkTo"][$tIndex]["id"]=$myId;
226 liveuser 671
 
3 liveuser 672
										}#if end
226 liveuser 673
 
3 liveuser 674
									#反之不要將自己在對方對話清單裡面的id改成現在的id(可以移除該對話id)
675
									else{
226 liveuser 676
 
3 liveuser 677
										#移除該對話id
678
										unset($this->connInfo[$toId]["talkTo"][$tIndex]);
226 liveuser 679
 
3 liveuser 680
										}#else end
226 liveuser 681
 
682
									}#if end
683
 
3 liveuser 684
								#如果要將自己加到對方的的通話清單裡面
685
								if($add){
226 liveuser 686
 
3 liveuser 687
									#將自己加到對方的的通話清單裡面
226 liveuser 688
									$this->connInfo[$toId]["talkTo"][]=array("id"=>$myId,"userId"=>$myUserId);
689
 
690
									}#if end
691
 
3 liveuser 692
								#檢查對方是否已經在自己的對話清單裡面
226 liveuser 693
 
3 liveuser 694
								#設置要新增對方到自己的對話清單裡面.
695
								$add=true;
226 liveuser 696
 
3 liveuser 697
								#自己有幾個對話對象就執行幾次
698
								foreach($this->connInfo[$myId]["talkTo"] as $mtIndex=>$mtInfo){
226 liveuser 699
 
3 liveuser 700
									#對方的userId與id若在自己的對話清單裡面
701
									if($mtInfo["userId"]===$cInfo["userId"] && $mtInfo["id"]===$toId){
226 liveuser 702
 
3 liveuser 703
										#設置不需要新增對方到自己的對話清單裡面
704
										$add=false;
226 liveuser 705
 
3 liveuser 706
										#跳出 foreach
707
										break;
226 liveuser 708
 
3 liveuser 709
										}#if end
226 liveuser 710
 
3 liveuser 711
									}#foreache end
226 liveuser 712
 
3 liveuser 713
								#如果要新增對方到自己的對話清單裡面.
714
								if($add){
226 liveuser 715
 
3 liveuser 716
									#將對方加到自己的對話清單裡面
717
									$this->connInfo[$myId]["talkTo"][]=array("id"=>$toId,"userId"=>$cInfo["userId"]);
226 liveuser 718
 
3 liveuser 719
									}#if end
226 liveuser 720
 
3 liveuser 721
								}#if end
226 liveuser 722
 
3 liveuser 723
							}#foreach end
226 liveuser 724
 
3 liveuser 725
						}#foreach end
226 liveuser 726
 
3 liveuser 727
					#結束認證成功後的流程
728
					return true;
226 liveuser 729
 
3 liveuser 730
					}#else end
226 liveuser 731
 
3 liveuser 732
				}#else end
226 liveuser 733
 
3 liveuser 734
			#結束認證流程
226 liveuser 735
			return true;
736
 
3 liveuser 737
			}#if end
226 liveuser 738
 
3 liveuser 739
		#如果收到 "id?"
740
		else if($msg==="id?"){
226 liveuser 741
 
3 liveuser 742
			#傳他人的id給client
743
			$from->send(json_encode($from->resourceId));
226 liveuser 744
 
3 liveuser 745
			#回傳成功
746
			return true;
226 liveuser 747
 
3 liveuser 748
			}#if end
226 liveuser 749
 
3 liveuser 750
		#如果收到 "ids?"
751
		else if($msg==="ids?"){
226 liveuser 752
 
3 liveuser 753
			#初始化儲存其他人的id
754
			$idsArray=array();
226 liveuser 755
 
3 liveuser 756
			#針對所的client
757
			foreach ($this->clients as $client){
226 liveuser 758
 
3 liveuser 759
				#排除自己
760
				if($from !== $client){
226 liveuser 761
 
3 liveuser 762
					#取得其他人的id
763
					$idsArray[]=$client->resourceId;
226 liveuser 764
 
3 liveuser 765
					}#if end
226 liveuser 766
 
767
				}#foreach end
768
 
3 liveuser 769
			#傳他人的id給client
770
			$from->send(json_encode($idsArray));
226 liveuser 771
 
3 liveuser 772
			#回傳成功
773
			return true;
226 liveuser 774
 
3 liveuser 775
			}#if end
226 liveuser 776
 
3 liveuser 777
		#如果收到 "talkTo?"
778
		else if($msg==="talkTo?"){
226 liveuser 779
 
3 liveuser 780
			#正在對話的對象id給client
781
			$from->send(json_encode($this->connInfo[$from->resourceId]["talkTo"]));
226 liveuser 782
 
3 liveuser 783
			#回傳成功
784
			return true;
226 liveuser 785
 
3 liveuser 786
			}#if end
226 liveuser 787
 
3 liveuser 788
		#如果收到的$msg長度大於 "talkTo:"
789
		if(strlen($msg)>strlen("talkTo:")){
226 liveuser 790
 
791
			#如果收到開頭為 "talkTo:"
3 liveuser 792
			#涵式說明:
793
			#取得符合特定字首與字尾的字串
794
			#回傳的結果:
795
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
796
			#$result["function"],當前執行的函數名稱.
797
			#$result["error"],錯誤訊息陣列.
798
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
799
			#$result["returnString"],爲符合字首條件的字串內容。
800
			#必填參數:
801
			#$conf["checkString"],字串,要檢查的字串.
802
			$conf["search::getMeetConditionsString"]["checkString"]=$msg;
803
			#可省略參數:
804
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
805
			$conf["search::getMeetConditionsString"]["frontWord"]="talkTo:";
806
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
807
			#$conf["tailWord"]="";
808
			#參考資料:
809
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
810
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
811
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 812
 
3 liveuser 813
			#如果選找前置字串 "talkTo:" 失敗
814
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 815
 
3 liveuser 816
				#設置執行失敗
817
				$result["status"]="false";
226 liveuser 818
 
3 liveuser 819
				#設置執行錯誤訊息
820
				$result["error"]=$getMeetConditionsString;
226 liveuser 821
 
3 liveuser 822
				#回傳結果
823
				return $result;
226 liveuser 824
 
3 liveuser 825
				}#if end
226 liveuser 826
 
3 liveuser 827
			#如果存在 "talkTo:" 前置字串
828
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 829
 
3 liveuser 830
				#用 "talkTo:" 分割 $buf
831
				#涵式說明:
832
				#將固定格式的字串分開,並回傳分開的結果。
833
				#回傳結果:
834
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
835
				#$result["error"],錯誤訊息陣列
836
				#$result["function"],當前執行的函數名稱.
837
				#$result["oriStr"],要分割的原始字串內容
838
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
839
				#$result["dataCounts"],爲總共分成幾段
840
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
841
				#必填的參數:
842
				$conf["stringProcess::spiltString"]["stringIn"]=$msg;#要處理的字串。
843
				$conf["stringProcess::spiltString"]["spiltSymbol"]="talkTo:";#爲以哪個符號作爲分割
844
				#可省略參數:
845
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
846
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
847
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
848
				unset($conf["stringProcess::spiltString"]);
226 liveuser 849
 
3 liveuser 850
				#如果分割字串失敗
851
				if($spiltString["status"]==="false"){
226 liveuser 852
 
3 liveuser 853
					#設置執行失敗
854
					$result["status"]="false";
226 liveuser 855
 
3 liveuser 856
					#設置執行錯誤訊息
857
					$result["error"]=$spiltString;
226 liveuser 858
 
3 liveuser 859
					#回傳結果
860
					return $result;
226 liveuser 861
 
3 liveuser 862
					}#if end
226 liveuser 863
 
3 liveuser 864
				#如果剛好分割出一筆資料
865
				if($spiltString["dataCounts"]===1){
226 liveuser 866
 
3 liveuser 867
					#取得自己的id
868
					$myId=$from->resourceId;
226 liveuser 869
 
3 liveuser 870
					#取得講話對象的id
871
					$toId=$spiltString["dataArray"][0];
226 liveuser 872
 
3 liveuser 873
					#設置對象不存在的識別
874
					$targetExist=false;
226 liveuser 875
 
3 liveuser 876
					#設置通話對象的key
877
					$targetKey="";
226 liveuser 878
 
3 liveuser 879
					#如果要對話的對象存在
880
					if(isset($this->connInfo[$toId])){
226 liveuser 881
 
3 liveuser 882
						#取得對象的userId
883
						$toUserId=$this->connInfo[$toId]["userId"];
226 liveuser 884
 
3 liveuser 885
						#取得同userId的對象id們
226 liveuser 886
 
3 liveuser 887
						#初始化同userId的對象id
888
						$targetC=array();
226 liveuser 889
 
3 liveuser 890
						#針對每個連線
891
						foreach($this->connInfo as $eachIndex=>$eachInfo){
226 liveuser 892
 
3 liveuser 893
							#如果是自己
894
							if($eachIndex===$myId){
226 liveuser 895
 
3 liveuser 896
								#跳到下一輪
897
								continue;
226 liveuser 898
 
3 liveuser 899
								}#if end
226 liveuser 900
 
3 liveuser 901
							#如果是同userId的對象
902
							if($eachInfo["userId"]===$toUserId){
226 liveuser 903
 
3 liveuser 904
								#取出連線
905
								$targetC[$eachIndex]=$this->connInfo[$eachIndex];
226 liveuser 906
 
3 liveuser 907
								}#if end
226 liveuser 908
 
3 liveuser 909
							}#foreach end
226 liveuser 910
 
3 liveuser 911
						#針對每個同userId的連線
912
						foreach($targetC as $tcIndex=>$tcInfo){
226 liveuser 913
 
3 liveuser 914
							#檢查自己的對話對象是否已經在清單裡面了
226 liveuser 915
 
3 liveuser 916
							#假設對象可以加到自己對話清單裡面
917
							$add=true;
226 liveuser 918
 
3 liveuser 919
							#針對每個要講話的對象
920
							foreach($this->connInfo[$myId]["talkTo"] as $index=>$cInfo){
226 liveuser 921
 
3 liveuser 922
								#如果對話對象已經在清單裡面了
923
								if($this->connInfo[$tcIndex]["userId"]===$cInfo["userId"] && $tcIndex===$cInfo["id"]){
226 liveuser 924
 
3 liveuser 925
									#設置不要再加到清單裡面
926
									$add=false;
226 liveuser 927
 
3 liveuser 928
									#跳出foreach
929
									break;
226 liveuser 930
 
931
									}#if end
932
 
3 liveuser 933
								}#foreach end
226 liveuser 934
 
3 liveuser 935
							#如果要加入到對話清單裡面
936
							if($add){
226 liveuser 937
 
3 liveuser 938
								#增加自己的對話對象
939
								$this->connInfo[$myId]["talkTo"][]=array("id"=>$tcIndex,"userId"=>$this->connInfo[$tcIndex]["userId"]);
226 liveuser 940
 
3 liveuser 941
								#假設對方可以加自己到對話清單裡面
942
								$add=true;
226 liveuser 943
 
3 liveuser 944
								#檢查通話對象能否跟自己對話
945
								foreach($this->connInfo[$tcIndex]["talkTo"] as $index=>$cInfo){
226 liveuser 946
 
3 liveuser 947
									#如果對話對象已經在清單裡面了
948
									if($this->connInfo[$myId]["userId"]===$cInfo["userId"]){
226 liveuser 949
 
3 liveuser 950
										#設置不要再加到清單裡面
951
										$add=false;
226 liveuser 952
 
3 liveuser 953
										#跳出 foreach
954
										break;
226 liveuser 955
 
3 liveuser 956
										}#if end
226 liveuser 957
 
3 liveuser 958
									}#foreach end
226 liveuser 959
 
3 liveuser 960
								#如果對方可以加自己到對話清單裡面
961
								if($add){
226 liveuser 962
 
3 liveuser 963
									#讓通話對象也可以傳送訊息回來
964
									$this->connInfo[$tcIndex]["talkTo"][]=array("id"=>$myId,"userId"=>$this->connInfo[$myId]["userId"]);
226 liveuser 965
 
3 liveuser 966
									}#if end
226 liveuser 967
 
3 liveuser 968
								#設置要給自己看的訊息
969
								$from->send(json_encode("true"));
226 liveuser 970
 
3 liveuser 971
								}#if end
226 liveuser 972
 
3 liveuser 973
							#反之
974
							else{
226 liveuser 975
 
3 liveuser 976
								#設置要給自己看的訊息
977
								$from->send(json_encode("false"));
226 liveuser 978
 
3 liveuser 979
								}#else end
226 liveuser 980
 
3 liveuser 981
							}#foreach end
226 liveuser 982
 
3 liveuser 983
						#回傳成功
984
						return true;
226 liveuser 985
 
3 liveuser 986
						}#if end
226 liveuser 987
 
3 liveuser 988
					#反之不存在
989
					else{
226 liveuser 990
 
3 liveuser 991
						#設置要給自己看的訊息
992
						$from->send(json_encode("false"));
226 liveuser 993
 
3 liveuser 994
						#回傳成功
995
						return true;
226 liveuser 996
 
3 liveuser 997
						}#else end
226 liveuser 998
 
3 liveuser 999
					}#if end
226 liveuser 1000
 
3 liveuser 1001
				}#if end
226 liveuser 1002
 
3 liveuser 1003
			}#if end
226 liveuser 1004
 
3 liveuser 1005
		#如果有要講話的對象
1006
		if(count($this->connInfo[$from->resourceId]["talkTo"])>0){
226 liveuser 1007
 
3 liveuser 1008
			#依據每個對話對象
1009
			foreach($this->connInfo[$from->resourceId]["talkTo"] as $index => $cInfo){
226 liveuser 1010
 
3 liveuser 1011
				#如果要講話的對象不存在(socket已經斷開)
1012
				if(!isset($this->connInfo[$cInfo["id"]])){
226 liveuser 1013
 
3 liveuser 1014
					#將訊息儲存起來,等對象上線後再把訊息傳過去.
1015
					$this->unSendMsg[]=array(
1016
						"fromId"=>$from->resourceId,
1017
						"toId"=>"",
1018
						"fromUserId"=>$this->connInfo[$from->resourceId]["userId"],
1019
						"toUserId"=>$cInfo["userId"],
1020
						"msg"=>$msg
1021
						);
226 liveuser 1022
 
3 liveuser 1023
					}#if end
226 liveuser 1024
 
3 liveuser 1025
				#反之
1026
				else{
226 liveuser 1027
 
3 liveuser 1028
					#另存 ConnectionInterface 物件
1029
					$connObject=$this->connInfo[$cInfo["id"]]["conn"];
226 liveuser 1030
 
3 liveuser 1031
					#傳送訊息給對方
1032
					$snedResult=$connObject->send(json_encode($msg));
226 liveuser 1033
 
3 liveuser 1034
					}#else end
226 liveuser 1035
 
3 liveuser 1036
				}#foreach end
226 liveuser 1037
 
3 liveuser 1038
			}#if end
226 liveuser 1039
 
3 liveuser 1040
		#反之沒有講話的對象
1041
		else{
226 liveuser 1042
 
3 liveuser 1043
			#提示server訊息被拋棄
1044
			echo "Message 「".$msg."」 will not be received by any one";
226 liveuser 1045
 
3 liveuser 1046
			#設置要給自己看的訊息
1047
			$from->send(json_encode("false"));
226 liveuser 1048
 
3 liveuser 1049
			}#else end
226 liveuser 1050
 
3 liveuser 1051
		}#function onMessage end
1052
 
1053
	#當clinet的連線斷掉前
1054
	public function onClose(ConnectionInterface $conn){
226 liveuser 1055
 
3 liveuser 1056
		// The connection is closed, remove it, as we can no longer send it messages
1057
        	$this->clients->detach($conn);
1058
 
1059
        	echo "Connection {$conn->resourceId} has disconnected\n";
226 liveuser 1060
 
3 liveuser 1061
		#移除連線的資訊
1062
		unset($this->connInfo[$conn->resourceId]);
226 liveuser 1063
 
3 liveuser 1064
		}#function onClose end
1065
 
1066
	#當出現錯誤時
1067
    	public function onError(ConnectionInterface $conn, \Exception $e){
226 liveuser 1068
 
3 liveuser 1069
		echo "An error has occurred: {$e->getMessage()}\n";
1070
 
1071
        	$conn->close();
226 liveuser 1072
 
3 liveuser 1073
		}#fucntion onError end
226 liveuser 1074
 
3 liveuser 1075
	}#class Chat end
226 liveuser 1076
 
3 liveuser 1077
#用 ChatV2 類別來實作 MessageComponentInterface 界面,
1078
#改善了用戶網路斷掉但Server端不會將連線斷掉的問題
1079
#改善了用戶端網路恢復後無法收到之前未收到的訊息的問題
1080
class ChatV2 implements MessageComponentInterface{
226 liveuser 1081
 
3 liveuser 1082
	#初始化儲存使用者資訊的陣列
226 liveuser 1083
	private $connInfo=array();
1084
 
3 liveuser 1085
	#初始化儲存未傳送出去的留言訊息
1086
	#"fromId",訊息來源的id
1087
	#"toId",訊息目的的id
1088
	#"fromUserId",訊息來源的userId
1089
	#"toUserId",訊息目標的userId
1090
	#"msg",傳送的訊息
1091
	private $unSendMsg=array();
226 liveuser 1092
 
3 liveuser 1093
	#初始化儲存待確認是否送達到對方的訊息
1094
	#$unConfirmMsg[$id],$id為訊息接收方,亦即收到訊息後,要跟server說有收到訊息者.
1095
	#"fromId",訊息來源的id
1096
	#"toId",訊息目的的id
1097
	#"fromUserId",訊息來源的userId
1098
	#"toUserId",訊息目標的userId
1099
	#"msg",傳送的訊息
1100
	private $unConfirmMsg=array();
226 liveuser 1101
 
3 liveuser 1102
	#初始化一開始尚未能夠連線到資料庫
1103
	private static $dbTouchable=false;
226 liveuser 1104
 
3 liveuser 1105
	#初始化db的位置
226 liveuser 1106
	public static $dbAddress="localhost";
1107
 
3 liveuser 1108
	#初始化連線db用的帳戶
1109
	public static $dbAccount="root";
226 liveuser 1110
 
3 liveuser 1111
	#初始化連線的db名稱
1112
	public static $dbName="test";
226 liveuser 1113
 
3 liveuser 1114
	#初始化連線db時用的密碼
1115
	public static $dbPassword="";
226 liveuser 1116
 
3 liveuser 1117
	#初始化連線db的哪個資料表
1118
	public static $memberTableName="member";
226 liveuser 1119
 
3 liveuser 1120
	#初始化登入時用來驗證帳號的資料表欄位名稱
1121
	public static $accountCol="account";
226 liveuser 1122
 
3 liveuser 1123
	#初始化登入時用來驗證密碼的資料表欄位名稱,設為""代表不用密碼來認證
1124
	public static $passwordCol="password";
226 liveuser 1125
 
3 liveuser 1126
	#建構子
1127
	public function __construct(){
226 liveuser 1128
 
3 liveuser 1129
		#如果尚未可以上資料庫
1130
		if(!(self::$dbTouchable)){
226 liveuser 1131
 
3 liveuser 1132
			#嘗試連線到目標資料庫.資料表
1133
			#涵式說明:
1134
			#一次取得資料庫、表的資料
1135
			#回傳的結果
1136
			#$result["status"],執行結果"true"為成功;"false"為執行失敗。
1137
			#$result["error"],錯誤訊息陣列。
1138
			#$result["function"],當前執行的漢書名稱.
1139
			#$result["dataColumnName"],抓取的資料欄位名稱陣列.
1140
				#$result["dataColumnName"][$i]代表第$i+1個欄位名稱
1141
			#$result["dataContent"],爲資料的內容。
1142
			#$result["dataContent"][$conf["WhereColumnName"][$i]][$dataSetNum]
1143
				#$dataSetNum 爲第$dataSetNum+1筆資料
1144
				#$conf["WhereColumnName"][$i] 爲第 $i+1 個欄位的名稱
1145
			#$result["dataCount"],爲取得的資料筆數。
1146
			#$result["sql"],執行的sql字串.
1147
			#必填的參數:
1148
			$conf["db::fastGetDbData"]["dbAddress"]=self::$dbAddress;#爲dbServer的位置。
1149
			$conf["db::fastGetDbData"]["dbAccount"]=self::$dbAccount;#爲登入dbServer的帳號。
1150
			$conf["db::fastGetDbData"]["dbName"]=self::$dbName;#爲要存取的資料庫名稱
1151
			$conf["db::fastGetDbData"]["tableName"]=self::$memberTableName;#爲要存取的資料表名稱
1152
			$conf["db::fastGetDbData"]["columnYouWant"]=array("id",self::$accountCol);#你想要的欄位!,若設為「array("*")」則代表全部欄位.
226 liveuser 1153
 
3 liveuser 1154
			#如果 $passwordCol 不為空
1155
			if(self::$passwordCol!=""){
226 liveuser 1156
 
3 liveuser 1157
				#加上密碼欄位
1158
				$conf["db::fastGetDbData"]["columnYouWant"][]=self::$passwordCol;
226 liveuser 1159
 
3 liveuser 1160
				}#if end
226 liveuser 1161
 
3 liveuser 1162
			#可省略的參數:
1163
			$conf["db::fastGetDbData"]["dbPassword"]=self::$dbPassword;#爲要存取dbServer的密碼
1164
			#$conf["db::fastGetDbData"]["WhereColumnName"]=array("account","password");#用於判斷語句的欄位項目陣列。
1165
			#$conf["db::fastGetDbData"]["WhereColumnValue"]=array($ac,$pw);#用於判斷語句的欄位數值陣列,若與LIKE搭配,則可以在關鍵自字串的左右名加上「%」符號,這樣就可以搜尋具有該字串的內容。
1166
			#$conf["WhereColumnCombine"]=array("");#用於判斷語句當中需要()起來的判斷式,須爲陣列值,"s"代表「(」,"e"代表「)」 ,若無則須設爲""。
1167
			#$conf["WhereColumnOperator"]=array("");#用於判斷語句的比較符號陣列,可以用的符號有「"="、"!="、">"、"<"、"LIKE"、"NOT LIKE"」,預設都爲「=」。
1168
			#$conf["WhereColumnAndOr"]=array("");#用於判斷語句條件之間成立的條件是AND還是OR,須爲陣列值。其數量應爲要判斷的欄位數量減一。
1169
			#$conf["orderItem"]="";#爲排序的項目依據,若要用隨機抽樣,可以用"rand()",可省略。
1170
			#$conf["ascORdesc"]="";#爲要低增還是遞減排序,asc爲遞增;desc爲遞減。
1171
			#$conf["numberStart"]="0";#為從第幾筆開始讀取,預設為0,代筆第一筆。
1172
			$conf["db::fastGetDbData"]["numLimit"]="1";#為要取幾筆資料,可以省略,省略則表示不限制數目。
1173
			#$conf["groupBy"]=array("");#爲要以哪幾個欄爲作爲分羣的依據(欄位相同的數值僅會取出一筆)。
1174
			#備註:
1175
			#建議在查詢資料前,能夠檢查是否每個欄位都存在.
1176
			$fastGetDbData=db::fastGetDbData($conf["db::fastGetDbData"]);
1177
			unset($conf["db::fastGetDbData"]);
226 liveuser 1178
 
3 liveuser 1179
			#如果取得資料失敗
1180
			if($fastGetDbData["status"]==="false"){
226 liveuser 1181
 
3 liveuser 1182
				#設置執行失敗
1183
				$result["status"]="false";
226 liveuser 1184
 
3 liveuser 1185
				#設置執行錯誤訊息
1186
				$result["error"]=$fastGetDbData;
226 liveuser 1187
 
3 liveuser 1188
				#印出debug訊息
1189
				var_dump($result);
226 liveuser 1190
 
3 liveuser 1191
				#結束程式
1192
				exit;
226 liveuser 1193
 
3 liveuser 1194
				}#if end
226 liveuser 1195
 
3 liveuser 1196
			#連線成功,將self::dbTouchable設為true
1197
			self::$dbTouchable=true;
226 liveuser 1198
 
3 liveuser 1199
			}#if end
226 liveuser 1200
 
3 liveuser 1201
		$this->clients = new \SplObjectStorage;
226 liveuser 1202
 
3 liveuser 1203
		}#funciton __construct end
226 liveuser 1204
 
3 liveuser 1205
	#當用戶與伺服器建立連線時
1206
	public function onOpen(ConnectionInterface $conn){
226 liveuser 1207
 
3 liveuser 1208
		// Store the new connection to send messages to later
1209
        	$this->clients->attach($conn);
1210
 
1211
		#提示server有clent連上web socket.
1212
        	echo "New connection! ({$conn->resourceId})\n";
226 liveuser 1213
 
3 liveuser 1214
 		#用client的id為index來儲存額外的資訊
1215
 		#元素 "conn" 代表已經建立連線的ConnectionInterface物件
1216
        	#元素 "talkTo" 代表要跟誰講話
1217
		#元素 "userId" 代表辨識使用者的id
1218
		#元素 "loigin=array("ac","pw")" 代表client輸入的帳號與密碼
1219
		#元素 "msgId" 為用來識別待確認訊息的索引
1220
		#元素 "gotMsgId" 為用來識別是否已經設置過 msgId 了
1221
 		#$this->connInfo[$conn->resourceId]=array("conn"=>$conn,"talkTo"=>array(),"userId"=>"","login"=>array("ac"=>"","pw"=>""),"type"=>"");
1222
        	$this->connInfo[$conn->resourceId]=array("conn"=>$conn,"talkTo"=>array(),"userId"=>"","login"=>array("ac"=>"","pw"=>""),"msgId"=>"","gotMsgId"=>"false");
226 liveuser 1223
 
3 liveuser 1224
		#包裝訊息
226 liveuser 1225
		#"type"為"login"
1226
		#"status"為"true"
3 liveuser 1227
		#"data"為實際的訊息內容
1228
		$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your account! ex:account:ws1");
226 liveuser 1229
 
1230
		#提示輸入帳號
3 liveuser 1231
		$conn->send(json_encode($packedMsg));
226 liveuser 1232
 
3 liveuser 1233
		}#function onOpen end
1234
 
1235
	#當伺服器收到訊息時
1236
	public function onMessage(ConnectionInterface $from, $msg){
226 liveuser 1237
 
3 liveuser 1238
		#debug
1239
		#$array=array("msgId"=>$this->connInfo[$from->resourceId]["msgId"],"resourceId"=>$from->resourceId,"msg"=>$msg);
1240
		#var_dump($array);
226 liveuser 1241
 
3 liveuser 1242
		#如果該連線沒有使用者id
1243
		if($this->connInfo[$from->resourceId]["userId"]===""){
226 liveuser 1244
 
3 liveuser 1245
			#代表需要認證,認證的會員資料表 slef::memberTableName,需要以下三個欄位.
1246
			#id		自訂
1247
			#account  	自訂
1248
			#password varchar(33)
226 liveuser 1249
 
3 liveuser 1250
			/*
226 liveuser 1251
 
3 liveuser 1252
			#如果尚未輸入用戶端類型
1253
			if($this->connInfo[$from->resourceId]["type"]===""){
226 liveuser 1254
 
3 liveuser 1255
				#如果 $msg 長度大於 "type:"
1256
				if(strlen($msg) > strlen("type:")){
226 liveuser 1257
 
3 liveuser 1258
					#檢查有無前置字元 "account:"
1259
					#函式說明:
1260
					#將字串特定關鍵字與其前面的內容剔除
1261
					#回傳結果:
1262
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1263
					#$result["error"],錯誤訊息陣列.
1264
					#$result["warning"],警告訊息鎮列.
1265
					#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
1266
					#$result["function"],當前執行的函數名稱.
1267
					#$result["oriStr"],要處理的原始字串內容.
1268
					#$result["content"],處理好的的字串內容.
1269
					#必填的參數:
1270
					$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$msg;#要處理的字串.
1271
					$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="type:";#特定字串.
1272
					$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
1273
					unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 1274
 
3 liveuser 1275
					#如果移除前置字元失敗
1276
					if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 1277
 
3 liveuser 1278
						#設置執行失敗
1279
						$result["status"]="false";
226 liveuser 1280
 
3 liveuser 1281
						#設置執行錯誤訊息
1282
						$result["error"]=$delStrBeforeKeyWord;
226 liveuser 1283
 
3 liveuser 1284
						#回傳結果
1285
						return $result;
226 liveuser 1286
 
3 liveuser 1287
						}#if end
226 liveuser 1288
 
3 liveuser 1289
					#如果有符合條件的前置字元
1290
					if($delStrBeforeKeyWord["founded"]==="true"){
226 liveuser 1291
 
3 liveuser 1292
						#儲存用戶端類型
1293
						$this->connInfo[$from->resourceId]["type"]=$delStrBeforeKeyWord["content"];
226 liveuser 1294
 
3 liveuser 1295
						}#if end
226 liveuser 1296
 
3 liveuser 1297
					#反之
1298
					else{
226 liveuser 1299
 
3 liveuser 1300
						#提示輸入用戶端類型
1301
						$from->send(json_encode("Please input your type! ex:type:user"));
226 liveuser 1302
 
3 liveuser 1303
						#結束程式
1304
						return true;
226 liveuser 1305
 
3 liveuser 1306
						}#else end
226 liveuser 1307
 
3 liveuser 1308
					}#if end
226 liveuser 1309
 
3 liveuser 1310
				#反之代表輸入錯誤格式的type
1311
				else{
226 liveuser 1312
 
3 liveuser 1313
					#提示輸入用戶端類型
1314
					$from->send(json_encode("Please input your type! ex:type:user"));
226 liveuser 1315
 
3 liveuser 1316
					#結束程式
1317
					return true;
226 liveuser 1318
 
3 liveuser 1319
					}#else end
226 liveuser 1320
 
3 liveuser 1321
				}#if end
226 liveuser 1322
 
3 liveuser 1323
			#如果用戶端是"user"
1324
			if($this->connInfo[$from->resourceId]["type"]==="user"){
226 liveuser 1325
 
3 liveuser 1326
				#...
226 liveuser 1327
 
3 liveuser 1328
				}#if end
226 liveuser 1329
 
3 liveuser 1330
			#反之如果用戶端是"device"
1331
			else if($this->connInfo[$from->resourceId]["type"]==="device"){
226 liveuser 1332
 
3 liveuser 1333
				#...
226 liveuser 1334
 
3 liveuser 1335
				}#if end
226 liveuser 1336
 
3 liveuser 1337
			*/
226 liveuser 1338
 
3 liveuser 1339
			#如果尚未輸入帳戶
1340
			if($this->connInfo[$from->resourceId]["login"]["ac"]===""){
226 liveuser 1341
 
3 liveuser 1342
				#如果 $msg 長度大於 "account:"
1343
				if(strlen($msg) > strlen("account:")){
226 liveuser 1344
 
3 liveuser 1345
					#檢查有無前置字元 "account:"
1346
					#函式說明:
1347
					#將字串特定關鍵字與其前面的內容剔除
1348
					#回傳結果:
1349
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1350
					#$result["error"],錯誤訊息陣列.
1351
					#$result["warning"],警告訊息鎮列.
1352
					#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
1353
					#$result["function"],當前執行的函數名稱.
1354
					#$result["oriStr"],要處理的原始字串內容.
1355
					#$result["content"],處理好的的字串內容.
1356
					#必填的參數:
1357
					$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$msg;#要處理的字串.
1358
					$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="account:";#特定字串.
1359
					$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
1360
					unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 1361
 
3 liveuser 1362
					#如果移除前置字元失敗
1363
					if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 1364
 
3 liveuser 1365
						#設置執行失敗
1366
						$result["status"]="false";
226 liveuser 1367
 
3 liveuser 1368
						#設置執行錯誤訊息
1369
						$result["error"]=$delStrBeforeKeyWord;
226 liveuser 1370
 
3 liveuser 1371
						#回傳結果
1372
						return $result;
226 liveuser 1373
 
3 liveuser 1374
						}#if end
226 liveuser 1375
 
3 liveuser 1376
					#如果有符合條件的前置字元
1377
					if($delStrBeforeKeyWord["founded"]==="true"){
226 liveuser 1378
 
3 liveuser 1379
						#儲存帳戶
1380
						$this->connInfo[$from->resourceId]["login"]["ac"]=$delStrBeforeKeyWord["content"];
226 liveuser 1381
 
3 liveuser 1382
						}#if end
226 liveuser 1383
 
1384
					#反之代表格式錯誤
3 liveuser 1385
					else{
226 liveuser 1386
 
3 liveuser 1387
						#包裝訊息
226 liveuser 1388
						#"type"為"login"
1389
						#"status"為"true"
3 liveuser 1390
						#"data"為實際的訊息內容
1391
						$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your account! ex:account:ws1");
226 liveuser 1392
 
1393
						#提示輸入帳號
3 liveuser 1394
						$from->send(json_encode($packedMsg));
226 liveuser 1395
 
3 liveuser 1396
						#結束程式
1397
						return true;
226 liveuser 1398
 
3 liveuser 1399
						}#else end
226 liveuser 1400
 
3 liveuser 1401
					}#if end
226 liveuser 1402
 
3 liveuser 1403
				#反之代表輸入錯誤格式的account
1404
				else{
226 liveuser 1405
 
3 liveuser 1406
					#包裝訊息
226 liveuser 1407
					#"type"為"login"
1408
					#"status"為"true"
3 liveuser 1409
					#"data"為實際的訊息內容
1410
					$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your account! ex:account:ws1");
226 liveuser 1411
 
1412
					#提示輸入帳號
3 liveuser 1413
					$from->send(json_encode($packedMsg));
226 liveuser 1414
 
3 liveuser 1415
					#結束程式
1416
					return true;
226 liveuser 1417
 
3 liveuser 1418
					}#else end
226 liveuser 1419
 
3 liveuser 1420
				}#if end
226 liveuser 1421
 
3 liveuser 1422
			#如果有設置密碼欄位
1423
			if(self::$passwordCol!==""){
226 liveuser 1424
 
3 liveuser 1425
				#如果尚未輸入密碼
1426
				if($this->connInfo[$from->resourceId]["login"]["pw"]===""){
226 liveuser 1427
 
3 liveuser 1428
					#$msg 長度大於 "password:"
1429
					if(strlen($msg) > strlen("password:")){
226 liveuser 1430
 
3 liveuser 1431
						#檢查有無前置字元 "password:"
1432
						#函式說明:
1433
						#將字串特定關鍵字與其前面的內容剔除
1434
						#回傳結果:
1435
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1436
						#$result["error"],錯誤訊息陣列.
1437
						#$result["warning"],警告訊息鎮列.
1438
						#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
1439
						#$result["function"],當前執行的函數名稱.
1440
						#$result["oriStr"],要處理的原始字串內容.
1441
						#$result["content"],處理好的的字串內容.
1442
						#必填的參數:
1443
						$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$msg;#要處理的字串.
1444
						$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="password:";#特定字串.
1445
						$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
1446
						unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 1447
 
3 liveuser 1448
						#如果移除前置字元失敗
1449
						if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 1450
 
3 liveuser 1451
							#設置執行失敗
1452
							$result["status"]="false";
226 liveuser 1453
 
3 liveuser 1454
							#設置執行錯誤訊息
1455
							$result["error"]=$delStrBeforeKeyWord;
226 liveuser 1456
 
3 liveuser 1457
							#回傳結果
1458
							return $result;
226 liveuser 1459
 
3 liveuser 1460
							}#if end
226 liveuser 1461
 
3 liveuser 1462
						#如果有符合條件的前置字元
1463
						if($delStrBeforeKeyWord["founded"]==="true"){
226 liveuser 1464
 
3 liveuser 1465
							#儲存密碼
1466
							$this->connInfo[$from->resourceId]["login"]["pw"]=$delStrBeforeKeyWord["content"];
226 liveuser 1467
 
3 liveuser 1468
							}#if end
226 liveuser 1469
 
3 liveuser 1470
						#反之代表格式錯誤
1471
						else{
226 liveuser 1472
 
3 liveuser 1473
							#包裝訊息
226 liveuser 1474
							#"type"為"login"
1475
							#"status"為"true"
3 liveuser 1476
							#"data"為實際的訊息內容
1477
							$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your password! ex:password:ws1");
226 liveuser 1478
 
1479
							#提示輸入密碼
3 liveuser 1480
							$from->send(json_encode($packedMsg));
226 liveuser 1481
 
3 liveuser 1482
							#結束程式
1483
							return true;
226 liveuser 1484
 
3 liveuser 1485
							}#else end
226 liveuser 1486
 
3 liveuser 1487
						}#if end
226 liveuser 1488
 
3 liveuser 1489
					#反之代表格式錯誤
1490
					else{
226 liveuser 1491
 
3 liveuser 1492
						#包裝訊息
226 liveuser 1493
						#"type"為"login"
1494
						#"status"為"true"
3 liveuser 1495
						#"data"為實際的訊息內容
1496
						$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your password! ex:password:ws1");
226 liveuser 1497
 
1498
						#提示輸入密碼
3 liveuser 1499
						$from->send(json_encode($packedMsg));
226 liveuser 1500
 
3 liveuser 1501
						#結束程式
1502
						return true;
226 liveuser 1503
 
3 liveuser 1504
						}#else end
226 liveuser 1505
 
3 liveuser 1506
					}#if end
226 liveuser 1507
 
3 liveuser 1508
				}#if end
226 liveuser 1509
 
3 liveuser 1510
			#如果已經輸入帳號了
1511
			if($this->connInfo[$from->resourceId]["login"]["ac"]!=""){
226 liveuser 1512
 
3 liveuser 1513
				#設置可以進行驗證
1514
				$startAuth=true;
226 liveuser 1515
 
3 liveuser 1516
				#另存帳號
1517
				$ac=$this->connInfo[$from->resourceId]["login"]["ac"];
226 liveuser 1518
 
3 liveuser 1519
				#初始化密碼
1520
				$pw="";
226 liveuser 1521
 
3 liveuser 1522
				#如果有設置密碼欄位
1523
				if(self::$passwordCol!==""){
226 liveuser 1524
 
3 liveuser 1525
					#如果client已經輸入密碼了
1526
					if($this->connInfo[$from->resourceId]["login"]["pw"]!=""){
226 liveuser 1527
 
3 liveuser 1528
						#另存密碼
1529
						$pw=md5($this->connInfo[$from->resourceId]["login"]["pw"]);
226 liveuser 1530
 
3 liveuser 1531
						}#if end
226 liveuser 1532
 
3 liveuser 1533
					#反之
1534
					else{
226 liveuser 1535
 
3 liveuser 1536
						#設置尚不能進行認證
1537
						$startAuth=false;
226 liveuser 1538
 
3 liveuser 1539
						}#else end
226 liveuser 1540
 
3 liveuser 1541
					}#if end
226 liveuser 1542
 
3 liveuser 1543
				#如果尚不能進行驗證
1544
				if(!$startAuth){
226 liveuser 1545
 
3 liveuser 1546
					#結束程式
1547
					return true;
226 liveuser 1548
 
3 liveuser 1549
					}#if end
226 liveuser 1550
 
3 liveuser 1551
				#檢查有無符合的帳戶密碼
1552
				#涵式說明:
1553
				#一次取得資料庫、表的資料
1554
				#回傳的結果
1555
				#$result["status"],執行結果"true"為成功;"false"為執行失敗。
1556
				#$result["error"],錯誤訊息陣列。
1557
				#$result["function"],當前執行的漢書名稱.
1558
				#$result["dataColumnName"],抓取的資料欄位名稱陣列.
1559
					#$result["dataColumnName"][$i]代表第$i+1個欄位名稱
1560
				#$result["dataContent"],爲資料的內容。
1561
				#$result["dataContent"][$conf["WhereColumnName"][$i]][$dataSetNum]
1562
					#$dataSetNum 爲第$dataSetNum+1筆資料
1563
					#$conf["WhereColumnName"][$i] 爲第 $i+1 個欄位的名稱
1564
				#$result["dataCount"],爲取得的資料筆數。
1565
				#$result["sql"],執行的sql字串.
1566
				#必填的參數:
1567
				$conf["db::fastGetDbData"]["dbAddress"]=self::$dbAddress;#爲dbServer的位置。
1568
				$conf["db::fastGetDbData"]["dbAccount"]=self::$dbAccount;#爲登入dbServer的帳號。
1569
				$conf["db::fastGetDbData"]["dbName"]=self::$dbName;#爲要存取的資料庫名稱
1570
				$conf["db::fastGetDbData"]["tableName"]=self::$memberTableName;#爲要存取的資料表名稱
1571
				$conf["db::fastGetDbData"]["columnYouWant"]=array("id");#你想要的欄位!,若設為「array("*")」則代表全部欄位.
1572
				#可省略的參數:
1573
				$conf["db::fastGetDbData"]["dbPassword"]=self::$dbPassword;#爲要存取dbServer的密碼
1574
				$conf["db::fastGetDbData"]["WhereColumnName"]=array(self::$accountCol);#用於判斷語句的欄位項目陣列。
1575
				$conf["db::fastGetDbData"]["WhereColumnValue"]=array($ac);#用於判斷語句的欄位數值陣列,若與LIKE搭配,則可以在關鍵自字串的左右名加上「%」符號,這樣就可以搜尋具有該字串的內容。
226 liveuser 1576
 
3 liveuser 1577
				#如果有輸入密碼
1578
				if($pw!==""){
226 liveuser 1579
 
3 liveuser 1580
					#新增要判斷 self::$password 欄位,是否有於 $pw
1581
					$conf["db::fastGetDbData"]["WhereColumnName"][]=self::$passwordCol;
1582
					$conf["db::fastGetDbData"]["WhereColumnValue"][]=$pw;
226 liveuser 1583
 
3 liveuser 1584
					}#if end
226 liveuser 1585
 
3 liveuser 1586
				#$conf["WhereColumnCombine"]=array("");#用於判斷語句當中需要()起來的判斷式,須爲陣列值,"s"代表「(」,"e"代表「)」 ,若無則須設爲""。
1587
				#$conf["WhereColumnOperator"]=array("");#用於判斷語句的比較符號陣列,可以用的符號有「"="、"!="、">"、"<"、"LIKE"、"NOT LIKE"」,預設都爲「=」。
1588
				#$conf["WhereColumnAndOr"]=array("");#用於判斷語句條件之間成立的條件是AND還是OR,須爲陣列值。其數量應爲要判斷的欄位數量減一。
1589
				#$conf["orderItem"]="";#爲排序的項目依據,若要用隨機抽樣,可以用"rand()",可省略。
1590
				#$conf["ascORdesc"]="";#爲要低增還是遞減排序,asc爲遞增;desc爲遞減。
1591
				#$conf["numberStart"]="0";#為從第幾筆開始讀取,預設為0,代筆第一筆。
1592
				$conf["db::fastGetDbData"]["numLimit"]="1";#為要取幾筆資料,可以省略,省略則表示不限制數目。
1593
				#$conf["groupBy"]=array("");#爲要以哪幾個欄爲作爲分羣的依據(欄位相同的數值僅會取出一筆)。
1594
				#備註:
1595
				#建議在查詢資料前,能夠檢查是否每個欄位都存在.
1596
				$fastGetDbData=db::fastGetDbData($conf["db::fastGetDbData"]);
1597
				unset($conf["db::fastGetDbData"]);
226 liveuser 1598
 
3 liveuser 1599
				#如果取得資料失敗
1600
				if($fastGetDbData["status"]==="false"){
226 liveuser 1601
 
3 liveuser 1602
					#設置執行失敗
1603
					$result["status"]="false";
226 liveuser 1604
 
3 liveuser 1605
					#設置執行錯誤訊息
226 liveuser 1606
					$result["error"]=$fastGetDbData;
1607
 
3 liveuser 1608
					#提示server有資料庫錯誤
1609
					echo "dbError!";
226 liveuser 1610
 
3 liveuser 1611
					#結束程式
1612
					exit;
226 liveuser 1613
 
3 liveuser 1614
					}#if end
226 liveuser 1615
 
3 liveuser 1616
				#如果沒有一筆資料
1617
				if($fastGetDbData["dataCount"]!==1){
226 liveuser 1618
 
3 liveuser 1619
					#代表登入失敗
226 liveuser 1620
 
3 liveuser 1621
					#清空登入用的帳戶
1622
					$this->connInfo[$from->resourceId]["login"]["ac"]="";
226 liveuser 1623
 
3 liveuser 1624
					#清空登入用的密碼
1625
					$this->connInfo[$from->resourceId]["login"]["pw"]="";
226 liveuser 1626
 
3 liveuser 1627
					#包裝訊息
226 liveuser 1628
					#"type"為"login"
1629
					#"status"為"false"
3 liveuser 1630
					#"data"為實際的訊息內容
1631
					$packedMsg=array("type"=>"login","status"=>"false","data"=>"Login failed, please input account. ex:account:ws1");
226 liveuser 1632
 
1633
					#提示登入失敗
3 liveuser 1634
					$from->send(json_encode($packedMsg));
226 liveuser 1635
 
3 liveuser 1636
					#執行到這即可
1637
					return true;
226 liveuser 1638
 
3 liveuser 1639
					}#if end
226 liveuser 1640
 
3 liveuser 1641
				#反之代表帳戶資訊正確
1642
				else{
226 liveuser 1643
 
3 liveuser 1644
					#設置 $myUserId
1645
					$myUserId=$this->connInfo[$from->resourceId]["userId"]=$fastGetDbData["dataContent"]["id"][0];
226 liveuser 1646
 
3 liveuser 1647
					#設置 $myId
1648
					$myId=$from->resourceId;
226 liveuser 1649
 
3 liveuser 1650
					#初始化msgId的部份內容
1651
					$msgId=$myUserId."-";
226 liveuser 1652
 
3 liveuser 1653
					#初始化儲存msgId的陣列
1654
					$msgIdArray=array();
226 liveuser 1655
 
3 liveuser 1656
					#取得所有client的msgId
1657
					foreach($this->connInfo as $clientInfoArray){
226 liveuser 1658
 
3 liveuser 1659
						#如果msgId不為""
1660
						if($clientInfoArray["msgId"]!==""){
226 liveuser 1661
 
3 liveuser 1662
							#取得msgId
1663
							$msgIdArray[]=$clientInfoArray["msgId"];
226 liveuser 1664
 
3 liveuser 1665
							}#if end
226 liveuser 1666
 
3 liveuser 1667
						}#foreach end
226 liveuser 1668
 
3 liveuser 1669
					#如果尚未產生完整的msgId或msgId有重複
1670
					while($msgId===$myUserId."-" || in_array($msgId,$msgIdArray)){
226 liveuser 1671
 
3 liveuser 1672
						#涵式說明:
1673
						#建立以圖片(PNG格式)呈現的驗證碼.
1674
						#回傳的解果:
1675
						#$result["status"],執行是否正常,"true"代表執行成功,"false"代表執行失敗.
1676
						#$result["error"],錯誤訊息.
1677
						#$result["function"],檔前執行的函數名稱.
1678
						#$result["randNumberWord"],傳驗證碼的內容.
1679
						#$result["imgAddress"],圖片的位置與名稱.
1680
						#必填的參數:
1681
						#$conf["imgAddressAndName"],字串,爲驗證碼圖片儲存的位置與名稱,副檔名程式會自動產生
1682
						$conf["authenticate::validationCode"]["imgAddressAndName"]="no used!";
1683
						#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
1684
						$conf["authenticate::validationCode"]["fileArgu"]="no used!";
1685
						#可省略的參數:
1686
						#$conf["num"],字串,爲驗證碼的位數,請輸入阿拉伯數字,預設為"8"位數.
1687
						#$conf["num"]="8";
1688
						#$conf["disableImg"],字串,是否要取消驗證碼圖片的輸出,"true"為要取消,預設為"false"為不取消
1689
						$conf["authenticate::validationCode"]["disableImg"]="true";
1690
						#$conf["imgToData"],字串,預設為"true"代表將圖片轉存成base64圖片,並將原始圖片移除;反之為"false"
1691
						#$conf["imgToData"]="true";
1692
						$validationCode=authenticate::validationCode($conf["authenticate::validationCode"]);
1693
						unset($conf["authenticate::validationCode"]);
226 liveuser 1694
 
3 liveuser 1695
						#如果產生亂數失敗
1696
						if($validationCode["status"]==="false"){
226 liveuser 1697
 
3 liveuser 1698
							#設置錯誤狀態
1699
							$result["status"]="false";
226 liveuser 1700
 
3 liveuser 1701
							#設置錯誤提示
1702
							$result["error"]=$validationCode;
226 liveuser 1703
 
3 liveuser 1704
							#印出錯誤訊息
1705
							var_dump($result);
226 liveuser 1706
 
1707
							#回傳結果
1708
							return $result;
1709
 
3 liveuser 1710
							}#if end
226 liveuser 1711
 
1712
						#儲存產生好的msgId
3 liveuser 1713
						$msgId=$myUserId."-".$validationCode["randNumberWord"];
226 liveuser 1714
 
3 liveuser 1715
						}#while end
226 liveuser 1716
 
3 liveuser 1717
					#設置獨立於id與userId且用於驗證訊息是否收到的msgId
1718
					$this->connInfo[$from->resourceId]["msgId"]=$msgId;
226 liveuser 1719
 
3 liveuser 1720
					#包裝訊息
226 liveuser 1721
					#"type"為"login"
1722
					#"status"為"true"
3 liveuser 1723
					#"data"為實際的訊息內容
1724
					$packedMsg=array("type"=>"login","status"=>"true","data"=>"Login successfully!");
226 liveuser 1725
 
3 liveuser 1726
					#提示登入成功
1727
					$from->send(json_encode($packedMsg));
226 liveuser 1728
 
3 liveuser 1729
					#檢查是否有訊息是要給自己的
1730
					foreach($this->unSendMsg as $index => $historyMsg){
226 liveuser 1731
 
3 liveuser 1732
						#如果有要給自己的訊息
1733
						if($myUserId===$historyMsg["toUserId"]){
226 liveuser 1734
 
3 liveuser 1735
							#包裝訊息
226 liveuser 1736
							#"type"為"unSendMsg?"
1737
							#"status"為"true"
3 liveuser 1738
							#"data"為實際的訊息內容
1739
							$packedMsg=array("type"=>"unSendMsg?","status"=>"true","data"=>$historyMsg["msg"]);
226 liveuser 1740
 
3 liveuser 1741
							#接收別人給的留言
1742
							$from->send(json_encode($packedMsg));
226 liveuser 1743
 
3 liveuser 1744
							#有幾個人在線上就執行幾次
1745
							foreach($this->connInfo as $toId => $cInfo){
226 liveuser 1746
 
3 liveuser 1747
								#如果是自己
1748
								if($myId===$toId ){
226 liveuser 1749
 
3 liveuser 1750
									#跳過
1751
									continue;
226 liveuser 1752
 
3 liveuser 1753
									}#if end
226 liveuser 1754
 
3 liveuser 1755
								#如果留言的對象有在線上
1756
								if($historyMsg["fromUserId"]===$cInfo["userId"]){
226 liveuser 1757
 
3 liveuser 1758
									#檢查對方是否已經在自己的通話清單裡面了
226 liveuser 1759
 
3 liveuser 1760
									#初始化要將對方加到自己的對話清單裡面
1761
									$add=false;
226 liveuser 1762
 
3 liveuser 1763
									#根據自己的每個通話對象
1764
									foreach($this->connInfo[$myId]["talkTo"] as $myToIndex=>$myToCinfo ){
226 liveuser 1765
 
3 liveuser 1766
										#如果對對方已經存在於自己的對話清單裡面了
1767
										if($myToCinfo["userId"]===$historyMsg["fromUserId"] && $myId===$historyMsg["fromId"]){
226 liveuser 1768
 
3 liveuser 1769
											#設置不要將對方加到自己的對話清單裡面
1770
											$add=false;
226 liveuser 1771
 
3 liveuser 1772
											#跳出foreach
1773
											break;
226 liveuser 1774
 
3 liveuser 1775
											}#if end
226 liveuser 1776
 
3 liveuser 1777
										}#foreach end
226 liveuser 1778
 
3 liveuser 1779
									#如果要將對方加到自己的對話清單裡面
1780
									if($add){
226 liveuser 1781
 
3 liveuser 1782
										#將對方加到自己的talkTo清單裡面
1783
										$this->connInfo[$myId]["talkTo"][]=array("id"=>$toId,"userId"=>$historyMsg["fromUserId"],"msgId"=>$this->connInfo[$toId]["msgId"]);
226 liveuser 1784
 
3 liveuser 1785
										}#if end
226 liveuser 1786
 
3 liveuser 1787
									#檢查自己有沒有在對方talkTo清單裡面
226 liveuser 1788
 
3 liveuser 1789
									#假設對方需要加自己到對話清單裡面
1790
									$add=true;
226 liveuser 1791
 
3 liveuser 1792
									#檢查通話對象能否跟自己對話
226 liveuser 1793
 
3 liveuser 1794
									#依據對方每個通話的對象
1795
									foreach($this->connInfo[$toId]["talkTo"] as $talkToIndex=>$talkToCinfo){
226 liveuser 1796
 
3 liveuser 1797
										#如果自己的userId已經在對方的對話清單裡面了
1798
										if($myUserId===$talkToCinfo["userId"]){
226 liveuser 1799
 
3 liveuser 1800
											#如果對方對話userId對應的id不在線上
1801
											if(!isset($this->connInfo[$toId])){
226 liveuser 1802
 
3 liveuser 1803
												#debug
226 liveuser 1804
												#var_dump("對方對話userId(".$talkToCinfo["userId"].")應的id(".$toId.")不在線上");
1805
 
3 liveuser 1806
												#檢查對方對話清單是否已經含有自己的id與userId了
226 liveuser 1807
 
3 liveuser 1808
												#假設對方對話清單沒有自己的id與userId
1809
												$update=true;
226 liveuser 1810
 
3 liveuser 1811
												#依據對方每個通話的對象
1812
												foreach($this->connInfo[$toId]["talkTo"] as $ceToIndex=>$ceToCinfo){
226 liveuser 1813
 
1814
													#如果對方對話清單已經含有自己的id與userId了
3 liveuser 1815
													if($ceToCinfo["id"]===$myId && $ceToCinfo["userId"]===$myUserId){
226 liveuser 1816
 
3 liveuser 1817
														#debug
1818
														#var_dump("對方對話清單已經含有自己的id(".$myId.")與userId了(".$myUserId.")");
226 liveuser 1819
 
3 liveuser 1820
														#設置不需要更新
1821
														$update=false;
226 liveuser 1822
 
3 liveuser 1823
														#debug
1824
														#var_dump($toId."要加".$myId."到通話清單裡面");
226 liveuser 1825
 
3 liveuser 1826
														#設置對方不需要加自己到對話清單裡面
1827
														$add=false;
226 liveuser 1828
 
3 liveuser 1829
														}#if end
226 liveuser 1830
 
3 liveuser 1831
													}#foreach end
226 liveuser 1832
 
3 liveuser 1833
												#如果對方對話清單沒有自己的id與userId與msgId
1834
												if($update){
226 liveuser 1835
 
3 liveuser 1836
													#debug
1837
													#var_dump($toId."要更新對話清單中索引為".$talkToIndex."的id(".$this->connInfo[$toId]["talkTo"][$talkToIndex]["id"].")為".$myId);
226 liveuser 1838
 
3 liveuser 1839
													#將自己在對方對話清單裡面的id改成現在的id
1840
													$this->connInfo[$toId]["talkTo"][$talkToIndex]["id"]=$myId;
226 liveuser 1841
 
3 liveuser 1842
													}#if end
226 liveuser 1843
 
3 liveuser 1844
												#反之對方對話清單已經有自己的id與userId
1845
												else{
226 liveuser 1846
 
3 liveuser 1847
													#移除對方該已經斷線的對話id
1848
													unset($this->connInfo[$toId]["talkTo"][$talkToIndex]);
226 liveuser 1849
 
3 liveuser 1850
													}#else end
226 liveuser 1851
 
3 liveuser 1852
												}#if end
226 liveuser 1853
 
3 liveuser 1854
											}#if end
226 liveuser 1855
 
3 liveuser 1856
										}#foreach end
226 liveuser 1857
 
3 liveuser 1858
									#如果對方需要加自己到對話清單裡面
1859
									if($add){
226 liveuser 1860
 
3 liveuser 1861
										#檢查對方每個通話對象
1862
										foreach($this->connInfo[$toId]["talkTo"] as $reCktIndex=>$reCktInfo){
226 liveuser 1863
 
3 liveuser 1864
											#如果已經有將自己加到對方的對話清單裡面
1865
											if($reCktInfo["id"]===$myId && $reCktInfo["userId"]===$myUserId){
226 liveuser 1866
 
3 liveuser 1867
												#設置不用將自己加到對方的對話清單裡面
1868
												$add=false;
226 liveuser 1869
 
3 liveuser 1870
												}#if end
226 liveuser 1871
 
3 liveuser 1872
											}#foreach end
226 liveuser 1873
 
3 liveuser 1874
										#如果對方需要加自己到對話清單裡面
1875
										if($add){
226 liveuser 1876
 
3 liveuser 1877
											#debug
1878
											#var_dump($toId."要加".$myId."(msgId為".$this->connInfo[$myId]["msgId"].")到通話清單裡面");
226 liveuser 1879
 
3 liveuser 1880
											#讓通話對象也可以傳送訊息回來
1881
											$this->connInfo[$toId]["talkTo"][]=array("id"=>$myId,"userId"=>$myUserId,"msgId"=>$this->connInfo[$myId]["msgId"]);
226 liveuser 1882
 
3 liveuser 1883
											}#if end
226 liveuser 1884
 
3 liveuser 1885
										}#if end
226 liveuser 1886
 
3 liveuser 1887
									}#if end
226 liveuser 1888
 
3 liveuser 1889
								}#foreach end
226 liveuser 1890
 
3 liveuser 1891
							#移除留言紀錄
1892
							unset($this->unSendMsg[$index]);
226 liveuser 1893
 
3 liveuser 1894
							}#if end
226 liveuser 1895
 
3 liveuser 1896
						}#foreach end
226 liveuser 1897
 
3 liveuser 1898
					#檢查線上是否有人想跟我對話
226 liveuser 1899
 
3 liveuser 1900
					#有幾個人在線上就執行幾次
1901
					foreach($this->connInfo as $toId => $cInfo){
226 liveuser 1902
 
3 liveuser 1903
						#如果是自己
1904
						if($myId===$toId){
226 liveuser 1905
 
3 liveuser 1906
							#跳過
1907
							continue;
226 liveuser 1908
 
3 liveuser 1909
							}#if end
226 liveuser 1910
 
3 liveuser 1911
						#該cliet目前再跟幾個人通話,就執行幾次
1912
						foreach($cInfo["talkTo"] as $tIndex=>$tInfo){
226 liveuser 1913
 
3 liveuser 1914
							#如果自己的userId在對方的對話清單裡面
1915
							if($myUserId===$tInfo["userId"]){
226 liveuser 1916
 
3 liveuser 1917
								#假設自己需要被對方加到對話清單裡面
1918
								$add=true;
226 liveuser 1919
 
3 liveuser 1920
								#檢查自己是否已經在對方的對話清單裡面
226 liveuser 1921
 
3 liveuser 1922
								#對方有幾個通話對象就執行幾次
1923
								foreach($this->connInfo[$toId]["talkTo"] as $toIndex=>$toCinfo){
226 liveuser 1924
 
3 liveuser 1925
									#如果自己已經在對方的對話清單裡面
1926
									if($myUserId===$toCinfo["userId"] && $myId===$toCinfo["id"]){
226 liveuser 1927
 
3 liveuser 1928
										#設置自己不需要被對方加到對話清單裡面
1929
										$add=false;
226 liveuser 1930
 
3 liveuser 1931
										#跳出迴圈
1932
										break;
226 liveuser 1933
 
3 liveuser 1934
										}#if end
226 liveuser 1935
 
3 liveuser 1936
									}#foreach end
226 liveuser 1937
 
3 liveuser 1938
								#另存針對自己userId的連線id
1939
								$oneIdOfMyUserid=$this->connInfo[$toId]["talkTo"][$tIndex]["id"];
226 liveuser 1940
 
3 liveuser 1941
								#如果對方對話清單裡面的用戶id不在線
1942
								if(!isset($this->connInfo[$oneIdOfMyUserid])){
226 liveuser 1943
 
3 liveuser 1944
									#假設要將自己在對方對話清單裡面的id改成現在的id
1945
									$update=true;
226 liveuser 1946
 
3 liveuser 1947
									#自己不需要被對方加到對話清單裡面
1948
									$add=false;
226 liveuser 1949
 
3 liveuser 1950
									#檢查自己的id是否已經在對方的對話id裡面
1951
									foreach($this->connInfo[$toId]["talkTo"] as $ceIndex=>$ceInfo){
226 liveuser 1952
 
3 liveuser 1953
										#如果自己的id已經在對方的對話清單裡面
1954
										if($myId===$ceInfo["id"]){
226 liveuser 1955
 
3 liveuser 1956
											#設置不要將自己在對方對話清單裡面的id改成現在的id(可以移除該對話id)
1957
											$update=false;
226 liveuser 1958
 
3 liveuser 1959
											#跳出迴圈
1960
											break;
226 liveuser 1961
 
3 liveuser 1962
											}#if end
226 liveuser 1963
 
3 liveuser 1964
										}#foreach end
226 liveuser 1965
 
3 liveuser 1966
									#如果要將自己在對方對話清單裡面的id改成現在的id
1967
									if($update){
226 liveuser 1968
 
3 liveuser 1969
										#debug
1970
										#var_dump($toId."要更新對話清單中索引為".$tIndex."的id(".$this->connInfo[$toId]["talkTo"][$tIndex]["id"].")為".$myId);
226 liveuser 1971
 
3 liveuser 1972
										#將自己在對方對話清單裡面的id改成現在的id
1973
										$this->connInfo[$toId]["talkTo"][$tIndex]["id"]=$myId;
226 liveuser 1974
 
3 liveuser 1975
										}#if end
226 liveuser 1976
 
3 liveuser 1977
									#反之不要將自己在對方對話清單裡面的id改成現在的id(可以移除該對話id)
1978
									else{
226 liveuser 1979
 
3 liveuser 1980
										#移除該對話id
1981
										unset($this->connInfo[$toId]["talkTo"][$tIndex]);
226 liveuser 1982
 
3 liveuser 1983
										}#else end
226 liveuser 1984
 
1985
									}#if end
1986
 
3 liveuser 1987
								#如果要將自己加到對方的的通話清單裡面
1988
								if($add){
226 liveuser 1989
 
3 liveuser 1990
									#debug
1991
									#var_dump($toId."要加".$myId."(msgId為".$this->connInfo[$myId]["msgId"].")到通話清單裡面");
226 liveuser 1992
 
3 liveuser 1993
									#將自己加到對方的的通話清單裡面
226 liveuser 1994
									$this->connInfo[$toId]["talkTo"][]=array("id"=>$myId,"userId"=>$myUserId,"msgId"=>$this->connInfo[$myId]["msgId"]);
1995
 
1996
									}#if end
1997
 
3 liveuser 1998
								#檢查對方是否已經在自己的對話清單裡面
226 liveuser 1999
 
3 liveuser 2000
								#設置要新增對方到自己的對話清單裡面.
2001
								$add=true;
226 liveuser 2002
 
3 liveuser 2003
								#自己有幾個對話對象就執行幾次
2004
								foreach($this->connInfo[$myId]["talkTo"] as $mtIndex=>$mtInfo){
226 liveuser 2005
 
3 liveuser 2006
									#對方的userId與id若在自己的對話清單裡面
2007
									if($mtInfo["userId"]===$cInfo["userId"] && $mtInfo["id"]===$toId){
226 liveuser 2008
 
3 liveuser 2009
										#設置不需要新增對方到自己的對話清單裡面
2010
										$add=false;
226 liveuser 2011
 
3 liveuser 2012
										#跳出 foreach
2013
										break;
226 liveuser 2014
 
3 liveuser 2015
										}#if end
226 liveuser 2016
 
3 liveuser 2017
									}#foreache end
226 liveuser 2018
 
3 liveuser 2019
								#如果要新增對方到自己的對話清單裡面.
2020
								if($add){
226 liveuser 2021
 
3 liveuser 2022
									#自己有幾個對話對象就執行幾次
2023
									foreach($this->connInfo[$myId]["talkTo"] as $mtIndex=>$mtInfo){
226 liveuser 2024
 
3 liveuser 2025
										#如果對方已經在自己的通話清單
2026
										if($mtInfo["userId"]===$cInfo["userId"] && $mtInfo["id"]===$toId){
2027
 
2028
											#設置不要將對方到自己的對話清單裡面.
2029
											$add=false;
226 liveuser 2030
 
3 liveuser 2031
											#跳出 foreach end
2032
											break;
2033
 
2034
											}#if end
226 liveuser 2035
 
3 liveuser 2036
										}#foreach end
226 liveuser 2037
 
3 liveuser 2038
									#如果要新增對方到自己的對話清單裡面.
2039
									if($add){
226 liveuser 2040
 
3 liveuser 2041
										#將對方加到自己的對話清單裡面
2042
										$this->connInfo[$myId]["talkTo"][]=array("id"=>$toId,"userId"=>$cInfo["userId"],"msgId"=>$this->connInfo[$toId]["msgId"]);
226 liveuser 2043
 
3 liveuser 2044
										}#if end
226 liveuser 2045
 
3 liveuser 2046
									}#if end
226 liveuser 2047
 
3 liveuser 2048
								}#if end
226 liveuser 2049
 
3 liveuser 2050
							}#foreach end
226 liveuser 2051
 
3 liveuser 2052
						}#foreach end
226 liveuser 2053
 
3 liveuser 2054
					#結束認證成功後的流程
2055
					return true;
226 liveuser 2056
 
3 liveuser 2057
					}#else end
226 liveuser 2058
 
3 liveuser 2059
				}#else end
226 liveuser 2060
 
3 liveuser 2061
			#結束認證流程
226 liveuser 2062
			return true;
2063
 
3 liveuser 2064
			}#if end
226 liveuser 2065
 
3 liveuser 2066
		#如果收到 "id?"
2067
		else if($msg==="id?"){
226 liveuser 2068
 
3 liveuser 2069
			#包裝訊息
226 liveuser 2070
			#"type"為"id?"
2071
			#"status"為"true"
3 liveuser 2072
			#"data"為實際的訊息內容
2073
			$packedMsg=array("type"=>"id?","status"=>"true","data"=>$from->resourceId);
226 liveuser 2074
 
3 liveuser 2075
			#傳自己的id給client
2076
			$from->send(json_encode($packedMsg));
226 liveuser 2077
 
3 liveuser 2078
			#回傳成功
2079
			return true;
226 liveuser 2080
 
3 liveuser 2081
			}#if end
226 liveuser 2082
 
3 liveuser 2083
		#如果收到 "ids?"
2084
		else if($msg==="ids?"){
226 liveuser 2085
 
3 liveuser 2086
			#初始化儲存其他人的id
2087
			$idsArray=array();
226 liveuser 2088
 
3 liveuser 2089
			#針對所的client
2090
			foreach ($this->clients as $client){
226 liveuser 2091
 
3 liveuser 2092
				#排除自己
2093
				if($from !== $client){
226 liveuser 2094
 
3 liveuser 2095
					#取得其他人的id
2096
					$idsArray[]=$client->resourceId;
226 liveuser 2097
 
3 liveuser 2098
					}#if end
226 liveuser 2099
 
2100
				}#foreach end
2101
 
3 liveuser 2102
			#包裝訊息
226 liveuser 2103
			#"type"為"ids?"
2104
			#"status"為"true"
3 liveuser 2105
			#"data"為實際的訊息內容
2106
			$packedMsg=array("type"=>"ids?","status"=>"true","data"=>$idsArray);
226 liveuser 2107
 
3 liveuser 2108
			#傳他人的id給client
2109
			$from->send(json_encode($packedMsg));
226 liveuser 2110
 
3 liveuser 2111
			#回傳成功
2112
			return true;
226 liveuser 2113
 
3 liveuser 2114
			}#if end
226 liveuser 2115
 
3 liveuser 2116
		#如果收到 "talkTo?"
2117
		else if($msg==="talkTo?"){
226 liveuser 2118
 
3 liveuser 2119
			#包裝訊息
226 liveuser 2120
			#"type"為"talkTo?"
2121
			#"status"為"true"
3 liveuser 2122
			#"data"為實際的訊息內容
2123
			$packedMsg=array("type"=>"talkTo?","status"=>"true","data"=>$this->connInfo[$from->resourceId]["talkTo"]);
226 liveuser 2124
 
3 liveuser 2125
			#正在對話的對象id給client
2126
			$from->send(json_encode($packedMsg));
226 liveuser 2127
 
3 liveuser 2128
			#回傳成功
2129
			return true;
226 liveuser 2130
 
3 liveuser 2131
			}#if end
226 liveuser 2132
 
3 liveuser 2133
		#反之如果是 "msgId?"
2134
		else if($msg==="msgId?"){
226 liveuser 2135
 
3 liveuser 2136
			#包裝訊息
226 liveuser 2137
			#"type"為"talkTo?"
2138
			#"status"為"true"
3 liveuser 2139
			#"data"為實際的訊息內容
2140
			$packedMsg=array("type"=>"msgId?","status"=>"true","data"=>$this->connInfo[$from->resourceId]["msgId"]);
226 liveuser 2141
 
3 liveuser 2142
			#取得自己的msgId
2143
			$from->send(json_encode($packedMsg));
226 liveuser 2144
 
3 liveuser 2145
			#回傳成功
2146
			return true;
226 liveuser 2147
 
3 liveuser 2148
			}#if end
226 liveuser 2149
 
3 liveuser 2150
		#如果收到的$msg長度大於 "talkTo:"
2151
		if(strlen($msg)>strlen("talkTo:")){
226 liveuser 2152
 
2153
			#如果收到開頭為 "talkTo:"
3 liveuser 2154
			#涵式說明:
2155
			#取得符合特定字首與字尾的字串
2156
			#回傳的結果:
2157
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
2158
			#$result["function"],當前執行的函數名稱.
2159
			#$result["error"],錯誤訊息陣列.
2160
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
2161
			#$result["returnString"],爲符合字首條件的字串內容。
2162
			#必填參數:
2163
			#$conf["checkString"],字串,要檢查的字串.
2164
			$conf["search::getMeetConditionsString"]["checkString"]=$msg;
2165
			#可省略參數:
2166
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
2167
			$conf["search::getMeetConditionsString"]["frontWord"]="talkTo:";
2168
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
2169
			#$conf["tailWord"]="";
2170
			#參考資料:
2171
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
2172
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
2173
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 2174
 
3 liveuser 2175
			#如果選找前置字串 "talkTo:" 失敗
2176
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 2177
 
3 liveuser 2178
				#設置執行失敗
2179
				$result["status"]="false";
226 liveuser 2180
 
3 liveuser 2181
				#設置執行錯誤訊息
2182
				$result["error"]=$getMeetConditionsString;
226 liveuser 2183
 
3 liveuser 2184
				#回傳結果
2185
				return $result;
226 liveuser 2186
 
3 liveuser 2187
				}#if end
226 liveuser 2188
 
3 liveuser 2189
			#如果存在 "talkTo:" 前置字串
2190
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 2191
 
3 liveuser 2192
				#用 "talkTo:" 分割 $buf
2193
				#涵式說明:
2194
				#將固定格式的字串分開,並回傳分開的結果。
2195
				#回傳結果:
2196
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2197
				#$result["error"],錯誤訊息陣列
2198
				#$result["function"],當前執行的函數名稱.
2199
				#$result["oriStr"],要分割的原始字串內容
2200
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
2201
				#$result["dataCounts"],爲總共分成幾段
2202
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
2203
				#必填的參數:
2204
				$conf["stringProcess::spiltString"]["stringIn"]=$msg;#要處理的字串。
2205
				$conf["stringProcess::spiltString"]["spiltSymbol"]="talkTo:";#爲以哪個符號作爲分割
2206
				#可省略參數:
2207
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
2208
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
2209
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
2210
				unset($conf["stringProcess::spiltString"]);
226 liveuser 2211
 
3 liveuser 2212
				#如果分割字串失敗
2213
				if($spiltString["status"]==="false"){
226 liveuser 2214
 
3 liveuser 2215
					#設置執行失敗
2216
					$result["status"]="false";
226 liveuser 2217
 
3 liveuser 2218
					#設置執行錯誤訊息
2219
					$result["error"]=$spiltString;
226 liveuser 2220
 
3 liveuser 2221
					#回傳結果
2222
					return $result;
226 liveuser 2223
 
3 liveuser 2224
					}#if end
226 liveuser 2225
 
3 liveuser 2226
				#如果剛好分割出一筆資料
2227
				if($spiltString["dataCounts"]===1){
226 liveuser 2228
 
3 liveuser 2229
					#取得自己的id
2230
					$myId=$from->resourceId;
226 liveuser 2231
 
3 liveuser 2232
					#取得講話對象的id
2233
					$toId=$spiltString["dataArray"][0];
226 liveuser 2234
 
3 liveuser 2235
					#設置對象不存在的識別
2236
					$targetExist=false;
226 liveuser 2237
 
3 liveuser 2238
					#設置通話對象的key
226 liveuser 2239
					$targetKey="";
2240
 
3 liveuser 2241
					#如果要對話的對象存在
2242
					if(isset($this->connInfo[$toId])){
226 liveuser 2243
 
3 liveuser 2244
						#取得對象的userId
2245
						$toUserId=$this->connInfo[$toId]["userId"];
226 liveuser 2246
 
3 liveuser 2247
						#取得同userId的對象id們
226 liveuser 2248
 
3 liveuser 2249
						#初始化同userId的對象id
2250
						$targetC=array();
226 liveuser 2251
 
3 liveuser 2252
						#針對每個連線
2253
						foreach($this->connInfo as $eachIndex=>$eachInfo){
226 liveuser 2254
 
3 liveuser 2255
							#如果是自己
2256
							if($eachIndex===$myId){
226 liveuser 2257
 
3 liveuser 2258
								#跳到下一輪
2259
								continue;
226 liveuser 2260
 
3 liveuser 2261
								}#if end
226 liveuser 2262
 
3 liveuser 2263
							#如果是同userId的對象
2264
							if($eachInfo["userId"]===$toUserId){
226 liveuser 2265
 
3 liveuser 2266
								#取出連線
2267
								$targetC[$eachIndex]=$this->connInfo[$eachIndex];
226 liveuser 2268
 
3 liveuser 2269
								}#if end
226 liveuser 2270
 
3 liveuser 2271
							}#foreach end
226 liveuser 2272
 
3 liveuser 2273
						#針對每個同userId的連線
2274
						foreach($targetC as $tcIndex=>$tcInfo){
226 liveuser 2275
 
3 liveuser 2276
							#檢查自己的對話對象是否已經在清單裡面了
226 liveuser 2277
 
3 liveuser 2278
							#假設對象可以加到自己對話清單裡面
2279
							$add=true;
226 liveuser 2280
 
3 liveuser 2281
							#針對每個要講話的對象
2282
							foreach($this->connInfo[$myId]["talkTo"] as $index=>$cInfo){
226 liveuser 2283
 
3 liveuser 2284
								#如果對話對象已經在清單裡面了
2285
								if($this->connInfo[$tcIndex]["userId"]===$cInfo["userId"] && $tcIndex===$cInfo["id"] && $tcInfo["msgId"]===$cInfo["msgId"]){
226 liveuser 2286
 
3 liveuser 2287
									#設置不要再加到清單裡面
2288
									$add=false;
226 liveuser 2289
 
3 liveuser 2290
									#跳出foreach
2291
									break;
226 liveuser 2292
 
2293
									}#if end
2294
 
3 liveuser 2295
								}#foreach end
226 liveuser 2296
 
3 liveuser 2297
							#如果要加入到對話清單裡面
2298
							if($add){
226 liveuser 2299
 
3 liveuser 2300
								#增加自己的對話對象
2301
								$this->connInfo[$myId]["talkTo"][]=array("id"=>$tcIndex,"userId"=>$this->connInfo[$tcIndex]["userId"],"msgId"=>$this->connInfo[$tcIndex]["msgId"]);
226 liveuser 2302
 
3 liveuser 2303
								#假設對方可以加自己到對話清單裡面
2304
								$add=true;
226 liveuser 2305
 
3 liveuser 2306
								#檢查通話對象能否跟自己對話
2307
								foreach($this->connInfo[$tcIndex]["talkTo"] as $index=>$cInfo){
226 liveuser 2308
 
3 liveuser 2309
									#如果對話對象已經在清單裡面了
2310
									if($this->connInfo[$myId]["userId"]===$cInfo["userId"]){
226 liveuser 2311
 
3 liveuser 2312
										#設置不要再加到清單裡面
2313
										$add=false;
226 liveuser 2314
 
3 liveuser 2315
										#跳出 foreach
2316
										break;
226 liveuser 2317
 
3 liveuser 2318
										}#if end
226 liveuser 2319
 
3 liveuser 2320
									}#foreach end
226 liveuser 2321
 
3 liveuser 2322
								#如果對方可以加自己到對話清單裡面
2323
								if($add){
226 liveuser 2324
 
3 liveuser 2325
									#讓通話對象也可以傳送訊息回來
2326
									$this->connInfo[$tcIndex]["talkTo"][]=array("id"=>$myId,"userId"=>$this->connInfo[$myId]["userId"],"msgId"=>$this->connInfo[$myId]["msgId"]);
226 liveuser 2327
 
3 liveuser 2328
									}#if end
226 liveuser 2329
 
3 liveuser 2330
								#設置成功訊息
2331
								$msg="client id ".$toId." added to talkTo list";
226 liveuser 2332
 
3 liveuser 2333
								#包裝訊息
226 liveuser 2334
								#"type"為"status"
2335
								#"status"為"true"
3 liveuser 2336
								#"data"為實際的訊息內容
2337
								$packedMsg=array("type"=>"status","status"=>"true","data"=>$msg);
226 liveuser 2338
 
3 liveuser 2339
								#設置要給自己看的訊息
226 liveuser 2340
								$from->send(json_encode($packedMsg));
2341
 
3 liveuser 2342
								}#if end
226 liveuser 2343
 
3 liveuser 2344
							#反之
2345
							else{
226 liveuser 2346
 
3 liveuser 2347
								#設置錯誤訊息
2348
								$msg="client id ".$toId." already in talkTo list";
226 liveuser 2349
 
3 liveuser 2350
								#包裝訊息
226 liveuser 2351
								#"type"為"status"
2352
								#"status"為"false"
3 liveuser 2353
								#"data"為實際的訊息內容
2354
								$packedMsg=array("type"=>"status","status"=>"false","data"=>$msg);
226 liveuser 2355
 
3 liveuser 2356
								#設置要給自己看的訊息
2357
								$from->send(json_encode($packedMsg));
226 liveuser 2358
 
3 liveuser 2359
								}#else end
226 liveuser 2360
 
3 liveuser 2361
							}#foreach end
226 liveuser 2362
 
3 liveuser 2363
						#回傳成功
2364
						return true;
226 liveuser 2365
 
3 liveuser 2366
						}#if end
226 liveuser 2367
 
3 liveuser 2368
					#反之不存在
2369
					else{
226 liveuser 2370
 
3 liveuser 2371
						#設置錯誤訊息
2372
						$msg="client id ".$toId." doesn't exist";
226 liveuser 2373
 
3 liveuser 2374
						#包裝訊息
226 liveuser 2375
						#"type"為"status"
2376
						#"status"為"false"
3 liveuser 2377
						#"data"為實際的訊息內容
2378
						$packedMsg=array("type"=>"status","status"=>"false","data"=>$msg);
226 liveuser 2379
 
3 liveuser 2380
						#設置要給自己看的訊息
2381
						$from->send(json_encode($packedMsg));
226 liveuser 2382
 
3 liveuser 2383
						#回傳成功
2384
						return true;
226 liveuser 2385
 
2386
						}#else end
2387
 
3 liveuser 2388
					}#if end
226 liveuser 2389
 
3 liveuser 2390
				}#if end
226 liveuser 2391
 
3 liveuser 2392
			}#if end
226 liveuser 2393
 
3 liveuser 2394
		#預設沒有收到確認收到訊息的回應訊息
2395
		$mIndex="false";
226 liveuser 2396
 
3 liveuser 2397
		#如果收到的$msg長度大於 "msgId:"
2398
		if(strlen($msg)>strlen("msgId:")){
226 liveuser 2399
 
3 liveuser 2400
			#解析 $msg
226 liveuser 2401
 
2402
			#如果收到開頭為 "msgId:"
3 liveuser 2403
			#涵式說明:
2404
			#取得符合特定字首與字尾的字串
2405
			#回傳的結果:
2406
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
2407
			#$result["function"],當前執行的函數名稱.
2408
			#$result["error"],錯誤訊息陣列.
2409
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
2410
			#$result["returnString"],爲符合字首條件的字串內容。
2411
			#必填參數:
2412
			#$conf["checkString"],字串,要檢查的字串.
2413
			$conf["search::getMeetConditionsString"]["checkString"]=$msg;
2414
			#可省略參數:
2415
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
2416
			$conf["search::getMeetConditionsString"]["frontWord"]="msgId:";
2417
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
2418
			#$conf["tailWord"]="";
2419
			#參考資料:
2420
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
2421
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
2422
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 2423
 
3 liveuser 2424
			#如果選找前置字串 "msgId:" 失敗
2425
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 2426
 
3 liveuser 2427
				#設置執行失敗
2428
				$result["status"]="false";
226 liveuser 2429
 
3 liveuser 2430
				#設置執行錯誤訊息
2431
				$result["error"]=$getMeetConditionsString;
226 liveuser 2432
 
3 liveuser 2433
				#回傳結果
2434
				return $result;
226 liveuser 2435
 
3 liveuser 2436
				}#if end
226 liveuser 2437
 
3 liveuser 2438
			#如果存在	 "msgId:" 前置字串
2439
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 2440
 
3 liveuser 2441
				#用 "msgId:" 分割 $msg
2442
				#涵式說明:
2443
				#將固定格式的字串分開,並回傳分開的結果。
2444
				#回傳結果:
2445
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2446
				#$result["error"],錯誤訊息陣列
2447
				#$result["function"],當前執行的函數名稱.
2448
				#$result["oriStr"],要分割的原始字串內容
2449
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
2450
				#$result["dataCounts"],爲總共分成幾段
2451
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
2452
				#必填的參數:
2453
				$conf["stringProcess::spiltString"]["stringIn"]=$msg;#要處理的字串。
2454
				$conf["stringProcess::spiltString"]["spiltSymbol"]="msgId:";#爲以哪個符號作爲分割
2455
				#可省略參數:
2456
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
2457
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
2458
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
2459
				unset($conf["stringProcess::spiltString"]);
226 liveuser 2460
 
3 liveuser 2461
				#如果分割字串失敗
2462
				if($spiltString["status"]==="false"){
226 liveuser 2463
 
3 liveuser 2464
					#設置執行失敗
2465
					$result["status"]="false";
226 liveuser 2466
 
3 liveuser 2467
					#設置執行錯誤訊息
2468
					$result["error"]=$spiltString;
226 liveuser 2469
 
3 liveuser 2470
					#回傳結果
2471
					return $result;
226 liveuser 2472
 
3 liveuser 2473
					}#if end
226 liveuser 2474
 
3 liveuser 2475
				#如果剛好分割出一筆資料
2476
				if($spiltString["dataCounts"]===1){
226 liveuser 2477
 
3 liveuser 2478
					#如果尚未設置過msgId
2479
					if($this->connInfo[$from->resourceId]["gotMsgId"]==="false"){
226 liveuser 2480
 
3 liveuser 2481
						#取得待確認訊息id
2482
						$msgId=$spiltString["dataArray"][0];
226 liveuser 2483
 
3 liveuser 2484
						#初始化儲存現有msgId的變數
2485
						$msgIdArray=array();
226 liveuser 2486
 
3 liveuser 2487
						#取得現有的msgId
2488
						foreach($this->connInfo as $cInfo){
226 liveuser 2489
 
3 liveuser 2490
							#如果msgId不為空
2491
							if($cInfo["msgId"]!==""){
226 liveuser 2492
 
3 liveuser 2493
								#儲存msgId
2494
								$msgIdArray[]=$cInfo["msgId"];
226 liveuser 2495
 
3 liveuser 2496
								}#if end
226 liveuser 2497
 
3 liveuser 2498
							}#foreach end
226 liveuser 2499
 
3 liveuser 2500
						#檢查msgId是否存在於$msgIdArray裡面
2501
						if(in_array($msgId,$msgIdArray)){
226 liveuser 2502
 
3 liveuser 2503
							#設置自己的msgId
226 liveuser 2504
							$this->connInfo[$from->resourceId]["msgId"]=$msgId;
2505
 
3 liveuser 2506
							#設置已經設置過msgId
2507
							$this->connInfo[$from->resourceId]["gotMsgId"]="true";
226 liveuser 2508
 
3 liveuser 2509
							#設置成功訊息
2510
							$msg="set msgId successfully";
226 liveuser 2511
 
3 liveuser 2512
							#包裝訊息
226 liveuser 2513
							#"type"為"status"
2514
							#"status"為"false"
3 liveuser 2515
							#"data"為實際的訊息內容
2516
							$packedMsg=array("type"=>"status","status"=>"true","data"=>$msg);
226 liveuser 2517
 
3 liveuser 2518
							#設置要給自己看的訊息
2519
							$from->send(json_encode($packedMsg));
226 liveuser 2520
 
3 liveuser 2521
							#針對每個連線
2522
							foreach($this->connInfo as $connIndex=>$connInfo){
226 liveuser 2523
 
3 liveuser 2524
								#如果是跟發訊息者同msgId但id不一樣的連線
2525
								if($connInfo["msgId"]===$msgId && $connIndex!==$from->resourceId){
226 liveuser 2526
 
3 liveuser 2527
									#將id為$connIndex的連線斷線
2528
									$this->clients->detach($this->connInfo[$connIndex]["conn"]);
2529
 
2530
									#提示已經將連線斷開
2531
									echo "Connection {$connIndex} has disconnected\n";
226 liveuser 2532
 
3 liveuser 2533
									#移除先前同msgId但id不一樣的連線
2534
									unset($this->connInfo[$connIndex]);
226 liveuser 2535
 
3 liveuser 2536
									#針對每個連線
2537
									foreach($this->connInfo as $cIndexForTD=>$cInfoForTD){
226 liveuser 2538
 
3 liveuser 2539
										#針對 talkTo 的每個項目
2540
										foreach($cInfoForTD["talkTo"] as $ttIndex=>$ttInfo){
226 liveuser 2541
 
3 liveuser 2542
											#如果是不存在的通話對象
2543
											if($ttInfo["id"]===$connIndex){
226 liveuser 2544
 
3 liveuser 2545
												#移除之
2546
												unset($this->connInfo[$cIndexForTD]["talkTo"][$ttIndex]);
226 liveuser 2547
 
3 liveuser 2548
												}#if end
226 liveuser 2549
 
3 liveuser 2550
											}#foreach end
226 liveuser 2551
 
3 liveuser 2552
										}#foreach end
226 liveuser 2553
 
3 liveuser 2554
									}#if end
226 liveuser 2555
 
3 liveuser 2556
								}#foreach end
226 liveuser 2557
 
3 liveuser 2558
							#如果有要確認的訊息陣列
2559
							if(isset($this->unConfirmMsg[$msgId])){
226 liveuser 2560
 
3 liveuser 2561
								#初始化要傳送的待確認訊息
2562
								$packedMsg=array();
226 liveuser 2563
 
3 liveuser 2564
								#有幾個要確認的訊息就執行幾次
2565
								foreach($this->unConfirmMsg[$msgId] as $unCMindex=>$unCMinfo){
226 liveuser 2566
 
3 liveuser 2567
									#如果待確認訊息的傳送目標id不等於剛要求更換msgId的用戶id
2568
									if($unCMinfo["toId"]!==$from->resourceId){
226 liveuser 2569
 
3 liveuser 2570
										#設置傳送目標id為要求更換msgId的用戶id
2571
										$this->unConfirmMsg[$msgId][$unCMindex]["toId"]=$from->resourceId;
226 liveuser 2572
 
3 liveuser 2573
										#檢查所有連線資訊
2574
										foreach($this->connInfo as $connId=>$connInfo){
226 liveuser 2575
 
3 liveuser 2576
											#依據talkTo清單的每個對象
2577
											foreach($connInfo["talkTo"] as $talk2Index=>$talk2Info){
226 liveuser 2578
 
3 liveuser 2579
												#若對象的id為$unCMinfo["toId"]且userId為$this->connInfo[$from->resourceId]["userId"]且msgId為$this->connInfo[$from->resourceId]["msgId"]者
2580
												if($talk2Info["id"]===$unCMinfo["toId"] && $talk2Info["userId"]===$this->connInfo[$from->resourceId]["userId"] && $talk2Info["msgId"]===$this->connInfo[$from->resourceId]["msgId"]){
226 liveuser 2581
 
3 liveuser 2582
													#移除該talkTo對象
2583
													unset($this->connInfo[$connId]["talkTo"][$talk2Index]);
226 liveuser 2584
 
3 liveuser 2585
													}#if ded
226 liveuser 2586
 
3 liveuser 2587
												}#foreach end
226 liveuser 2588
 
3 liveuser 2589
											}#foreach end
226 liveuser 2590
 
3 liveuser 2591
										}#if end
226 liveuser 2592
 
3 liveuser 2593
									#如果要傳送的待確認訊息為空陣列
2594
									if($packedMsg===array()){
226 liveuser 2595
 
3 liveuser 2596
										#包裝訊息
2597
										#"type"為"msg"
2598
										#"index"為$cInfo["id"]
2599
										#"data"為實際的訊息內容
2600
										$packedMsg=array("type"=>"msg","index"=>$unCMindex,"data"=>$unCMinfo["msg"]);
226 liveuser 2601
 
3 liveuser 2602
										}#if end
226 liveuser 2603
 
3 liveuser 2604
									}#foreach end
226 liveuser 2605
 
3 liveuser 2606
								#如果要傳送的待確認訊息不為空陣列
2607
								if($packedMsg!==array()){
226 liveuser 2608
 
3 liveuser 2609
									#var_dump("重新登入更改msgId後要傳送的未確認訊息:".print_r($packedMsg,true));
226 liveuser 2610
 
3 liveuser 2611
									#傳送包裝好的待確認訊息給對方
2612
									$from->send(json_encode($packedMsg));
226 liveuser 2613
 
3 liveuser 2614
									}#if end
226 liveuser 2615
 
3 liveuser 2616
								}#if end
226 liveuser 2617
 
3 liveuser 2618
							#結束程式
2619
							return true;
226 liveuser 2620
 
3 liveuser 2621
							}#if end
226 liveuser 2622
 
3 liveuser 2623
						}#if end
226 liveuser 2624
 
3 liveuser 2625
					#反之已經設置過 msgId 了
2626
					else{
226 liveuser 2627
 
3 liveuser 2628
						#設置錯誤訊息
2629
						$msg="msgId already set";
226 liveuser 2630
 
3 liveuser 2631
						#包裝訊息
226 liveuser 2632
						#"type"為"status"
2633
						#"status"為"false"
3 liveuser 2634
						#"data"為實際的訊息內容
2635
						$packedMsg=array("type"=>"status","status"=>"false","data"=>$msg);
226 liveuser 2636
 
3 liveuser 2637
						#設置要給自己看的訊息
2638
						$from->send(json_encode($packedMsg));
2639
 
2640
						#結束程式
2641
						return true;
226 liveuser 2642
 
3 liveuser 2643
						}#else end
226 liveuser 2644
 
3 liveuser 2645
					}#if end
226 liveuser 2646
 
3 liveuser 2647
				#設置失敗訊息
2648
				$msg="set msgId failed";
226 liveuser 2649
 
3 liveuser 2650
				#包裝訊息
226 liveuser 2651
				#"type"為"status"
2652
				#"status"為"false"
3 liveuser 2653
				#"data"為實際的訊息內容
2654
				$packedMsg=array("type"=>"status","status"=>"false","data"=>$msg);
226 liveuser 2655
 
3 liveuser 2656
				#設置要給自己看的訊息
2657
				$from->send(json_encode($packedMsg));
2658
 
2659
				#結束程式
2660
				return true;
226 liveuser 2661
 
3 liveuser 2662
				}#if end
226 liveuser 2663
 
3 liveuser 2664
			}#if end
226 liveuser 2665
 
3 liveuser 2666
		#如果訊息長度大於 strlen("mIndex:")
2667
		if(strlen($msg)>strlen("mIndex:")){
226 liveuser 2668
 
2669
			#如果是確認收到訊息的回應訊息開頭 "mIndex:"
3 liveuser 2670
			#涵式說明:
2671
			#取得符合特定字首與字尾的字串
2672
			#回傳的結果:
2673
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
2674
			#$result["function"],當前執行的函數名稱.
2675
			#$result["error"],錯誤訊息陣列.
2676
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
2677
			#$result["returnString"],爲符合字首條件的字串內容。
2678
			#必填參數:
2679
			#$conf["checkString"],字串,要檢查的字串.
2680
			$conf["search::getMeetConditionsString"]["checkString"]=$msg;
2681
			#可省略參數:
2682
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
2683
			$conf["search::getMeetConditionsString"]["frontWord"]="mIndex:";
2684
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
2685
			#$conf["tailWord"]="";
2686
			#參考資料:
2687
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
2688
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
2689
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 2690
 
3 liveuser 2691
			#如果選找前置字串 "mIndex:" 失敗
2692
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 2693
 
3 liveuser 2694
				#設置執行失敗
2695
				$result["status"]="false";
226 liveuser 2696
 
3 liveuser 2697
				#設置執行錯誤訊息
2698
				$result["error"]=$getMeetConditionsString;
226 liveuser 2699
 
3 liveuser 2700
				#回傳結果
2701
				return $result;
226 liveuser 2702
 
3 liveuser 2703
				}#if end
226 liveuser 2704
 
3 liveuser 2705
			#如果存在	 "mIndex:" 前置字串
2706
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 2707
 
3 liveuser 2708
				#用 "mIndex:" 分割 $buf
2709
				#涵式說明:
2710
				#將固定格式的字串分開,並回傳分開的結果。
2711
				#回傳結果:
2712
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2713
				#$result["error"],錯誤訊息陣列
2714
				#$result["function"],當前執行的函數名稱.
2715
				#$result["oriStr"],要分割的原始字串內容
2716
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
2717
				#$result["dataCounts"],爲總共分成幾段
2718
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
2719
				#必填的參數:
2720
				$conf["stringProcess::spiltString"]["stringIn"]=$msg;#要處理的字串。
2721
				$conf["stringProcess::spiltString"]["spiltSymbol"]="mIndex:";#爲以哪個符號作爲分割
2722
				#可省略參數:
2723
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
2724
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
2725
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
2726
				unset($conf["stringProcess::spiltString"]);
226 liveuser 2727
 
3 liveuser 2728
				#如果分割字串失敗
2729
				if($spiltString["status"]==="false"){
226 liveuser 2730
 
3 liveuser 2731
					#設置執行失敗
2732
					$result["status"]="false";
226 liveuser 2733
 
3 liveuser 2734
					#設置執行錯誤訊息
2735
					$result["error"]=$spiltString;
226 liveuser 2736
 
3 liveuser 2737
					#回傳結果
2738
					return $result;
226 liveuser 2739
 
3 liveuser 2740
					}#if end
226 liveuser 2741
 
3 liveuser 2742
				#如果存在分割的識別字串
2743
				if($spiltString["found"]==="true"){
226 liveuser 2744
 
3 liveuser 2745
					#如果只分割出一段
2746
					if($spiltString["dataCounts"]===1){
226 liveuser 2747
 
3 liveuser 2748
						#取得待確認訊息的索引
2749
						$mIndex=$spiltString["dataArray"][0];
226 liveuser 2750
 
3 liveuser 2751
						}#if end
226 liveuser 2752
 
3 liveuser 2753
					}#if end
226 liveuser 2754
 
3 liveuser 2755
				}#if end
226 liveuser 2756
 
3 liveuser 2757
			}#if end
226 liveuser 2758
 
3 liveuser 2759
		#如果有要講話的對象
2760
		if(count($this->connInfo[$from->resourceId]["talkTo"])>0){
226 liveuser 2761
 
3 liveuser 2762
			#依據每個對話對象
2763
			foreach($this->connInfo[$from->resourceId]["talkTo"] as $index => $cInfo){
226 liveuser 2764
 
3 liveuser 2765
				#如果要講話的對象不存在(socket已經斷開)
2766
				if(!isset($this->connInfo[$cInfo["id"]])){
226 liveuser 2767
 
3 liveuser 2768
					#將訊息儲存起來,等對象上線後再把訊息傳過去.
2769
					$this->unSendMsg[]=array(
2770
						"fromId"=>$from->resourceId,
2771
						"toId"=>"",
2772
						"fromUserId"=>$this->connInfo[$from->resourceId]["userId"],
2773
						"toUserId"=>$cInfo["userId"],
2774
						"msg"=>$msg
2775
						);
226 liveuser 2776
 
3 liveuser 2777
					}#if end
226 liveuser 2778
 
3 liveuser 2779
				#反之,講話的對象存在
2780
				else{
226 liveuser 2781
 
3 liveuser 2782
					#如果收到確認收到訊息的回應
2783
					if($mIndex!=="false"){
226 liveuser 2784
 
3 liveuser 2785
						#儲存對話目標的msgId
2786
						$targetMsgId=$this->connInfo[$from->resourceId]["msgId"];
226 liveuser 2787
 
3 liveuser 2788
						#針對每個連線的待確認訊息
2789
						foreach($this->unConfirmMsg as $unCMindex=>$unCMinfo){
226 liveuser 2790
 
3 liveuser 2791
							#debug
2792
							#var_dump($unCMindex."!==".$targetMsgId." && count(\$unCMinfo):".count($unCMinfo));
226 liveuser 2793
 
3 liveuser 2794
							#如果 未確認訊息達到10則以上 且不是接收訊息者的msgId
2795
							if($unCMindex!==$targetMsgId && count($unCMinfo)>10){
226 liveuser 2796
 
3 liveuser 2797
								#代表接收訊息的用戶無法透過網路跟server溝通
226 liveuser 2798
 
3 liveuser 2799
								#提示 server 連線已結束
2800
								echo "Connection {$unCMinfo["id"]} has disconnected\n";
226 liveuser 2801
 
3 liveuser 2802
								#將待驗證的訊息變成留言訊息
226 liveuser 2803
 
3 liveuser 2804
								#有幾個未確認訊息就執行幾次
2805
								foreach($this->unConfirmMsg[$unCMindex] as $unConMsgIndex => $unConMsgInfo){
226 liveuser 2806
 
3 liveuser 2807
									#將訊息儲存起來,等對象上線後再把訊息傳過去.
2808
									$this->unSendMsg[]=array(
2809
										"fromId"=>$unConMsgInfo["fromId"],
2810
										"toId"=>"",
2811
										"fromUserId"=>$unConMsgInfo["fromUserId"],
2812
										"toUserId"=>$unConMsgInfo["toUserId"],
2813
										"msg"=>$unConMsgInfo["msg"]
2814
										);
226 liveuser 2815
 
3 liveuser 2816
									}#foreach end
226 liveuser 2817
 
3 liveuser 2818
								#移除待驗證的訊息資訊
2819
								unset($this->unConfirmMsg[$unCMindex]);
226 liveuser 2820
 
3 liveuser 2821
								#將client的連線斷開
2822
								$this->clients->detach($this->connInfo[$unConMsgInfo["fromId"]]["conn"]);
226 liveuser 2823
 
3 liveuser 2824
								#移除連線的資訊
226 liveuser 2825
								unset($this->connInfo[$unConMsgInfo["fromId"]]);
2826
 
3 liveuser 2827
								}#if end
226 liveuser 2828
 
3 liveuser 2829
							}#foreach end
226 liveuser 2830
 
3 liveuser 2831
						#存在收到訊息用戶id的待確認訊息
2832
						if(isset($this->unConfirmMsg[$targetMsgId])){
226 liveuser 2833
 
3 liveuser 2834
							#如果該未確認訊息存在
2835
							if(isset($this->unConfirmMsg[$targetMsgId][$mIndex])){
226 liveuser 2836
 
3 liveuser 2837
								#debug
2838
								#var_dump("移除待確認的訊息".print_r($this->unConfirmMsg[$targetMsgId][$mIndex],true));
226 liveuser 2839
 
3 liveuser 2840
								#移除該確認訊息
2841
								unset($this->unConfirmMsg[$targetMsgId][$mIndex]);
226 liveuser 2842
 
3 liveuser 2843
								#還剩下幾個待確認訊息就執行幾次
2844
								foreach($this->unConfirmMsg[$targetMsgId] as $unCMindex=>$unCMinfo){
226 liveuser 2845
 
3 liveuser 2846
									#如果後面還有訊息
2847
									if(isset($this->unConfirmMsg[$targetMsgId][$unCMindex+1])){
226 liveuser 2848
 
3 liveuser 2849
										#如果與下一份訊息的 fromUserId一樣, toUserId 一樣, fromId一樣, toId 不同, msg 一樣.
2850
										if(
2851
											(
2852
												$this->unConfirmMsg[$targetMsgId][$unCMindex]["fromUserId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromUserId"]
2853
												)
2854
											&&
2855
											(
2856
												$this->unConfirmMsg[$targetMsgId][$unCMindex]["toUserId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toUserId"]
2857
												)
2858
											&&
2859
											(
2860
												$this->unConfirmMsg[$targetMsgId][$unCMindex]["fromId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromId"]
2861
												)
2862
											&&
2863
											(
2864
												$this->unConfirmMsg[$targetMsgId][$unCMindex]["toId"]!==$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toId"]
226 liveuser 2865
												)
3 liveuser 2866
											&&
2867
											(
2868
												$this->unConfirmMsg[$targetMsgId][$unCMindex]["msg"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["msg"]
226 liveuser 2869
												)
3 liveuser 2870
											){
226 liveuser 2871
 
3 liveuser 2872
											#卸除該筆重複的訊息
2873
											unset($this->unConfirmMsg[$targetMsgId][$unCMindex]);
226 liveuser 2874
 
3 liveuser 2875
											#跳到下一則訊息
226 liveuser 2876
											continue;
2877
 
3 liveuser 2878
											}#if end
226 liveuser 2879
 
2880
										/*
3 liveuser 2881
										#debug
2882
										else{
226 liveuser 2883
 
3 liveuser 2884
											var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["fromUserId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromUserId"]);
2885
											var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["fromId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromId"]);
226 liveuser 2886
 
3 liveuser 2887
											var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["toUserId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toUserId"]);
2888
											var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["toId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toId"]);
226 liveuser 2889
 
3 liveuser 2890
											var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["msg"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["msg"]);
226 liveuser 2891
 
3 liveuser 2892
											}#else end
2893
										*/
226 liveuser 2894
 
3 liveuser 2895
										}#if end
226 liveuser 2896
 
3 liveuser 2897
									#包裝訊息
2898
									#"type"為"msg"
2899
									#"index"為$cInfo["id"]
2900
									#"data"為實際的訊息內容
2901
									$packedMsg=array("type"=>"msg","index"=>$unCMindex,"data"=>$unCMinfo["msg"]);
226 liveuser 2902
 
3 liveuser 2903
									#傳送包裝好的待確認訊息給對方
2904
									$from->send(json_encode($packedMsg));
226 liveuser 2905
 
3 liveuser 2906
									#一次只送一則訊息
2907
									break;
226 liveuser 2908
 
3 liveuser 2909
									}#foreach end
226 liveuser 2910
 
3 liveuser 2911
								}#if end
226 liveuser 2912
 
3 liveuser 2913
							}#if end
226 liveuser 2914
 
3 liveuser 2915
						}#if end
226 liveuser 2916
 
3 liveuser 2917
					#反之為要傳送的訊息
2918
					else{
226 liveuser 2919
 
3 liveuser 2920
						#儲存對話目標的msgId
2921
						$targetMsgId=$this->connInfo[$cInfo["id"]]["msgId"];
226 liveuser 2922
 
3 liveuser 2923
						#$unConfirmMsg[$msgId],為訊息接收方的$msgId,亦即收到訊息後,要跟server說有收到訊息者.
2924
						#"fromId",訊息來源的id
2925
						#"toId",訊息目的的id
2926
						#"fromUserId",訊息來源的userId
2927
						#"toUserId",訊息目標的userId
2928
						#"msg",傳送的訊息
2929
						#"msgId",訊息目標連線的msgId
2930
						#儲存待確認傳送的訊息到 $unConfirmMsg
2931
						$this->unConfirmMsg[$targetMsgId][]=array('fromId'=>$from->resourceId,'toId'=>$cInfo["id"],'fromUserId'=>$this->connInfo[$from->resourceId]["userId"],'toUserId'=>$cInfo["userId"],'msg'=>$msg,'msgId'=>$this->connInfo[$cInfo["id"]]["msgId"]);
226 liveuser 2932
 
2933
						#var_dump($this->unConfirmMsg[$targetMsgId]);
2934
 
3 liveuser 2935
						#如果未確認的訊息數量已經達到10則
2936
						if(count($this->unConfirmMsg[$targetMsgId])>10){
226 liveuser 2937
 
3 liveuser 2938
							#代表用戶無法透過網路跟server溝通
226 liveuser 2939
 
3 liveuser 2940
							#提示 server 連線已結束
2941
							echo "Connection {$cInfo["id"]} has disconnected\n";
226 liveuser 2942
 
3 liveuser 2943
							#將待驗證的訊息變成留言訊息
226 liveuser 2944
 
3 liveuser 2945
							#有幾個未確認訊息就執行幾次
2946
							foreach($this->unConfirmMsg[$targetMsgId] as $unCMindex => $unCMinfo){
226 liveuser 2947
 
3 liveuser 2948
								#將訊息儲存起來,等對象上線後再把訊息傳過去.
2949
								$this->unSendMsg[]=array(
2950
									"fromId"=>$unCMinfo["fromId"],
2951
									"toId"=>"",
2952
									"fromUserId"=>$unCMinfo["fromUserId"],
2953
									"toUserId"=>$unCMinfo["toUserId"],
2954
									"msg"=>$unCMinfo["msg"]
2955
									);
226 liveuser 2956
 
3 liveuser 2957
								}#foreach end
226 liveuser 2958
 
3 liveuser 2959
							#移除待驗證的訊息資訊
2960
							unset($this->unConfirmMsg[$targetMsgId]);
226 liveuser 2961
 
3 liveuser 2962
							#將client的連線斷開
2963
							$this->clients->detach($this->connInfo[$cInfo["id"]]["conn"]);
226 liveuser 2964
 
3 liveuser 2965
							#移除連線的資訊
2966
							unset($this->connInfo[$cInfo["id"]]);
226 liveuser 2967
 
3 liveuser 2968
							}#if end
226 liveuser 2969
 
3 liveuser 2970
						#反之
2971
						else{
226 liveuser 2972
 
3 liveuser 2973
							#裡面有幾個待確認的訊息就執行幾次
2974
							foreach($this->unConfirmMsg[$targetMsgId] as $unCMindex=>$unCMinfo){
226 liveuser 2975
 
3 liveuser 2976
								#如果後面還有訊息
2977
								if(isset($this->unConfirmMsg[$targetMsgId][$unCMindex+1])){
226 liveuser 2978
 
3 liveuser 2979
									#debug
2980
									#var_dump($this->unConfirmMsg[$targetMsgId]);
226 liveuser 2981
 
3 liveuser 2982
									#如果與下一份訊息的 fromUserId一樣, toUserId 一樣, fromId一樣, toId 不同, msg 一樣.
2983
									if(
2984
										(
2985
											$this->unConfirmMsg[$targetMsgId][$unCMindex]["fromUserId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromUserId"]
2986
											)
2987
										&&
2988
										(
2989
											$this->unConfirmMsg[$targetMsgId][$unCMindex]["toUserId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toUserId"]
2990
											)
2991
										&&
2992
										(
2993
											$this->unConfirmMsg[$targetMsgId][$unCMindex]["fromId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromId"]
2994
											)
2995
										&&
2996
										(
2997
											$this->unConfirmMsg[$targetMsgId][$unCMindex]["toId"]!==$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toId"]
226 liveuser 2998
											)
3 liveuser 2999
										&&
3000
										(
3001
											$this->unConfirmMsg[$targetMsgId][$unCMindex]["msg"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["msg"]
226 liveuser 3002
											)
3 liveuser 3003
										){
226 liveuser 3004
 
3 liveuser 3005
										#卸除該筆重複的訊息
3006
										unset($this->unConfirmMsg[$targetMsgId][$unCMindex]);
226 liveuser 3007
 
3 liveuser 3008
										#跳到下一則訊息
226 liveuser 3009
										continue;
3010
 
3 liveuser 3011
										}#if end
226 liveuser 3012
 
3013
									/*
3 liveuser 3014
									#debug
3015
									else{
226 liveuser 3016
 
3 liveuser 3017
										var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["toUserId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toUserId"]);
3018
										var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["toId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toId"]);
3019
										var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["msg"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["msg"]);
226 liveuser 3020
 
3 liveuser 3021
										}#else end
3022
									*/
226 liveuser 3023
 
3 liveuser 3024
									}#if end
226 liveuser 3025
 
3 liveuser 3026
								#debug
3027
								#var_dump("index:".$targetMsgId.print_r($this->unConfirmMsg[$targetMsgId],true));
226 liveuser 3028
 
3 liveuser 3029
								#另存 ConnectionInterface 物件
3030
								$connObject=$this->connInfo[$cInfo["id"]]["conn"];
226 liveuser 3031
 
3 liveuser 3032
								#包裝訊息
3033
								#"type"為"msg"
3034
								#"index"為$cInfo["id"]
3035
								#"data"為實際的訊息內容
3036
								$packedMsg=array("type"=>"msg","index"=>$unCMindex,"data"=>$unCMinfo["msg"]);
226 liveuser 3037
 
3 liveuser 3038
								#傳送包裝好的訊息給對方
3039
								$connObject->send(json_encode($packedMsg));
226 liveuser 3040
 
3 liveuser 3041
								#一次只送一則訊息
3042
								break;
226 liveuser 3043
 
3 liveuser 3044
								}#foreach end
226 liveuser 3045
 
3 liveuser 3046
							}#else end
226 liveuser 3047
 
3048
						}#else end
3049
 
3 liveuser 3050
					}#else end
226 liveuser 3051
 
3 liveuser 3052
				}#foreach end
226 liveuser 3053
 
3 liveuser 3054
			}#if end
226 liveuser 3055
 
3 liveuser 3056
		#反之沒有講話的對象
3057
		else{
226 liveuser 3058
 
3 liveuser 3059
			$msg="Message 「".$msg."」 will not be received by any one";
226 liveuser 3060
 
3 liveuser 3061
			#提示server訊息被拋棄
3062
			echo $msg;
226 liveuser 3063
 
3 liveuser 3064
			#包裝訊息
226 liveuser 3065
			#"type"為"status"
3066
			#"status"為"false"
3 liveuser 3067
			#"data"為實際的訊息內容
3068
			$packedMsg=array("type"=>"status","status"=>"false","data"=>$msg);
226 liveuser 3069
 
3 liveuser 3070
			#設置要給自己看的訊息
3071
			$from->send(json_encode($packedMsg));
226 liveuser 3072
 
3 liveuser 3073
			}#else end
226 liveuser 3074
 
3 liveuser 3075
		}#function onMessage end
3076
 
3077
	#當clinet的連線斷掉前
3078
    	public function onClose(ConnectionInterface $conn){
226 liveuser 3079
 
3 liveuser 3080
		// The connection is closed, remove it, as we can no longer send it messages
3081
        	$this->clients->detach($conn);
226 liveuser 3082
 
3 liveuser 3083
		#提示 server 連線已結束
3084
        	echo "Connection {$conn->resourceId} has disconnected\n";
226 liveuser 3085
 
3 liveuser 3086
		#取得斷線目標的待確認訊息id
3087
		$msgId=$this->connInfo[$conn->resourceId]["msgId"];
226 liveuser 3088
 
3 liveuser 3089
		#移除目標id的待確認訊息
3090
		unset($this->unConfirmMsg[$msgId]);
226 liveuser 3091
 
3 liveuser 3092
		#移除連線的資訊
3093
		unset($this->connInfo[$conn->resourceId]);
226 liveuser 3094
 
3 liveuser 3095
		}#function onClose end
3096
 
3097
		#當出現錯誤時
3098
    		public function onError(ConnectionInterface $conn, \Exception $e){
226 liveuser 3099
 
3 liveuser 3100
		#提示出現連線錯誤
3101
		echo "An error has occurred: {$e->getMessage()}\n";
3102
 
3103
		#關閉socket
3104
        	$conn->close();
226 liveuser 3105
 
3 liveuser 3106
		}#fucntion onError end
226 liveuser 3107
 
3 liveuser 3108
	}#class ChatV2 end
226 liveuser 3109
 
3 liveuser 3110
#用 ChatV3 類別來實作 MessageComponentInterface 界面,
3111
#新增可以對Server下達command的功能
3112
#修正要設置的msgId不存在時不會回傳錯誤訊息且繼續執行的問題
3113
class ChatV3 implements MessageComponentInterface{
226 liveuser 3114
 
3 liveuser 3115
	#初始化儲存使用者資訊的陣列
226 liveuser 3116
	private $connInfo=array();
3117
 
3 liveuser 3118
	#初始化儲存未傳送出去的留言訊息
3119
	#"fromId",訊息來源的id
3120
	#"toId",訊息目的的id
3121
	#"fromUserId",訊息來源的userId
3122
	#"toUserId",訊息目標的userId
3123
	#"msg",傳送的訊息
3124
	private $unSendMsg=array();
226 liveuser 3125
 
3 liveuser 3126
	#初始化儲存待確認是否送達到對方的訊息
3127
	#$unConfirmMsg[$id],$id為訊息接收方,亦即收到訊息後,要跟server說有收到訊息者.
3128
	#"fromId",訊息來源的id
3129
	#"toId",訊息目的的id
3130
	#"fromUserId",訊息來源的userId
3131
	#"toUserId",訊息目標的userId
3132
	#"msg",傳送的訊息
3133
	private $unConfirmMsg=array();
226 liveuser 3134
 
3 liveuser 3135
	#初始化一開始尚未能夠連線到資料庫
3136
	private static $dbTouchable=false;
226 liveuser 3137
 
3 liveuser 3138
	#初始化db的位置
226 liveuser 3139
	public static $dbAddress="localhost";
3140
 
3 liveuser 3141
	#初始化連線db用的帳戶
3142
	public static $dbAccount="root";
226 liveuser 3143
 
3 liveuser 3144
	#初始化連線的db名稱
3145
	public static $dbName="test";
226 liveuser 3146
 
3 liveuser 3147
	#初始化連線db時用的密碼
3148
	public static $dbPassword="";
226 liveuser 3149
 
3 liveuser 3150
	#初始化連線db的哪個資料表
3151
	public static $memberTableName="member";
226 liveuser 3152
 
3 liveuser 3153
	#初始化登入時用來驗證帳號的資料表欄位名稱
3154
	public static $accountCol="account";
226 liveuser 3155
 
3 liveuser 3156
	#初始化登入時用來驗證密碼的資料表欄位名稱,設為""代表不用密碼來認證
3157
	public static $passwordCol="password";
226 liveuser 3158
 
3 liveuser 3159
	#初始化用來儲存 __FILE__ 內容的變數 fileArgu
226 liveuser 3160
	public static $fileArgu=__FILE__;
3161
 
3 liveuser 3162
	#建構子
3163
	public function __construct(){
226 liveuser 3164
 
3 liveuser 3165
		#如果尚未可以上資料庫
3166
		if(!(self::$dbTouchable)){
226 liveuser 3167
 
3 liveuser 3168
			#嘗試連線到目標資料庫.資料表
3169
			#涵式說明:
3170
			#一次取得資料庫、表的資料
3171
			#回傳的結果
3172
			#$result["status"],執行結果"true"為成功;"false"為執行失敗。
3173
			#$result["error"],錯誤訊息陣列。
3174
			#$result["function"],當前執行的漢書名稱.
3175
			#$result["dataColumnName"],抓取的資料欄位名稱陣列.
3176
				#$result["dataColumnName"][$i]代表第$i+1個欄位名稱
3177
			#$result["dataContent"],爲資料的內容。
3178
			#$result["dataContent"][$conf["WhereColumnName"][$i]][$dataSetNum]
3179
				#$dataSetNum 爲第$dataSetNum+1筆資料
3180
				#$conf["WhereColumnName"][$i] 爲第 $i+1 個欄位的名稱
3181
			#$result["dataCount"],爲取得的資料筆數。
3182
			#$result["sql"],執行的sql字串.
3183
			#必填的參數:
3184
			$conf["db::fastGetDbData"]["dbAddress"]=self::$dbAddress;#爲dbServer的位置。
3185
			$conf["db::fastGetDbData"]["dbAccount"]=self::$dbAccount;#爲登入dbServer的帳號。
3186
			$conf["db::fastGetDbData"]["dbName"]=self::$dbName;#爲要存取的資料庫名稱
3187
			$conf["db::fastGetDbData"]["tableName"]=self::$memberTableName;#爲要存取的資料表名稱
3188
			$conf["db::fastGetDbData"]["columnYouWant"]=array("id",self::$accountCol);#你想要的欄位!,若設為「array("*")」則代表全部欄位.
226 liveuser 3189
 
3 liveuser 3190
			#如果 $passwordCol 不為空
3191
			if(self::$passwordCol!=""){
226 liveuser 3192
 
3 liveuser 3193
				#加上密碼欄位
3194
				$conf["db::fastGetDbData"]["columnYouWant"][]=self::$passwordCol;
226 liveuser 3195
 
3 liveuser 3196
				}#if end
226 liveuser 3197
 
3 liveuser 3198
			#可省略的參數:
3199
			$conf["db::fastGetDbData"]["dbPassword"]=self::$dbPassword;#爲要存取dbServer的密碼
3200
			#$conf["db::fastGetDbData"]["WhereColumnName"]=array("account","password");#用於判斷語句的欄位項目陣列。
3201
			#$conf["db::fastGetDbData"]["WhereColumnValue"]=array($ac,$pw);#用於判斷語句的欄位數值陣列,若與LIKE搭配,則可以在關鍵自字串的左右名加上「%」符號,這樣就可以搜尋具有該字串的內容。
3202
			#$conf["WhereColumnCombine"]=array("");#用於判斷語句當中需要()起來的判斷式,須爲陣列值,"s"代表「(」,"e"代表「)」 ,若無則須設爲""。
3203
			#$conf["WhereColumnOperator"]=array("");#用於判斷語句的比較符號陣列,可以用的符號有「"="、"!="、">"、"<"、"LIKE"、"NOT LIKE"」,預設都爲「=」。
3204
			#$conf["WhereColumnAndOr"]=array("");#用於判斷語句條件之間成立的條件是AND還是OR,須爲陣列值。其數量應爲要判斷的欄位數量減一。
3205
			#$conf["orderItem"]="";#爲排序的項目依據,若要用隨機抽樣,可以用"rand()",可省略。
3206
			#$conf["ascORdesc"]="";#爲要低增還是遞減排序,asc爲遞增;desc爲遞減。
3207
			#$conf["numberStart"]="0";#為從第幾筆開始讀取,預設為0,代筆第一筆。
3208
			$conf["db::fastGetDbData"]["numLimit"]="1";#為要取幾筆資料,可以省略,省略則表示不限制數目。
3209
			#$conf["groupBy"]=array("");#爲要以哪幾個欄爲作爲分羣的依據(欄位相同的數值僅會取出一筆)。
3210
			#備註:
3211
			#建議在查詢資料前,能夠檢查是否每個欄位都存在.
3212
			$fastGetDbData=db::fastGetDbData($conf["db::fastGetDbData"]);
3213
			unset($conf["db::fastGetDbData"]);
226 liveuser 3214
 
3 liveuser 3215
			#如果取得資料失敗
3216
			if($fastGetDbData["status"]==="false"){
226 liveuser 3217
 
3 liveuser 3218
				#設置執行失敗
3219
				$result["status"]="false";
226 liveuser 3220
 
3 liveuser 3221
				#設置執行錯誤訊息
3222
				$result["error"]=$fastGetDbData;
226 liveuser 3223
 
3 liveuser 3224
				#印出debug訊息
3225
				var_dump($result);
226 liveuser 3226
 
3 liveuser 3227
				#結束程式
3228
				exit;
226 liveuser 3229
 
3 liveuser 3230
				}#if end
226 liveuser 3231
 
3 liveuser 3232
			#連線成功,將self::dbTouchable設為true
3233
			self::$dbTouchable=true;
226 liveuser 3234
 
3 liveuser 3235
			}#if end
226 liveuser 3236
 
3 liveuser 3237
		$this->clients = new \SplObjectStorage;
3238
 
3239
		}#funciton __construct end
226 liveuser 3240
 
3 liveuser 3241
	#當用戶與伺服器建立連線時
3242
	public function onOpen(ConnectionInterface $conn){
226 liveuser 3243
 
3 liveuser 3244
		// Store the new connection to send messages to later
3245
		 $this->clients->attach($conn);
3246
 
3247
		#提示server有clent連上web socket.
3248
		echo "New connection! ({$conn->resourceId})\n";
3249
 
3250
		#用client的id為index來儲存額外的資訊
3251
		#元素 "conn" 代表已經建立連線的ConnectionInterface物件
3252
		#元素 "talkTo" 代表要跟誰講話
3253
		#元素 "userId" 代表辨識使用者的id
3254
		#元素 "loigin=array("ac","pw")" 代表client輸入的帳號與密碼
3255
		#元素 "msgId" 為用來識別待確認訊息的索引
3256
		#元素 "gotMsgId" 為用來識別是否已經設置過 msgId 了
3257
	 	#$this->connInfo[$conn->resourceId]=array("conn"=>$conn,"talkTo"=>array(),"userId"=>"","login"=>array("ac"=>"","pw"=>""),"type"=>"");
3258
		$this->connInfo[$conn->resourceId]=array("conn"=>$conn,"talkTo"=>array(),"userId"=>"","login"=>array("ac"=>"","pw"=>""),"msgId"=>"","gotMsgId"=>"false");
226 liveuser 3259
 
3 liveuser 3260
		#包裝訊息
226 liveuser 3261
		#"type"為"login"
3262
		#"status"為"true"
3 liveuser 3263
		#"data"為實際的訊息內容
3264
		$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your account! ex:account:ws1");
226 liveuser 3265
 
3266
		#提示輸入帳號
3 liveuser 3267
		$conn->send(json_encode($packedMsg));
226 liveuser 3268
 
3 liveuser 3269
		}#function onOpen end
3270
 
3271
	#當伺服器收到訊息時
3272
	public function onMessage(ConnectionInterface $from, $msg){
226 liveuser 3273
 
3 liveuser 3274
		#debug
3275
		#$array=array("msgId"=>$this->connInfo[$from->resourceId]["msgId"],"resourceId"=>$from->resourceId,"msg"=>$msg);
3276
		#var_dump($array);
226 liveuser 3277
 
3 liveuser 3278
		#如果該連線沒有使用者id
3279
		if($this->connInfo[$from->resourceId]["userId"]===""){
226 liveuser 3280
 
3 liveuser 3281
			#代表需要認證,認證的會員資料表 slef::memberTableName,需要以下三個欄位.
3282
			#id		  自訂
3283
			#account  自訂
3284
			#password varchar(33)
226 liveuser 3285
 
3 liveuser 3286
			/*
226 liveuser 3287
 
3 liveuser 3288
			#如果尚未輸入用戶端類型
3289
			if($this->connInfo[$from->resourceId]["type"]===""){
226 liveuser 3290
 
3 liveuser 3291
				#如果 $msg 長度大於 "type:"
3292
				if(strlen($msg) > strlen("type:")){
226 liveuser 3293
 
3 liveuser 3294
					#檢查有無前置字元 "account:"
3295
					#函式說明:
3296
					#將字串特定關鍵字與其前面的內容剔除
3297
					#回傳結果:
3298
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3299
					#$result["error"],錯誤訊息陣列.
3300
					#$result["warning"],警告訊息鎮列.
3301
					#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
3302
					#$result["function"],當前執行的函數名稱.
3303
					#$result["oriStr"],要處理的原始字串內容.
3304
					#$result["content"],處理好的的字串內容.
3305
					#必填的參數:
3306
					$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$msg;#要處理的字串.
3307
					$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="type:";#特定字串.
3308
					$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
3309
					unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 3310
 
3 liveuser 3311
					#如果移除前置字元失敗
3312
					if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 3313
 
3 liveuser 3314
						#設置執行失敗
3315
						$result["status"]="false";
226 liveuser 3316
 
3 liveuser 3317
						#設置執行錯誤訊息
3318
						$result["error"]=$delStrBeforeKeyWord;
226 liveuser 3319
 
3 liveuser 3320
						#回傳結果
3321
						return $result;
226 liveuser 3322
 
3 liveuser 3323
						}#if end
226 liveuser 3324
 
3 liveuser 3325
					#如果有符合條件的前置字元
3326
					if($delStrBeforeKeyWord["founded"]==="true"){
226 liveuser 3327
 
3 liveuser 3328
						#儲存用戶端類型
3329
						$this->connInfo[$from->resourceId]["type"]=$delStrBeforeKeyWord["content"];
226 liveuser 3330
 
3 liveuser 3331
						}#if end
226 liveuser 3332
 
3 liveuser 3333
					#反之
3334
					else{
226 liveuser 3335
 
3 liveuser 3336
						#提示輸入用戶端類型
3337
						$from->send(json_encode("Please input your type! ex:type:user"));
226 liveuser 3338
 
3 liveuser 3339
						#結束程式
3340
						return true;
226 liveuser 3341
 
3 liveuser 3342
						}#else end
226 liveuser 3343
 
3 liveuser 3344
					}#if end
226 liveuser 3345
 
3 liveuser 3346
				#反之代表輸入錯誤格式的type
3347
				else{
226 liveuser 3348
 
3 liveuser 3349
					#提示輸入用戶端類型
3350
					$from->send(json_encode("Please input your type! ex:type:user"));
226 liveuser 3351
 
3 liveuser 3352
					#結束程式
3353
					return true;
226 liveuser 3354
 
3 liveuser 3355
					}#else end
226 liveuser 3356
 
3 liveuser 3357
				}#if end
226 liveuser 3358
 
3 liveuser 3359
			#如果用戶端是"user"
3360
			if($this->connInfo[$from->resourceId]["type"]==="user"){
226 liveuser 3361
 
3 liveuser 3362
				#...
226 liveuser 3363
 
3 liveuser 3364
				}#if end
226 liveuser 3365
 
3 liveuser 3366
			#反之如果用戶端是"device"
3367
			else if($this->connInfo[$from->resourceId]["type"]==="device"){
226 liveuser 3368
 
3 liveuser 3369
				#...
226 liveuser 3370
 
3 liveuser 3371
				}#if end
226 liveuser 3372
 
3 liveuser 3373
			*/
226 liveuser 3374
 
3 liveuser 3375
			#如果尚未輸入帳戶
3376
			if($this->connInfo[$from->resourceId]["login"]["ac"]===""){
226 liveuser 3377
 
3 liveuser 3378
				#如果 $msg 長度大於 "account:"
3379
				if(strlen($msg) > strlen("account:")){
226 liveuser 3380
 
3 liveuser 3381
					#檢查有無前置字元 "account:"
3382
					#函式說明:
3383
					#將字串特定關鍵字與其前面的內容剔除
3384
					#回傳結果:
3385
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3386
					#$result["error"],錯誤訊息陣列.
3387
					#$result["warning"],警告訊息鎮列.
3388
					#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
3389
					#$result["function"],當前執行的函數名稱.
3390
					#$result["oriStr"],要處理的原始字串內容.
3391
					#$result["content"],處理好的的字串內容.
3392
					#必填的參數:
3393
					$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$msg;#要處理的字串.
3394
					$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="account:";#特定字串.
3395
					$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
3396
					unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 3397
 
3 liveuser 3398
					#如果移除前置字元失敗
3399
					if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 3400
 
3 liveuser 3401
						#設置執行失敗
3402
						$result["status"]="false";
226 liveuser 3403
 
3 liveuser 3404
						#設置執行錯誤訊息
3405
						$result["error"]=$delStrBeforeKeyWord;
226 liveuser 3406
 
3 liveuser 3407
						#回傳結果
3408
						return $result;
226 liveuser 3409
 
3 liveuser 3410
						}#if end
226 liveuser 3411
 
3 liveuser 3412
					#如果有符合條件的前置字元
3413
					if($delStrBeforeKeyWord["founded"]==="true"){
226 liveuser 3414
 
3 liveuser 3415
						#儲存帳戶
3416
						$this->connInfo[$from->resourceId]["login"]["ac"]=$delStrBeforeKeyWord["content"];
226 liveuser 3417
 
3 liveuser 3418
						}#if end
226 liveuser 3419
 
3420
					#反之代表格式錯誤
3 liveuser 3421
					else{
226 liveuser 3422
 
3 liveuser 3423
						#包裝訊息
226 liveuser 3424
						#"type"為"login"
3425
						#"status"為"true"
3 liveuser 3426
						#"data"為實際的訊息內容
3427
						$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your account! ex:account:ws1");
226 liveuser 3428
 
3429
						#提示輸入帳號
3 liveuser 3430
						$from->send(json_encode($packedMsg));
226 liveuser 3431
 
3 liveuser 3432
						#結束程式
3433
						return true;
226 liveuser 3434
 
3 liveuser 3435
						}#else end
226 liveuser 3436
 
3 liveuser 3437
					}#if end
226 liveuser 3438
 
3 liveuser 3439
				#反之代表輸入錯誤格式的account
3440
				else{
226 liveuser 3441
 
3 liveuser 3442
					#包裝訊息
226 liveuser 3443
					#"type"為"login"
3444
					#"status"為"true"
3 liveuser 3445
					#"data"為實際的訊息內容
3446
					$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your account! ex:account:ws1");
226 liveuser 3447
 
3448
					#提示輸入帳號
3 liveuser 3449
					$from->send(json_encode($packedMsg));
226 liveuser 3450
 
3 liveuser 3451
					#結束程式
3452
					return true;
226 liveuser 3453
 
3 liveuser 3454
					}#else end
226 liveuser 3455
 
3 liveuser 3456
				}#if end
226 liveuser 3457
 
3 liveuser 3458
			#如果有設置密碼欄位
3459
			if(self::$passwordCol!==""){
226 liveuser 3460
 
3 liveuser 3461
				#如果尚未輸入密碼
3462
				if($this->connInfo[$from->resourceId]["login"]["pw"]===""){
226 liveuser 3463
 
3 liveuser 3464
					#$msg 長度大於 "password:"
3465
					if(strlen($msg) > strlen("password:")){
226 liveuser 3466
 
3 liveuser 3467
						#檢查有無前置字元 "password:"
3468
						#函式說明:
3469
						#將字串特定關鍵字與其前面的內容剔除
3470
						#回傳結果:
3471
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3472
						#$result["error"],錯誤訊息陣列.
3473
						#$result["warning"],警告訊息鎮列.
3474
						#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
3475
						#$result["function"],當前執行的函數名稱.
3476
						#$result["oriStr"],要處理的原始字串內容.
3477
						#$result["content"],處理好的的字串內容.
3478
						#必填的參數:
3479
						$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$msg;#要處理的字串.
3480
						$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="password:";#特定字串.
3481
						$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
3482
						unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 3483
 
3 liveuser 3484
						#如果移除前置字元失敗
3485
						if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 3486
 
3 liveuser 3487
							#設置執行失敗
3488
							$result["status"]="false";
226 liveuser 3489
 
3 liveuser 3490
							#設置執行錯誤訊息
3491
							$result["error"]=$delStrBeforeKeyWord;
226 liveuser 3492
 
3 liveuser 3493
							#回傳結果
3494
							return $result;
226 liveuser 3495
 
3 liveuser 3496
							}#if end
226 liveuser 3497
 
3 liveuser 3498
						#如果有符合條件的前置字元
3499
						if($delStrBeforeKeyWord["founded"]==="true"){
226 liveuser 3500
 
3 liveuser 3501
							#儲存密碼
3502
							$this->connInfo[$from->resourceId]["login"]["pw"]=$delStrBeforeKeyWord["content"];
226 liveuser 3503
 
3 liveuser 3504
							}#if end
226 liveuser 3505
 
3 liveuser 3506
						#反之代表格式錯誤
3507
						else{
226 liveuser 3508
 
3 liveuser 3509
							#包裝訊息
226 liveuser 3510
							#"type"為"login"
3511
							#"status"為"true"
3 liveuser 3512
							#"data"為實際的訊息內容
3513
							$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your password! ex:password:ws1");
226 liveuser 3514
 
3515
							#提示輸入密碼
3 liveuser 3516
							$from->send(json_encode($packedMsg));
226 liveuser 3517
 
3 liveuser 3518
							#結束程式
3519
							return true;
226 liveuser 3520
 
3 liveuser 3521
							}#else end
226 liveuser 3522
 
3 liveuser 3523
						}#if end
226 liveuser 3524
 
3 liveuser 3525
					#反之代表格式錯誤
3526
					else{
226 liveuser 3527
 
3 liveuser 3528
						#包裝訊息
226 liveuser 3529
						#"type"為"login"
3530
						#"status"為"true"
3 liveuser 3531
						#"data"為實際的訊息內容
3532
						$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your password! ex:password:ws1");
226 liveuser 3533
 
3534
						#提示輸入密碼
3 liveuser 3535
						$from->send(json_encode($packedMsg));
226 liveuser 3536
 
3 liveuser 3537
						#結束程式
3538
						return true;
226 liveuser 3539
 
3 liveuser 3540
						}#else end
226 liveuser 3541
 
3 liveuser 3542
					}#if end
226 liveuser 3543
 
3 liveuser 3544
				}#if end
226 liveuser 3545
 
3 liveuser 3546
			#如果已經輸入帳號了
3547
			if($this->connInfo[$from->resourceId]["login"]["ac"]!=""){
226 liveuser 3548
 
3 liveuser 3549
				#設置可以進行驗證
3550
				$startAuth=true;
226 liveuser 3551
 
3 liveuser 3552
				#另存帳號
3553
				$ac=$this->connInfo[$from->resourceId]["login"]["ac"];
226 liveuser 3554
 
3 liveuser 3555
				#初始化密碼
3556
				$pw="";
226 liveuser 3557
 
3 liveuser 3558
				#如果有設置密碼欄位
3559
				if(self::$passwordCol!==""){
226 liveuser 3560
 
3 liveuser 3561
					#如果client已經輸入密碼了
3562
					if($this->connInfo[$from->resourceId]["login"]["pw"]!=""){
226 liveuser 3563
 
3 liveuser 3564
						#另存密碼
3565
						$pw=md5($this->connInfo[$from->resourceId]["login"]["pw"]);
226 liveuser 3566
 
3 liveuser 3567
						}#if end
226 liveuser 3568
 
3 liveuser 3569
					#反之
3570
					else{
226 liveuser 3571
 
3 liveuser 3572
						#設置尚不能進行認證
3573
						$startAuth=false;
226 liveuser 3574
 
3 liveuser 3575
						}#else end
226 liveuser 3576
 
3 liveuser 3577
					}#if end
226 liveuser 3578
 
3 liveuser 3579
				#如果尚不能進行驗證
3580
				if(!$startAuth){
226 liveuser 3581
 
3 liveuser 3582
					#結束程式
3583
					return true;
226 liveuser 3584
 
3 liveuser 3585
					}#if end
226 liveuser 3586
 
3 liveuser 3587
				#檢查有無符合的帳戶密碼
3588
				#涵式說明:
3589
				#一次取得資料庫、表的資料
3590
				#回傳的結果
3591
				#$result["status"],執行結果"true"為成功;"false"為執行失敗。
3592
				#$result["error"],錯誤訊息陣列。
3593
				#$result["function"],當前執行的漢書名稱.
3594
				#$result["dataColumnName"],抓取的資料欄位名稱陣列.
3595
					#$result["dataColumnName"][$i]代表第$i+1個欄位名稱
3596
				#$result["dataContent"],爲資料的內容。
3597
				#$result["dataContent"][$conf["WhereColumnName"][$i]][$dataSetNum]
3598
					#$dataSetNum 爲第$dataSetNum+1筆資料
3599
					#$conf["WhereColumnName"][$i] 爲第 $i+1 個欄位的名稱
3600
				#$result["dataCount"],爲取得的資料筆數。
3601
				#$result["sql"],執行的sql字串.
3602
				#必填的參數:
3603
				$conf["db::fastGetDbData"]["dbAddress"]=self::$dbAddress;#爲dbServer的位置。
3604
				$conf["db::fastGetDbData"]["dbAccount"]=self::$dbAccount;#爲登入dbServer的帳號。
3605
				$conf["db::fastGetDbData"]["dbName"]=self::$dbName;#爲要存取的資料庫名稱
3606
				$conf["db::fastGetDbData"]["tableName"]=self::$memberTableName;#爲要存取的資料表名稱
3607
				$conf["db::fastGetDbData"]["columnYouWant"]=array("id");#你想要的欄位!,若設為「array("*")」則代表全部欄位.
3608
				#可省略的參數:
3609
				$conf["db::fastGetDbData"]["dbPassword"]=self::$dbPassword;#爲要存取dbServer的密碼
3610
				$conf["db::fastGetDbData"]["WhereColumnName"]=array(self::$accountCol);#用於判斷語句的欄位項目陣列。
3611
				$conf["db::fastGetDbData"]["WhereColumnValue"]=array($ac);#用於判斷語句的欄位數值陣列,若與LIKE搭配,則可以在關鍵自字串的左右名加上「%」符號,這樣就可以搜尋具有該字串的內容。
226 liveuser 3612
 
3 liveuser 3613
				#如果有輸入密碼
3614
				if($pw!==""){
226 liveuser 3615
 
3 liveuser 3616
					#新增要判斷 self::$password 欄位,是否有於 $pw
3617
					$conf["db::fastGetDbData"]["WhereColumnName"][]=self::$passwordCol;
3618
					$conf["db::fastGetDbData"]["WhereColumnValue"][]=$pw;
226 liveuser 3619
 
3 liveuser 3620
					}#if end
226 liveuser 3621
 
3 liveuser 3622
				#$conf["WhereColumnCombine"]=array("");#用於判斷語句當中需要()起來的判斷式,須爲陣列值,"s"代表「(」,"e"代表「)」 ,若無則須設爲""。
3623
				#$conf["WhereColumnOperator"]=array("");#用於判斷語句的比較符號陣列,可以用的符號有「"="、"!="、">"、"<"、"LIKE"、"NOT LIKE"」,預設都爲「=」。
3624
				#$conf["WhereColumnAndOr"]=array("");#用於判斷語句條件之間成立的條件是AND還是OR,須爲陣列值。其數量應爲要判斷的欄位數量減一。
3625
				#$conf["orderItem"]="";#爲排序的項目依據,若要用隨機抽樣,可以用"rand()",可省略。
3626
				#$conf["ascORdesc"]="";#爲要低增還是遞減排序,asc爲遞增;desc爲遞減。
3627
				#$conf["numberStart"]="0";#為從第幾筆開始讀取,預設為0,代筆第一筆。
3628
				$conf["db::fastGetDbData"]["numLimit"]="1";#為要取幾筆資料,可以省略,省略則表示不限制數目。
3629
				#$conf["groupBy"]=array("");#爲要以哪幾個欄爲作爲分羣的依據(欄位相同的數值僅會取出一筆)。
3630
				#備註:
3631
				#建議在查詢資料前,能夠檢查是否每個欄位都存在.
3632
				$fastGetDbData=db::fastGetDbData($conf["db::fastGetDbData"]);
3633
				unset($conf["db::fastGetDbData"]);
226 liveuser 3634
 
3 liveuser 3635
				#如果取得資料失敗
3636
				if($fastGetDbData["status"]==="false"){
226 liveuser 3637
 
3 liveuser 3638
					#設置執行失敗
3639
					$result["status"]="false";
226 liveuser 3640
 
3 liveuser 3641
					#設置執行錯誤訊息
226 liveuser 3642
					$result["error"]=$fastGetDbData;
3643
 
3 liveuser 3644
					#提示server有資料庫錯誤
3645
					echo "dbError!";
226 liveuser 3646
 
3 liveuser 3647
					#結束程式
3648
					exit;
226 liveuser 3649
 
3 liveuser 3650
					}#if end
226 liveuser 3651
 
3 liveuser 3652
				#如果沒有一筆資料
3653
				if($fastGetDbData["dataCount"]!==1){
226 liveuser 3654
 
3 liveuser 3655
					#代表登入失敗
226 liveuser 3656
 
3 liveuser 3657
					#清空登入用的帳戶
3658
					$this->connInfo[$from->resourceId]["login"]["ac"]="";
226 liveuser 3659
 
3 liveuser 3660
					#清空登入用的密碼
3661
					$this->connInfo[$from->resourceId]["login"]["pw"]="";
226 liveuser 3662
 
3 liveuser 3663
					#包裝訊息
226 liveuser 3664
					#"type"為"login"
3665
					#"status"為"false"
3 liveuser 3666
					#"data"為實際的訊息內容
3667
					$packedMsg=array("type"=>"login","status"=>"false","data"=>"Login failed, please input account. ex:account:ws1");
226 liveuser 3668
 
3669
					#提示登入失敗
3 liveuser 3670
					$from->send(json_encode($packedMsg));
226 liveuser 3671
 
3 liveuser 3672
					#執行到這即可
3673
					return true;
226 liveuser 3674
 
3 liveuser 3675
					}#if end
226 liveuser 3676
 
3 liveuser 3677
				#反之代表帳戶資訊正確
3678
				else{
226 liveuser 3679
 
3 liveuser 3680
					#設置 $myUserId
3681
					$myUserId=$this->connInfo[$from->resourceId]["userId"]=$fastGetDbData["dataContent"]["id"][0];
226 liveuser 3682
 
3 liveuser 3683
					#設置 $myId
3684
					$myId=$from->resourceId;
226 liveuser 3685
 
3 liveuser 3686
					#初始化msgId的部份內容
3687
					$msgId=$myUserId."-";
226 liveuser 3688
 
3 liveuser 3689
					#初始化儲存msgId的陣列
3690
					$msgIdArray=array();
226 liveuser 3691
 
3 liveuser 3692
					#取得所有client的msgId
3693
					foreach($this->connInfo as $clientInfoArray){
226 liveuser 3694
 
3 liveuser 3695
						#如果msgId不為""
3696
						if($clientInfoArray["msgId"]!==""){
226 liveuser 3697
 
3 liveuser 3698
							#取得msgId
3699
							$msgIdArray[]=$clientInfoArray["msgId"];
226 liveuser 3700
 
3 liveuser 3701
							}#if end
226 liveuser 3702
 
3 liveuser 3703
						}#foreach end
226 liveuser 3704
 
3 liveuser 3705
					#如果尚未產生完整的msgId或msgId有重複
3706
					while($msgId===$myUserId."-" || in_array($msgId,$msgIdArray)){
226 liveuser 3707
 
3 liveuser 3708
						#涵式說明:
3709
						#建立以圖片(PNG格式)呈現的驗證碼.
3710
						#回傳的解果:
3711
						#$result["status"],執行是否正常,"true"代表執行成功,"false"代表執行失敗.
3712
						#$result["error"],錯誤訊息.
3713
						#$result["function"],檔前執行的函數名稱.
3714
						#$result["randNumberWord"],傳驗證碼的內容.
3715
						#$result["imgAddress"],圖片的位置與名稱.
3716
						#必填的參數:
3717
						#$conf["imgAddressAndName"],字串,爲驗證碼圖片儲存的位置與名稱,副檔名程式會自動產生
3718
						$conf["authenticate::validationCode"]["imgAddressAndName"]="no used!";
3719
						#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
3720
						$conf["authenticate::validationCode"]["fileArgu"]="no used!";
3721
						#可省略的參數:
3722
						#$conf["num"],字串,爲驗證碼的位數,請輸入阿拉伯數字,預設為"8"位數.
3723
						#$conf["num"]="8";
3724
						#$conf["disableImg"],字串,是否要取消驗證碼圖片的輸出,"true"為要取消,預設為"false"為不取消
3725
						$conf["authenticate::validationCode"]["disableImg"]="true";
3726
						#$conf["imgToData"],字串,預設為"true"代表將圖片轉存成base64圖片,並將原始圖片移除;反之為"false"
3727
						#$conf["imgToData"]="true";
3728
						$validationCode=authenticate::validationCode($conf["authenticate::validationCode"]);
3729
						unset($conf["authenticate::validationCode"]);
226 liveuser 3730
 
3 liveuser 3731
						#如果產生亂數失敗
3732
						if($validationCode["status"]==="false"){
226 liveuser 3733
 
3 liveuser 3734
							#設置錯誤狀態
3735
							$result["status"]="false";
226 liveuser 3736
 
3 liveuser 3737
							#設置錯誤提示
3738
							$result["error"]=$validationCode;
226 liveuser 3739
 
3 liveuser 3740
							#印出錯誤訊息
3741
							var_dump($result);
226 liveuser 3742
 
3743
							#回傳結果
3744
							return $result;
3745
 
3 liveuser 3746
							}#if end
226 liveuser 3747
 
3748
						#儲存產生好的msgId
3 liveuser 3749
						$msgId=$myUserId."-".$validationCode["randNumberWord"];
226 liveuser 3750
 
3 liveuser 3751
						}#while end
226 liveuser 3752
 
3 liveuser 3753
					#設置獨立於id與userId且用於驗證訊息是否收到的msgId
3754
					$this->connInfo[$from->resourceId]["msgId"]=$msgId;
226 liveuser 3755
 
3 liveuser 3756
					#包裝訊息
226 liveuser 3757
					#"type"為"login"
3758
					#"status"為"true"
3 liveuser 3759
					#"data"為實際的訊息內容
3760
					$packedMsg=array("type"=>"login","status"=>"true","data"=>"Login successfully!");
226 liveuser 3761
 
3 liveuser 3762
					#提示登入成功
3763
					$from->send(json_encode($packedMsg));
226 liveuser 3764
 
3 liveuser 3765
					#檢查是否有訊息是要給自己的
3766
					foreach($this->unSendMsg as $index => $historyMsg){
226 liveuser 3767
 
3 liveuser 3768
						#如果有要給自己的訊息
3769
						if($myUserId===$historyMsg["toUserId"]){
226 liveuser 3770
 
3 liveuser 3771
							#包裝訊息
226 liveuser 3772
							#"type"為"unSendMsg?"
3773
							#"status"為"true"
3 liveuser 3774
							#"data"為實際的訊息內容
3775
							$packedMsg=array("type"=>"unSendMsg?","status"=>"true","data"=>$historyMsg["msg"]);
226 liveuser 3776
 
3 liveuser 3777
							#接收別人給的留言
3778
							$from->send(json_encode($packedMsg));
226 liveuser 3779
 
3 liveuser 3780
							#有幾個人在線上就執行幾次
3781
							foreach($this->connInfo as $toId => $cInfo){
226 liveuser 3782
 
3 liveuser 3783
								#如果是自己
3784
								if($myId===$toId ){
226 liveuser 3785
 
3 liveuser 3786
									#跳過
3787
									continue;
226 liveuser 3788
 
3 liveuser 3789
									}#if end
226 liveuser 3790
 
3 liveuser 3791
								#如果留言的對象有在線上
3792
								if($historyMsg["fromUserId"]===$cInfo["userId"]){
226 liveuser 3793
 
3 liveuser 3794
									#檢查對方是否已經在自己的通話清單裡面了
226 liveuser 3795
 
3 liveuser 3796
									#初始化要將對方加到自己的對話清單裡面
3797
									$add=false;
226 liveuser 3798
 
3 liveuser 3799
									#根據自己的每個通話對象
3800
									foreach($this->connInfo[$myId]["talkTo"] as $myToIndex=>$myToCinfo ){
226 liveuser 3801
 
3 liveuser 3802
										#如果對對方已經存在於自己的對話清單裡面了
3803
										if($myToCinfo["userId"]===$historyMsg["fromUserId"] && $myId===$historyMsg["fromId"]){
226 liveuser 3804
 
3 liveuser 3805
											#設置不要將對方加到自己的對話清單裡面
3806
											$add=false;
226 liveuser 3807
 
3 liveuser 3808
											#跳出foreach
3809
											break;
226 liveuser 3810
 
3 liveuser 3811
											}#if end
226 liveuser 3812
 
3 liveuser 3813
										}#foreach end
226 liveuser 3814
 
3 liveuser 3815
									#如果要將對方加到自己的對話清單裡面
3816
									if($add){
226 liveuser 3817
 
3 liveuser 3818
										#將對方加到自己的talkTo清單裡面
3819
										$this->connInfo[$myId]["talkTo"][]=array("id"=>$toId,"userId"=>$historyMsg["fromUserId"],"msgId"=>$this->connInfo[$toId]["msgId"]);
226 liveuser 3820
 
3 liveuser 3821
										}#if end
226 liveuser 3822
 
3 liveuser 3823
									#檢查自己有沒有在對方talkTo清單裡面
226 liveuser 3824
 
3 liveuser 3825
									#假設對方需要加自己到對話清單裡面
3826
									$add=true;
226 liveuser 3827
 
3 liveuser 3828
									#檢查通話對象能否跟自己對話
226 liveuser 3829
 
3 liveuser 3830
									#依據對方每個通話的對象
3831
									foreach($this->connInfo[$toId]["talkTo"] as $talkToIndex=>$talkToCinfo){
226 liveuser 3832
 
3 liveuser 3833
										#如果自己的userId已經在對方的對話清單裡面了
3834
										if($myUserId===$talkToCinfo["userId"]){
226 liveuser 3835
 
3 liveuser 3836
											#如果對方對話userId對應的id不在線上
3837
											if(!isset($this->connInfo[$toId])){
226 liveuser 3838
 
3 liveuser 3839
												#debug
226 liveuser 3840
												#var_dump("對方對話userId(".$talkToCinfo["userId"].")應的id(".$toId.")不在線上");
3841
 
3 liveuser 3842
												#檢查對方對話清單是否已經含有自己的id與userId了
226 liveuser 3843
 
3 liveuser 3844
												#假設對方對話清單沒有自己的id與userId
3845
												$update=true;
226 liveuser 3846
 
3 liveuser 3847
												#依據對方每個通話的對象
3848
												foreach($this->connInfo[$toId]["talkTo"] as $ceToIndex=>$ceToCinfo){
226 liveuser 3849
 
3850
													#如果對方對話清單已經含有自己的id與userId了
3 liveuser 3851
													if($ceToCinfo["id"]===$myId && $ceToCinfo["userId"]===$myUserId){
226 liveuser 3852
 
3 liveuser 3853
														#debug
3854
														#var_dump("對方對話清單已經含有自己的id(".$myId.")與userId了(".$myUserId.")");
226 liveuser 3855
 
3 liveuser 3856
														#設置不需要更新
3857
														$update=false;
226 liveuser 3858
 
3 liveuser 3859
														#debug
3860
														#var_dump($toId."要加".$myId."到通話清單裡面");
226 liveuser 3861
 
3 liveuser 3862
														#設置對方不需要加自己到對話清單裡面
3863
														$add=false;
226 liveuser 3864
 
3 liveuser 3865
														}#if end
226 liveuser 3866
 
3 liveuser 3867
													}#foreach end
226 liveuser 3868
 
3 liveuser 3869
												#如果對方對話清單沒有自己的id與userId與msgId
3870
												if($update){
226 liveuser 3871
 
3 liveuser 3872
													#debug
3873
													#var_dump($toId."要更新對話清單中索引為".$talkToIndex."的id(".$this->connInfo[$toId]["talkTo"][$talkToIndex]["id"].")為".$myId);
226 liveuser 3874
 
3 liveuser 3875
													#將自己在對方對話清單裡面的id改成現在的id
3876
													$this->connInfo[$toId]["talkTo"][$talkToIndex]["id"]=$myId;
226 liveuser 3877
 
3 liveuser 3878
													}#if end
226 liveuser 3879
 
3 liveuser 3880
												#反之對方對話清單已經有自己的id與userId
3881
												else{
226 liveuser 3882
 
3 liveuser 3883
													#移除對方該已經斷線的對話id
3884
													unset($this->connInfo[$toId]["talkTo"][$talkToIndex]);
226 liveuser 3885
 
3 liveuser 3886
													}#else end
226 liveuser 3887
 
3 liveuser 3888
												}#if end
226 liveuser 3889
 
3 liveuser 3890
											}#if end
226 liveuser 3891
 
3 liveuser 3892
										}#foreach end
226 liveuser 3893
 
3 liveuser 3894
									#如果對方需要加自己到對話清單裡面
3895
									if($add){
226 liveuser 3896
 
3 liveuser 3897
										#檢查對方每個通話對象
3898
										foreach($this->connInfo[$toId]["talkTo"] as $reCktIndex=>$reCktInfo){
226 liveuser 3899
 
3 liveuser 3900
											#如果已經有將自己加到對方的對話清單裡面
3901
											if($reCktInfo["id"]===$myId && $reCktInfo["userId"]===$myUserId){
226 liveuser 3902
 
3 liveuser 3903
												#設置不用將自己加到對方的對話清單裡面
3904
												$add=false;
226 liveuser 3905
 
3 liveuser 3906
												}#if end
226 liveuser 3907
 
3 liveuser 3908
											}#foreach end
226 liveuser 3909
 
3 liveuser 3910
										#如果對方需要加自己到對話清單裡面
3911
										if($add){
226 liveuser 3912
 
3 liveuser 3913
											#debug
3914
											#var_dump($toId."要加".$myId."(msgId為".$this->connInfo[$myId]["msgId"].")到通話清單裡面");
226 liveuser 3915
 
3 liveuser 3916
											#讓通話對象也可以傳送訊息回來
3917
											$this->connInfo[$toId]["talkTo"][]=array("id"=>$myId,"userId"=>$myUserId,"msgId"=>$this->connInfo[$myId]["msgId"]);
226 liveuser 3918
 
3 liveuser 3919
											}#if end
226 liveuser 3920
 
3 liveuser 3921
										}#if end
226 liveuser 3922
 
3 liveuser 3923
									}#if end
226 liveuser 3924
 
3 liveuser 3925
								}#foreach end
226 liveuser 3926
 
3 liveuser 3927
							#移除留言紀錄
3928
							unset($this->unSendMsg[$index]);
226 liveuser 3929
 
3 liveuser 3930
							}#if end
226 liveuser 3931
 
3 liveuser 3932
						}#foreach end
226 liveuser 3933
 
3 liveuser 3934
					#檢查線上是否有人想跟我對話
226 liveuser 3935
 
3 liveuser 3936
					#有幾個人在線上就執行幾次
3937
					foreach($this->connInfo as $toId => $cInfo){
226 liveuser 3938
 
3 liveuser 3939
						#如果是自己
3940
						if($myId===$toId){
226 liveuser 3941
 
3 liveuser 3942
							#跳過
3943
							continue;
226 liveuser 3944
 
3 liveuser 3945
							}#if end
226 liveuser 3946
 
3 liveuser 3947
						#該cliet目前再跟幾個人通話,就執行幾次
3948
						foreach($cInfo["talkTo"] as $tIndex=>$tInfo){
226 liveuser 3949
 
3 liveuser 3950
							#如果自己的userId在對方的對話清單裡面
3951
							if($myUserId===$tInfo["userId"]){
226 liveuser 3952
 
3 liveuser 3953
								#假設自己需要被對方加到對話清單裡面
3954
								$add=true;
226 liveuser 3955
 
3 liveuser 3956
								#檢查自己是否已經在對方的對話清單裡面
226 liveuser 3957
 
3 liveuser 3958
								#對方有幾個通話對象就執行幾次
3959
								foreach($this->connInfo[$toId]["talkTo"] as $toIndex=>$toCinfo){
226 liveuser 3960
 
3 liveuser 3961
									#如果自己已經在對方的對話清單裡面
3962
									if($myUserId===$toCinfo["userId"] && $myId===$toCinfo["id"]){
226 liveuser 3963
 
3 liveuser 3964
										#設置自己不需要被對方加到對話清單裡面
3965
										$add=false;
226 liveuser 3966
 
3 liveuser 3967
										#跳出迴圈
3968
										break;
226 liveuser 3969
 
3 liveuser 3970
										}#if end
226 liveuser 3971
 
3 liveuser 3972
									}#foreach end
226 liveuser 3973
 
3 liveuser 3974
								#另存針對自己userId的連線id
3975
								$oneIdOfMyUserid=$this->connInfo[$toId]["talkTo"][$tIndex]["id"];
226 liveuser 3976
 
3 liveuser 3977
								#如果對方對話清單裡面的用戶id不在線
3978
								if(!isset($this->connInfo[$oneIdOfMyUserid])){
226 liveuser 3979
 
3 liveuser 3980
									#假設要將自己在對方對話清單裡面的id改成現在的id
3981
									$update=true;
226 liveuser 3982
 
3 liveuser 3983
									#自己不需要被對方加到對話清單裡面
3984
									$add=false;
226 liveuser 3985
 
3 liveuser 3986
									#檢查自己的id是否已經在對方的對話id裡面
3987
									foreach($this->connInfo[$toId]["talkTo"] as $ceIndex=>$ceInfo){
226 liveuser 3988
 
3 liveuser 3989
										#如果自己的id已經在對方的對話清單裡面
3990
										if($myId===$ceInfo["id"]){
226 liveuser 3991
 
3 liveuser 3992
											#設置不要將自己在對方對話清單裡面的id改成現在的id(可以移除該對話id)
3993
											$update=false;
226 liveuser 3994
 
3 liveuser 3995
											#跳出迴圈
3996
											break;
226 liveuser 3997
 
3 liveuser 3998
											}#if end
226 liveuser 3999
 
3 liveuser 4000
										}#foreach end
226 liveuser 4001
 
3 liveuser 4002
									#如果要將自己在對方對話清單裡面的id改成現在的id
4003
									if($update){
226 liveuser 4004
 
3 liveuser 4005
										#debug
4006
										#var_dump($toId."要更新對話清單中索引為".$tIndex."的id(".$this->connInfo[$toId]["talkTo"][$tIndex]["id"].")為".$myId);
226 liveuser 4007
 
3 liveuser 4008
										#將自己在對方對話清單裡面的id改成現在的id
4009
										$this->connInfo[$toId]["talkTo"][$tIndex]["id"]=$myId;
226 liveuser 4010
 
3 liveuser 4011
										}#if end
226 liveuser 4012
 
3 liveuser 4013
									#反之不要將自己在對方對話清單裡面的id改成現在的id(可以移除該對話id)
4014
									else{
226 liveuser 4015
 
3 liveuser 4016
										#移除該對話id
4017
										unset($this->connInfo[$toId]["talkTo"][$tIndex]);
226 liveuser 4018
 
3 liveuser 4019
										}#else end
226 liveuser 4020
 
4021
									}#if end
4022
 
3 liveuser 4023
								#如果要將自己加到對方的的通話清單裡面
4024
								if($add){
226 liveuser 4025
 
3 liveuser 4026
									#debug
4027
									#var_dump($toId."要加".$myId."(msgId為".$this->connInfo[$myId]["msgId"].")到通話清單裡面");
226 liveuser 4028
 
3 liveuser 4029
									#將自己加到對方的的通話清單裡面
226 liveuser 4030
									$this->connInfo[$toId]["talkTo"][]=array("id"=>$myId,"userId"=>$myUserId,"msgId"=>$this->connInfo[$myId]["msgId"]);
4031
 
4032
									}#if end
4033
 
3 liveuser 4034
								#檢查對方是否已經在自己的對話清單裡面
226 liveuser 4035
 
3 liveuser 4036
								#設置要新增對方到自己的對話清單裡面.
4037
								$add=true;
226 liveuser 4038
 
3 liveuser 4039
								#自己有幾個對話對象就執行幾次
4040
								foreach($this->connInfo[$myId]["talkTo"] as $mtIndex=>$mtInfo){
226 liveuser 4041
 
3 liveuser 4042
									#對方的userId與id若在自己的對話清單裡面
4043
									if($mtInfo["userId"]===$cInfo["userId"] && $mtInfo["id"]===$toId){
226 liveuser 4044
 
3 liveuser 4045
										#設置不需要新增對方到自己的對話清單裡面
4046
										$add=false;
226 liveuser 4047
 
3 liveuser 4048
										#跳出 foreach
4049
										break;
226 liveuser 4050
 
3 liveuser 4051
										}#if end
226 liveuser 4052
 
3 liveuser 4053
									}#foreache end
226 liveuser 4054
 
3 liveuser 4055
								#如果要新增對方到自己的對話清單裡面.
4056
								if($add){
226 liveuser 4057
 
3 liveuser 4058
									#自己有幾個對話對象就執行幾次
4059
									foreach($this->connInfo[$myId]["talkTo"] as $mtIndex=>$mtInfo){
226 liveuser 4060
 
3 liveuser 4061
										#如果對方已經在自己的通話清單
4062
										if($mtInfo["userId"]===$cInfo["userId"] && $mtInfo["id"]===$toId){
4063
 
4064
											#設置不要將對方到自己的對話清單裡面.
4065
											$add=false;
226 liveuser 4066
 
3 liveuser 4067
											#跳出 foreach end
4068
											break;
4069
 
4070
											}#if end
226 liveuser 4071
 
3 liveuser 4072
										}#foreach end
226 liveuser 4073
 
3 liveuser 4074
									#如果要新增對方到自己的對話清單裡面.
4075
									if($add){
226 liveuser 4076
 
3 liveuser 4077
										#將對方加到自己的對話清單裡面
4078
										$this->connInfo[$myId]["talkTo"][]=array("id"=>$toId,"userId"=>$cInfo["userId"],"msgId"=>$this->connInfo[$toId]["msgId"]);
226 liveuser 4079
 
3 liveuser 4080
										}#if end
226 liveuser 4081
 
3 liveuser 4082
									}#if end
226 liveuser 4083
 
3 liveuser 4084
								}#if end
226 liveuser 4085
 
3 liveuser 4086
							}#foreach end
226 liveuser 4087
 
3 liveuser 4088
						}#foreach end
226 liveuser 4089
 
3 liveuser 4090
					#結束認證成功後的流程
4091
					return true;
226 liveuser 4092
 
3 liveuser 4093
					}#else end
226 liveuser 4094
 
3 liveuser 4095
				}#else end
226 liveuser 4096
 
3 liveuser 4097
			#結束認證流程
226 liveuser 4098
			return true;
4099
 
3 liveuser 4100
			}#if end
226 liveuser 4101
 
3 liveuser 4102
		#如果收到 "id?"
4103
		else if($msg==="id?"){
226 liveuser 4104
 
3 liveuser 4105
			#包裝訊息
226 liveuser 4106
			#"type"為"id?"
4107
			#"status"為"true"
3 liveuser 4108
			#"data"為實際的訊息內容
4109
			$packedMsg=array("type"=>"id?","status"=>"true","data"=>$from->resourceId);
226 liveuser 4110
 
3 liveuser 4111
			#傳自己的id給client
4112
			$from->send(json_encode($packedMsg));
226 liveuser 4113
 
3 liveuser 4114
			#回傳成功
4115
			return true;
226 liveuser 4116
 
3 liveuser 4117
			}#if end
226 liveuser 4118
 
3 liveuser 4119
		#如果收到 "ids?"
4120
		else if($msg==="ids?"){
226 liveuser 4121
 
3 liveuser 4122
			#初始化儲存其他人的id
4123
			$idsArray=array();
226 liveuser 4124
 
3 liveuser 4125
			#針對所的client
4126
			foreach ($this->clients as $client){
226 liveuser 4127
 
3 liveuser 4128
				#排除自己
4129
				if($from !== $client){
226 liveuser 4130
 
3 liveuser 4131
					#取得其他人的id
4132
					$idsArray[]=$client->resourceId;
226 liveuser 4133
 
3 liveuser 4134
					}#if end
226 liveuser 4135
 
4136
				}#foreach end
4137
 
3 liveuser 4138
			#包裝訊息
226 liveuser 4139
			#"type"為"ids?"
4140
			#"status"為"true"
3 liveuser 4141
			#"data"為實際的訊息內容
4142
			$packedMsg=array("type"=>"ids?","status"=>"true","data"=>$idsArray);
226 liveuser 4143
 
3 liveuser 4144
			#傳他人的id給client
4145
			$from->send(json_encode($packedMsg));
226 liveuser 4146
 
3 liveuser 4147
			#回傳成功
4148
			return true;
226 liveuser 4149
 
3 liveuser 4150
			}#if end
226 liveuser 4151
 
3 liveuser 4152
		#如果收到 "talkTo?"
4153
		else if($msg==="talkTo?"){
226 liveuser 4154
 
3 liveuser 4155
			#包裝訊息
226 liveuser 4156
			#"type"為"talkTo?"
4157
			#"status"為"true"
3 liveuser 4158
			#"data"為實際的訊息內容
4159
			$packedMsg=array("type"=>"talkTo?","status"=>"true","data"=>$this->connInfo[$from->resourceId]["talkTo"]);
226 liveuser 4160
 
3 liveuser 4161
			#正在對話的對象id給client
4162
			$from->send(json_encode($packedMsg));
226 liveuser 4163
 
3 liveuser 4164
			#回傳成功
4165
			return true;
226 liveuser 4166
 
3 liveuser 4167
			}#if end
226 liveuser 4168
 
3 liveuser 4169
		#反之如果是 "msgId?"
4170
		else if($msg==="msgId?"){
226 liveuser 4171
 
3 liveuser 4172
			#包裝訊息
226 liveuser 4173
			#"type"為"talkTo?"
4174
			#"status"為"true"
3 liveuser 4175
			#"data"為實際的訊息內容
4176
			$packedMsg=array("type"=>"msgId?","status"=>"true","data"=>$this->connInfo[$from->resourceId]["msgId"]);
226 liveuser 4177
 
3 liveuser 4178
			#取得自己的msgId
4179
			$from->send(json_encode($packedMsg));
226 liveuser 4180
 
3 liveuser 4181
			#回傳成功
4182
			return true;
226 liveuser 4183
 
3 liveuser 4184
			}#if end
226 liveuser 4185
 
3 liveuser 4186
		#如果收到的$msg長度大於 "talkTo:"
4187
		if(strlen($msg)>strlen("talkTo:")){
226 liveuser 4188
 
4189
			#如果收到開頭為 "talkTo:"
3 liveuser 4190
			#涵式說明:
4191
			#取得符合特定字首與字尾的字串
4192
			#回傳的結果:
4193
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
4194
			#$result["function"],當前執行的函數名稱.
4195
			#$result["error"],錯誤訊息陣列.
4196
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
4197
			#$result["returnString"],爲符合字首條件的字串內容。
4198
			#必填參數:
4199
			#$conf["checkString"],字串,要檢查的字串.
4200
			$conf["search::getMeetConditionsString"]["checkString"]=$msg;
4201
			#可省略參數:
4202
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
4203
			$conf["search::getMeetConditionsString"]["frontWord"]="talkTo:";
4204
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
4205
			#$conf["tailWord"]="";
4206
			#參考資料:
4207
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
4208
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
4209
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 4210
 
3 liveuser 4211
			#如果選找前置字串 "talkTo:" 失敗
4212
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 4213
 
3 liveuser 4214
				#設置執行失敗
4215
				$result["status"]="false";
226 liveuser 4216
 
3 liveuser 4217
				#設置執行錯誤訊息
4218
				$result["error"]=$getMeetConditionsString;
226 liveuser 4219
 
3 liveuser 4220
				#回傳結果
4221
				return $result;
226 liveuser 4222
 
3 liveuser 4223
				}#if end
226 liveuser 4224
 
3 liveuser 4225
			#如果存在 "talkTo:" 前置字串
4226
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 4227
 
3 liveuser 4228
				#用 "talkTo:" 分割 $buf
4229
				#涵式說明:
4230
				#將固定格式的字串分開,並回傳分開的結果。
4231
				#回傳結果:
4232
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4233
				#$result["error"],錯誤訊息陣列
4234
				#$result["function"],當前執行的函數名稱.
4235
				#$result["oriStr"],要分割的原始字串內容
4236
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
4237
				#$result["dataCounts"],爲總共分成幾段
4238
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
4239
				#必填的參數:
4240
				$conf["stringProcess::spiltString"]["stringIn"]=$msg;#要處理的字串。
4241
				$conf["stringProcess::spiltString"]["spiltSymbol"]="talkTo:";#爲以哪個符號作爲分割
4242
				#可省略參數:
4243
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
4244
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
4245
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
4246
				unset($conf["stringProcess::spiltString"]);
226 liveuser 4247
 
3 liveuser 4248
				#如果分割字串失敗
4249
				if($spiltString["status"]==="false"){
226 liveuser 4250
 
3 liveuser 4251
					#設置執行失敗
4252
					$result["status"]="false";
226 liveuser 4253
 
3 liveuser 4254
					#設置執行錯誤訊息
4255
					$result["error"]=$spiltString;
226 liveuser 4256
 
3 liveuser 4257
					#回傳結果
4258
					return $result;
226 liveuser 4259
 
3 liveuser 4260
					}#if end
226 liveuser 4261
 
3 liveuser 4262
				#如果剛好分割出一筆資料
4263
				if($spiltString["dataCounts"]===1){
226 liveuser 4264
 
3 liveuser 4265
					#取得自己的id
4266
					$myId=$from->resourceId;
226 liveuser 4267
 
3 liveuser 4268
					#取得講話對象的id
4269
					$toId=$spiltString["dataArray"][0];
226 liveuser 4270
 
3 liveuser 4271
					#設置對象不存在的識別
4272
					$targetExist=false;
226 liveuser 4273
 
3 liveuser 4274
					#設置通話對象的key
226 liveuser 4275
					$targetKey="";
4276
 
3 liveuser 4277
					#如果要對話的對象存在
4278
					if(isset($this->connInfo[$toId])){
226 liveuser 4279
 
3 liveuser 4280
						#取得對象的userId
4281
						$toUserId=$this->connInfo[$toId]["userId"];
226 liveuser 4282
 
3 liveuser 4283
						#取得同userId的對象id們
226 liveuser 4284
 
3 liveuser 4285
						#初始化同userId的對象id
4286
						$targetC=array();
226 liveuser 4287
 
3 liveuser 4288
						#針對每個連線
4289
						foreach($this->connInfo as $eachIndex=>$eachInfo){
226 liveuser 4290
 
3 liveuser 4291
							#如果是自己
4292
							if($eachIndex===$myId){
226 liveuser 4293
 
3 liveuser 4294
								#跳到下一輪
4295
								continue;
226 liveuser 4296
 
3 liveuser 4297
								}#if end
226 liveuser 4298
 
3 liveuser 4299
							#如果是同userId的對象
4300
							if($eachInfo["userId"]===$toUserId){
226 liveuser 4301
 
3 liveuser 4302
								#取出連線
4303
								$targetC[$eachIndex]=$this->connInfo[$eachIndex];
226 liveuser 4304
 
3 liveuser 4305
								}#if end
226 liveuser 4306
 
3 liveuser 4307
							}#foreach end
226 liveuser 4308
 
3 liveuser 4309
						#針對每個同userId的連線
4310
						foreach($targetC as $tcIndex=>$tcInfo){
226 liveuser 4311
 
3 liveuser 4312
							#檢查自己的對話對象是否已經在清單裡面了
226 liveuser 4313
 
3 liveuser 4314
							#假設對象可以加到自己對話清單裡面
4315
							$add=true;
226 liveuser 4316
 
3 liveuser 4317
							#針對每個要講話的對象
4318
							foreach($this->connInfo[$myId]["talkTo"] as $index=>$cInfo){
226 liveuser 4319
 
3 liveuser 4320
								#如果對話對象已經在清單裡面了
4321
								if($this->connInfo[$tcIndex]["userId"]===$cInfo["userId"] && $tcIndex===$cInfo["id"] && $tcInfo["msgId"]===$cInfo["msgId"]){
226 liveuser 4322
 
3 liveuser 4323
									#設置不要再加到清單裡面
4324
									$add=false;
226 liveuser 4325
 
3 liveuser 4326
									#跳出foreach
4327
									break;
226 liveuser 4328
 
4329
									}#if end
4330
 
3 liveuser 4331
								}#foreach end
226 liveuser 4332
 
3 liveuser 4333
							#如果要加入到對話清單裡面
4334
							if($add){
226 liveuser 4335
 
3 liveuser 4336
								#增加自己的對話對象
4337
								$this->connInfo[$myId]["talkTo"][]=array("id"=>$tcIndex,"userId"=>$this->connInfo[$tcIndex]["userId"],"msgId"=>$this->connInfo[$tcIndex]["msgId"]);
226 liveuser 4338
 
3 liveuser 4339
								#假設對方可以加自己到對話清單裡面
4340
								$add=true;
226 liveuser 4341
 
3 liveuser 4342
								#檢查通話對象能否跟自己對話
4343
								foreach($this->connInfo[$tcIndex]["talkTo"] as $index=>$cInfo){
226 liveuser 4344
 
3 liveuser 4345
									#如果對話對象已經在清單裡面了
4346
									if($this->connInfo[$myId]["userId"]===$cInfo["userId"]){
226 liveuser 4347
 
3 liveuser 4348
										#設置不要再加到清單裡面
4349
										$add=false;
226 liveuser 4350
 
3 liveuser 4351
										#跳出 foreach
4352
										break;
226 liveuser 4353
 
3 liveuser 4354
										}#if end
226 liveuser 4355
 
3 liveuser 4356
									}#foreach end
226 liveuser 4357
 
3 liveuser 4358
								#如果對方可以加自己到對話清單裡面
4359
								if($add){
226 liveuser 4360
 
3 liveuser 4361
									#讓通話對象也可以傳送訊息回來
4362
									$this->connInfo[$tcIndex]["talkTo"][]=array("id"=>$myId,"userId"=>$this->connInfo[$myId]["userId"],"msgId"=>$this->connInfo[$myId]["msgId"]);
226 liveuser 4363
 
3 liveuser 4364
									}#if end
226 liveuser 4365
 
3 liveuser 4366
								#設置成功訊息
4367
								$msg="client id ".$toId." added to talkTo list";
226 liveuser 4368
 
3 liveuser 4369
								#包裝訊息
226 liveuser 4370
								#"type"為"status"
4371
								#"status"為"true"
3 liveuser 4372
								#"data"為實際的訊息內容
4373
								$packedMsg=array("type"=>"status","status"=>"true","data"=>$msg);
226 liveuser 4374
 
3 liveuser 4375
								#設置要給自己看的訊息
226 liveuser 4376
								$from->send(json_encode($packedMsg));
4377
 
3 liveuser 4378
								}#if end
226 liveuser 4379
 
3 liveuser 4380
							#反之
4381
							else{
226 liveuser 4382
 
3 liveuser 4383
								#設置錯誤訊息
4384
								$msg="client id ".$toId." already in talkTo list";
226 liveuser 4385
 
3 liveuser 4386
								#包裝訊息
226 liveuser 4387
								#"type"為"status"
4388
								#"status"為"false"
3 liveuser 4389
								#"data"為實際的訊息內容
4390
								$packedMsg=array("type"=>"status","status"=>"false","data"=>$msg);
226 liveuser 4391
 
3 liveuser 4392
								#設置要給自己看的訊息
4393
								$from->send(json_encode($packedMsg));
226 liveuser 4394
 
3 liveuser 4395
								}#else end
226 liveuser 4396
 
3 liveuser 4397
							}#foreach end
226 liveuser 4398
 
3 liveuser 4399
						#回傳成功
4400
						return true;
226 liveuser 4401
 
3 liveuser 4402
						}#if end
226 liveuser 4403
 
3 liveuser 4404
					#反之不存在
4405
					else{
226 liveuser 4406
 
3 liveuser 4407
						#設置錯誤訊息
4408
						$msg="client id ".$toId." doesn't exist";
226 liveuser 4409
 
3 liveuser 4410
						#包裝訊息
226 liveuser 4411
						#"type"為"status"
4412
						#"status"為"false"
3 liveuser 4413
						#"data"為實際的訊息內容
4414
						$packedMsg=array("type"=>"status","status"=>"false","data"=>$msg);
226 liveuser 4415
 
3 liveuser 4416
						#設置要給自己看的訊息
4417
						$from->send(json_encode($packedMsg));
226 liveuser 4418
 
3 liveuser 4419
						#回傳成功
4420
						return true;
226 liveuser 4421
 
4422
						}#else end
4423
 
3 liveuser 4424
					}#if end
226 liveuser 4425
 
3 liveuser 4426
				}#if end
226 liveuser 4427
 
3 liveuser 4428
			}#if end
226 liveuser 4429
 
3 liveuser 4430
		#預設沒有收到確認收到訊息的回應訊息
4431
		$mIndex="false";
226 liveuser 4432
 
3 liveuser 4433
		#如果收到的$msg長度大於 "msgId:"
4434
		if(strlen($msg)>strlen("msgId:")){
226 liveuser 4435
 
3 liveuser 4436
			#解析 $msg
226 liveuser 4437
 
4438
			#如果收到開頭為 "msgId:"
3 liveuser 4439
			#涵式說明:
4440
			#取得符合特定字首與字尾的字串
4441
			#回傳的結果:
4442
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
4443
			#$result["function"],當前執行的函數名稱.
4444
			#$result["error"],錯誤訊息陣列.
4445
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
4446
			#$result["returnString"],爲符合字首條件的字串內容。
4447
			#必填參數:
4448
			#$conf["checkString"],字串,要檢查的字串.
4449
			$conf["search::getMeetConditionsString"]["checkString"]=$msg;
4450
			#可省略參數:
4451
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
4452
			$conf["search::getMeetConditionsString"]["frontWord"]="msgId:";
4453
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
4454
			#$conf["tailWord"]="";
4455
			#參考資料:
4456
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
4457
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
4458
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 4459
 
3 liveuser 4460
			#如果選找前置字串 "msgId:" 失敗
4461
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 4462
 
3 liveuser 4463
				#設置執行失敗
4464
				$result["status"]="false";
226 liveuser 4465
 
3 liveuser 4466
				#設置執行錯誤訊息
4467
				$result["error"]=$getMeetConditionsString;
226 liveuser 4468
 
3 liveuser 4469
				#回傳結果
4470
				return $result;
226 liveuser 4471
 
3 liveuser 4472
				}#if end
226 liveuser 4473
 
3 liveuser 4474
			#如果存在	 "msgId:" 前置字串
4475
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 4476
 
3 liveuser 4477
				#用 "msgId:" 分割 $msg
4478
				#涵式說明:
4479
				#將固定格式的字串分開,並回傳分開的結果。
4480
				#回傳結果:
4481
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4482
				#$result["error"],錯誤訊息陣列
4483
				#$result["function"],當前執行的函數名稱.
4484
				#$result["oriStr"],要分割的原始字串內容
4485
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
4486
				#$result["dataCounts"],爲總共分成幾段
4487
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
4488
				#必填的參數:
4489
				$conf["stringProcess::spiltString"]["stringIn"]=$msg;#要處理的字串。
4490
				$conf["stringProcess::spiltString"]["spiltSymbol"]="msgId:";#爲以哪個符號作爲分割
4491
				#可省略參數:
4492
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
4493
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
4494
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
4495
				unset($conf["stringProcess::spiltString"]);
226 liveuser 4496
 
3 liveuser 4497
				#如果分割字串失敗
4498
				if($spiltString["status"]==="false"){
226 liveuser 4499
 
3 liveuser 4500
					#設置執行失敗
4501
					$result["status"]="false";
226 liveuser 4502
 
3 liveuser 4503
					#設置執行錯誤訊息
4504
					$result["error"]=$spiltString;
226 liveuser 4505
 
3 liveuser 4506
					#回傳結果
4507
					return $result;
226 liveuser 4508
 
3 liveuser 4509
					}#if end
226 liveuser 4510
 
3 liveuser 4511
				#如果剛好分割出一筆資料
4512
				if($spiltString["dataCounts"]===1){
226 liveuser 4513
 
3 liveuser 4514
					#如果尚未設置過msgId
4515
					if($this->connInfo[$from->resourceId]["gotMsgId"]==="false"){
226 liveuser 4516
 
3 liveuser 4517
						#取得待確認訊息id
4518
						$msgId=$spiltString["dataArray"][0];
226 liveuser 4519
 
3 liveuser 4520
						#初始化儲存現有msgId的變數
4521
						$msgIdArray=array();
226 liveuser 4522
 
3 liveuser 4523
						#取得現有的msgId
4524
						foreach($this->connInfo as $cInfo){
226 liveuser 4525
 
3 liveuser 4526
							#如果msgId不為空
4527
							if($cInfo["msgId"]!==""){
226 liveuser 4528
 
3 liveuser 4529
								#儲存msgId
4530
								$msgIdArray[]=$cInfo["msgId"];
226 liveuser 4531
 
3 liveuser 4532
								}#if end
226 liveuser 4533
 
3 liveuser 4534
							}#foreach end
226 liveuser 4535
 
3 liveuser 4536
						#檢查msgId是否存在於$msgIdArray裡面
4537
						if(in_array($msgId,$msgIdArray)){
226 liveuser 4538
 
3 liveuser 4539
							#設置自己的msgId
226 liveuser 4540
							$this->connInfo[$from->resourceId]["msgId"]=$msgId;
4541
 
3 liveuser 4542
							#設置已經設置過msgId
4543
							$this->connInfo[$from->resourceId]["gotMsgId"]="true";
226 liveuser 4544
 
3 liveuser 4545
							#設置成功訊息
4546
							$msg="set msgId successfully";
226 liveuser 4547
 
3 liveuser 4548
							#包裝訊息
226 liveuser 4549
							#"type"為"status"
4550
							#"status"為"false"
3 liveuser 4551
							#"data"為實際的訊息內容
4552
							$packedMsg=array("type"=>"status","status"=>"true","data"=>$msg);
226 liveuser 4553
 
3 liveuser 4554
							#設置要給自己看的訊息
4555
							$from->send(json_encode($packedMsg));
226 liveuser 4556
 
3 liveuser 4557
							#針對每個連線
4558
							foreach($this->connInfo as $connIndex=>$connInfo){
226 liveuser 4559
 
3 liveuser 4560
								#如果是跟發訊息者同msgId但id不一樣的連線
4561
								if($connInfo["msgId"]===$msgId && $connIndex!==$from->resourceId){
226 liveuser 4562
 
3 liveuser 4563
									#將id為$connIndex的連線斷線
4564
									$this->clients->detach($this->connInfo[$connIndex]["conn"]);
4565
 
4566
									#提示已經將連線斷開
4567
									echo "Connection {$connIndex} has disconnected\n";
226 liveuser 4568
 
3 liveuser 4569
									#移除先前同msgId但id不一樣的連線
4570
									unset($this->connInfo[$connIndex]);
226 liveuser 4571
 
3 liveuser 4572
									#針對每個連線
4573
									foreach($this->connInfo as $cIndexForTD=>$cInfoForTD){
226 liveuser 4574
 
3 liveuser 4575
										#針對 talkTo 的每個項目
4576
										foreach($cInfoForTD["talkTo"] as $ttIndex=>$ttInfo){
226 liveuser 4577
 
3 liveuser 4578
											#如果是不存在的通話對象
4579
											if($ttInfo["id"]===$connIndex){
226 liveuser 4580
 
3 liveuser 4581
												#移除之
4582
												unset($this->connInfo[$cIndexForTD]["talkTo"][$ttIndex]);
226 liveuser 4583
 
3 liveuser 4584
												}#if end
226 liveuser 4585
 
3 liveuser 4586
											}#foreach end
226 liveuser 4587
 
3 liveuser 4588
										}#foreach end
226 liveuser 4589
 
3 liveuser 4590
									}#if end
226 liveuser 4591
 
3 liveuser 4592
								}#foreach end
226 liveuser 4593
 
3 liveuser 4594
							#如果有要確認的訊息陣列
4595
							if(isset($this->unConfirmMsg[$msgId])){
226 liveuser 4596
 
3 liveuser 4597
								#初始化要傳送的待確認訊息
4598
								$packedMsg=array();
226 liveuser 4599
 
3 liveuser 4600
								#有幾個要確認的訊息就執行幾次
4601
								foreach($this->unConfirmMsg[$msgId] as $unCMindex=>$unCMinfo){
226 liveuser 4602
 
3 liveuser 4603
									#如果待確認訊息的傳送目標id不等於剛要求更換msgId的用戶id
4604
									if($unCMinfo["toId"]!==$from->resourceId){
226 liveuser 4605
 
3 liveuser 4606
										#設置傳送目標id為要求更換msgId的用戶id
4607
										$this->unConfirmMsg[$msgId][$unCMindex]["toId"]=$from->resourceId;
226 liveuser 4608
 
3 liveuser 4609
										#檢查所有連線資訊
4610
										foreach($this->connInfo as $connId=>$connInfo){
226 liveuser 4611
 
3 liveuser 4612
											#依據talkTo清單的每個對象
4613
											foreach($connInfo["talkTo"] as $talk2Index=>$talk2Info){
226 liveuser 4614
 
3 liveuser 4615
												#若對象的id為$unCMinfo["toId"]且userId為$this->connInfo[$from->resourceId]["userId"]且msgId為$this->connInfo[$from->resourceId]["msgId"]者
4616
												if($talk2Info["id"]===$unCMinfo["toId"] && $talk2Info["userId"]===$this->connInfo[$from->resourceId]["userId"] && $talk2Info["msgId"]===$this->connInfo[$from->resourceId]["msgId"]){
226 liveuser 4617
 
3 liveuser 4618
													#移除該talkTo對象
4619
													unset($this->connInfo[$connId]["talkTo"][$talk2Index]);
226 liveuser 4620
 
3 liveuser 4621
													}#if ded
226 liveuser 4622
 
3 liveuser 4623
												}#foreach end
226 liveuser 4624
 
3 liveuser 4625
											}#foreach end
226 liveuser 4626
 
3 liveuser 4627
										}#if end
226 liveuser 4628
 
3 liveuser 4629
									#如果要傳送的待確認訊息為空陣列
4630
									if($packedMsg===array()){
226 liveuser 4631
 
3 liveuser 4632
										#包裝訊息
4633
										#"type"為"msg"
4634
										#"index"為$cInfo["id"]
4635
										#"data"為實際的訊息內容
4636
										$packedMsg=array("type"=>"msg","index"=>$unCMindex,"data"=>$unCMinfo["msg"]);
226 liveuser 4637
 
3 liveuser 4638
										}#if end
226 liveuser 4639
 
3 liveuser 4640
									}#foreach end
226 liveuser 4641
 
3 liveuser 4642
								#如果要傳送的待確認訊息不為空陣列
4643
								if($packedMsg!==array()){
226 liveuser 4644
 
3 liveuser 4645
									#var_dump("重新登入更改msgId後要傳送的未確認訊息:".print_r($packedMsg,true));
226 liveuser 4646
 
3 liveuser 4647
									#傳送包裝好的待確認訊息給對方
4648
									$from->send(json_encode($packedMsg));
226 liveuser 4649
 
3 liveuser 4650
									}#if end
226 liveuser 4651
 
3 liveuser 4652
								}#if end
226 liveuser 4653
 
3 liveuser 4654
							#結束程式
4655
							return true;
226 liveuser 4656
 
3 liveuser 4657
							}#if end
226 liveuser 4658
 
3 liveuser 4659
							#反之想要用的msgId並不存在於server
4660
							else{
226 liveuser 4661
 
3 liveuser 4662
								#設置錯誤訊息
4663
								$msg="msgId 「".$msgId."」 doesn't exist";
226 liveuser 4664
 
3 liveuser 4665
								#包裝訊息
226 liveuser 4666
								#"type"為"status"
4667
								#"status"為"false"
3 liveuser 4668
								#"data"為實際的訊息內容
4669
								$packedMsg=array("type"=>"status","status"=>"false","data"=>$msg);
226 liveuser 4670
 
3 liveuser 4671
								#設置要給自己看的訊息
4672
								$from->send(json_encode($packedMsg));
4673
 
4674
								#結束程式
4675
								return true;
226 liveuser 4676
 
3 liveuser 4677
								}#else end
226 liveuser 4678
 
3 liveuser 4679
						}#if end
226 liveuser 4680
 
3 liveuser 4681
					#反之已經設置過 msgId 了
4682
					else{
226 liveuser 4683
 
3 liveuser 4684
						#設置錯誤訊息
4685
						$msg="msgId already set";
226 liveuser 4686
 
3 liveuser 4687
						#包裝訊息
226 liveuser 4688
						#"type"為"status"
4689
						#"status"為"false"
3 liveuser 4690
						#"data"為實際的訊息內容
4691
						$packedMsg=array("type"=>"status","status"=>"false","data"=>$msg);
226 liveuser 4692
 
3 liveuser 4693
						#設置要給自己看的訊息
4694
						$from->send(json_encode($packedMsg));
4695
 
4696
						#結束程式
4697
						return true;
226 liveuser 4698
 
3 liveuser 4699
						}#else end
226 liveuser 4700
 
3 liveuser 4701
					}#if end
226 liveuser 4702
 
3 liveuser 4703
				#設置失敗訊息
4704
				$msg="set msgId failed";
226 liveuser 4705
 
3 liveuser 4706
				#包裝訊息
226 liveuser 4707
				#"type"為"status"
4708
				#"status"為"false"
3 liveuser 4709
				#"data"為實際的訊息內容
4710
				$packedMsg=array("type"=>"status","status"=>"false","data"=>$msg);
226 liveuser 4711
 
3 liveuser 4712
				#設置要給自己看的訊息
4713
				$from->send(json_encode($packedMsg));
4714
 
4715
				#結束程式
4716
				return true;
226 liveuser 4717
 
3 liveuser 4718
				}#if end
226 liveuser 4719
 
3 liveuser 4720
			}#if end
226 liveuser 4721
 
3 liveuser 4722
		#如果訊息長度大於 strlen("mIndex:")
4723
		if(strlen($msg)>strlen("mIndex:")){
226 liveuser 4724
 
4725
			#如果是確認收到訊息的回應訊息開頭 "mIndex:"
3 liveuser 4726
			#涵式說明:
4727
			#取得符合特定字首與字尾的字串
4728
			#回傳的結果:
4729
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
4730
			#$result["function"],當前執行的函數名稱.
4731
			#$result["error"],錯誤訊息陣列.
4732
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
4733
			#$result["returnString"],爲符合字首條件的字串內容。
4734
			#必填參數:
4735
			#$conf["checkString"],字串,要檢查的字串.
4736
			$conf["search::getMeetConditionsString"]["checkString"]=$msg;
4737
			#可省略參數:
4738
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
4739
			$conf["search::getMeetConditionsString"]["frontWord"]="mIndex:";
4740
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
4741
			#$conf["tailWord"]="";
4742
			#參考資料:
4743
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
4744
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
4745
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 4746
 
3 liveuser 4747
			#如果選找前置字串 "mIndex:" 失敗
4748
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 4749
 
3 liveuser 4750
				#設置執行失敗
4751
				$result["status"]="false";
226 liveuser 4752
 
3 liveuser 4753
				#設置執行錯誤訊息
4754
				$result["error"]=$getMeetConditionsString;
226 liveuser 4755
 
3 liveuser 4756
				#回傳結果
4757
				return $result;
226 liveuser 4758
 
3 liveuser 4759
				}#if end
226 liveuser 4760
 
3 liveuser 4761
			#如果存在	 "mIndex:" 前置字串
4762
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 4763
 
3 liveuser 4764
				#用 "mIndex:" 分割 $buf
4765
				#涵式說明:
4766
				#將固定格式的字串分開,並回傳分開的結果。
4767
				#回傳結果:
4768
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4769
				#$result["error"],錯誤訊息陣列
4770
				#$result["function"],當前執行的函數名稱.
4771
				#$result["oriStr"],要分割的原始字串內容
4772
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
4773
				#$result["dataCounts"],爲總共分成幾段
4774
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
4775
				#必填的參數:
4776
				$conf["stringProcess::spiltString"]["stringIn"]=$msg;#要處理的字串。
4777
				$conf["stringProcess::spiltString"]["spiltSymbol"]="mIndex:";#爲以哪個符號作爲分割
4778
				#可省略參數:
4779
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
4780
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
4781
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
4782
				unset($conf["stringProcess::spiltString"]);
226 liveuser 4783
 
3 liveuser 4784
				#如果分割字串失敗
4785
				if($spiltString["status"]==="false"){
226 liveuser 4786
 
3 liveuser 4787
					#設置執行失敗
4788
					$result["status"]="false";
226 liveuser 4789
 
3 liveuser 4790
					#設置執行錯誤訊息
4791
					$result["error"]=$spiltString;
226 liveuser 4792
 
3 liveuser 4793
					#回傳結果
4794
					return $result;
226 liveuser 4795
 
3 liveuser 4796
					}#if end
226 liveuser 4797
 
3 liveuser 4798
				#如果存在分割的識別字串
4799
				if($spiltString["found"]==="true"){
226 liveuser 4800
 
3 liveuser 4801
					#如果只分割出一段
4802
					if($spiltString["dataCounts"]===1){
226 liveuser 4803
 
3 liveuser 4804
						#取得待確認訊息的索引
4805
						$mIndex=$spiltString["dataArray"][0];
226 liveuser 4806
 
3 liveuser 4807
						}#if end
226 liveuser 4808
 
3 liveuser 4809
					}#if end
226 liveuser 4810
 
3 liveuser 4811
				}#if end
226 liveuser 4812
 
3 liveuser 4813
			}#if end
226 liveuser 4814
 
3 liveuser 4815
		#如果server收到訊息長度大於 "cmd:"
4816
		if(strlen($msg)>strlen("cmd:")){
226 liveuser 4817
 
4818
			#如果$msg開頭為"cmd:"
3 liveuser 4819
			#涵式說明:
4820
			#取得符合特定字首與字尾的字串
4821
			#回傳的結果:
4822
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
4823
			#$result["function"],當前執行的函數名稱.
4824
			#$result["error"],錯誤訊息陣列.
4825
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
4826
			#$result["returnString"],爲符合字首條件的字串內容。
4827
			#必填參數:
4828
			#$conf["checkString"],字串,要檢查的字串.
4829
			$conf["search::getMeetConditionsString"]["checkString"]=$msg;
4830
			#可省略參數:
4831
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
4832
			$conf["search::getMeetConditionsString"]["frontWord"]="cmd:";
4833
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
4834
			#$conf["tailWord"]="";
4835
			#參考資料:
4836
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
4837
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
4838
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 4839
 
3 liveuser 4840
			#如果選找前置字串 "cmd:" 失敗
4841
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 4842
 
3 liveuser 4843
				#設置執行失敗
4844
				$result["status"]="false";
226 liveuser 4845
 
3 liveuser 4846
				#設置執行錯誤訊息
4847
				$result["error"]=$getMeetConditionsString;
226 liveuser 4848
 
3 liveuser 4849
				#回傳結果
4850
				return $result;
226 liveuser 4851
 
3 liveuser 4852
				}#if end
226 liveuser 4853
 
3 liveuser 4854
			#如果存在	 "cmd:" 前置字串
4855
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 4856
 
3 liveuser 4857
				#用 "cmd:" 分割 $buf
4858
				#涵式說明:
4859
				#將固定格式的字串分開,並回傳分開的結果。
4860
				#回傳結果:
4861
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4862
				#$result["error"],錯誤訊息陣列
4863
				#$result["function"],當前執行的函數名稱.
4864
				#$result["oriStr"],要分割的原始字串內容
4865
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
4866
				#$result["dataCounts"],爲總共分成幾段
4867
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
4868
				#必填的參數:
4869
				$conf["stringProcess::spiltString"]["stringIn"]=$msg;#要處理的字串。
4870
				$conf["stringProcess::spiltString"]["spiltSymbol"]="cmd:";#爲以哪個符號作爲分割
4871
				#可省略參數:
4872
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
4873
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
4874
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
4875
				unset($conf["stringProcess::spiltString"]);
226 liveuser 4876
 
3 liveuser 4877
				#如果分割字串失敗
4878
				if($spiltString["status"]==="false"){
226 liveuser 4879
 
3 liveuser 4880
					#設置執行失敗
4881
					$result["status"]="false";
226 liveuser 4882
 
3 liveuser 4883
					#設置執行錯誤訊息
4884
					$result["error"]=$spiltString;
226 liveuser 4885
 
3 liveuser 4886
					#回傳結果
4887
					return $result;
226 liveuser 4888
 
3 liveuser 4889
					}#if end
226 liveuser 4890
 
3 liveuser 4891
				#如果剛好分割出一筆資料
4892
				if($spiltString["dataCounts"]===1){
226 liveuser 4893
 
3 liveuser 4894
					#取的要執行的指令
4895
					$cmd=$spiltString["dataArray"][0];
226 liveuser 4896
 
3 liveuser 4897
					#函式說明:
4898
					#呼叫shell執行系統命令,並取得回傳的內容.
4899
					#回傳的結果:
4900
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
4901
					#$result["error"],錯誤訊息陣列.
4902
					#$result["function"],當前執行的函數名稱.
4903
					#$result["cmd"],執行的指令內容.
4904
					#$result["output"],爲執行完二元碼後的輸出陣列.
4905
					#必填的參數
4906
					#$conf["command"],字串,要執行的指令與.
4907
					$conf["external::callShell"]["command"]=$cmd;
4908
					#$conf["fileArgu"],字串,變數__FILE__的內容.
226 liveuser 4909
					$conf["external::callShell"]["fileArgu"]=self::$fileArgu;
3 liveuser 4910
					#可省略參數:
4911
					#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
4912
					#$conf["argu"]=array("");
4913
					#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
4914
					#$conf["arguIsAddr"]=array();
4915
					#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
4916
					#$conf["enablePrintDescription"]="true";
4917
					#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.
4918
					#$conf["printDescription"]="";
4919
					#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
4920
					$conf["external::callShell"]["escapeshellarg"]="true";
4921
					#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
4922
					#$conf["username"]="";
4923
					#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
4924
					#$conf["password"]="";
4925
					#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要;"false"代表不要,預設為"false".
4926
					$conf["external::callShell"]["useScript"]="true";
4927
					#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 ".qbpwcf_tmp/external/callShell/".
4928
					#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
4929
					#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
4930
					#$conf["inBackGround"]="";
4931
					#備註:
4932
					#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
4933
					#參考資料:
4934
					#exec=>http://php.net/manual/en/function.exec.php
4935
					#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
4936
					#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
4937
					$callShell=external::callShell($conf["external::callShell"]);
4938
					unset($conf["external::callShell"]);
226 liveuser 4939
 
3 liveuser 4940
					#如果執行外部指令失敗
4941
					if($callShell["status"]==="false"){
226 liveuser 4942
 
3 liveuser 4943
						#設置要傳給client的訊息
4944
						$result=array("data"=>$callShell,"type"=>"status","status"=>"false");
226 liveuser 4945
 
4946
						#將程式執行後的錯誤輸出傳給client
3 liveuser 4947
						$from->send(json_encode($result));
226 liveuser 4948
 
3 liveuser 4949
						#回傳結果
4950
						return true;
226 liveuser 4951
 
3 liveuser 4952
						}#if end
226 liveuser 4953
 
3 liveuser 4954
					#設置要傳給client的訊息
4955
					$result=array("data"=>$callShell["output"],"type"=>"cmd");
226 liveuser 4956
 
4957
					#將程式執行後的輸出傳給client
3 liveuser 4958
					$from->send(json_encode($result));
226 liveuser 4959
 
3 liveuser 4960
					#結束程式
4961
					return true;
226 liveuser 4962
 
3 liveuser 4963
					}#if end
226 liveuser 4964
 
3 liveuser 4965
				}#if end
226 liveuser 4966
 
3 liveuser 4967
			}#if end
226 liveuser 4968
 
3 liveuser 4969
		#如果有要講話的對象
4970
		if(count($this->connInfo[$from->resourceId]["talkTo"])>0){
226 liveuser 4971
 
3 liveuser 4972
			#依據每個對話對象
4973
			foreach($this->connInfo[$from->resourceId]["talkTo"] as $index => $cInfo){
226 liveuser 4974
 
3 liveuser 4975
				#如果要講話的對象不存在(socket已經斷開)
4976
				if(!isset($this->connInfo[$cInfo["id"]])){
226 liveuser 4977
 
3 liveuser 4978
					#將訊息儲存起來,等對象上線後再把訊息傳過去.
4979
					$this->unSendMsg[]=array(
4980
						"fromId"=>$from->resourceId,
4981
						"toId"=>"",
4982
						"fromUserId"=>$this->connInfo[$from->resourceId]["userId"],
4983
						"toUserId"=>$cInfo["userId"],
4984
						"msg"=>$msg
4985
						);
226 liveuser 4986
 
3 liveuser 4987
					}#if end
226 liveuser 4988
 
3 liveuser 4989
				#反之,講話的對象存在
4990
				else{
226 liveuser 4991
 
3 liveuser 4992
					#如果收到確認收到訊息的回應
4993
					if($mIndex!=="false"){
226 liveuser 4994
 
3 liveuser 4995
						#儲存對話目標的msgId
4996
						$targetMsgId=$this->connInfo[$from->resourceId]["msgId"];
226 liveuser 4997
 
3 liveuser 4998
						#針對每個連線的待確認訊息
4999
						foreach($this->unConfirmMsg as $unCMindex=>$unCMinfo){
226 liveuser 5000
 
3 liveuser 5001
							#debug
5002
							#var_dump($unCMindex."!==".$targetMsgId." && count(\$unCMinfo):".count($unCMinfo));
226 liveuser 5003
 
3 liveuser 5004
							#如果 未確認訊息達到10則以上 且不是接收訊息者的msgId
5005
							if($unCMindex!==$targetMsgId && count($unCMinfo)>10){
226 liveuser 5006
 
3 liveuser 5007
								#代表接收訊息的用戶無法透過網路跟server溝通
226 liveuser 5008
 
3 liveuser 5009
								#提示 server 連線已結束
5010
								echo "Connection {$unCMinfo["id"]} has disconnected\n";
226 liveuser 5011
 
3 liveuser 5012
								#將待驗證的訊息變成留言訊息
226 liveuser 5013
 
3 liveuser 5014
								#有幾個未確認訊息就執行幾次
5015
								foreach($this->unConfirmMsg[$unCMindex] as $unConMsgIndex => $unConMsgInfo){
226 liveuser 5016
 
3 liveuser 5017
									#將訊息儲存起來,等對象上線後再把訊息傳過去.
5018
									$this->unSendMsg[]=array(
5019
										"fromId"=>$unConMsgInfo["fromId"],
5020
										"toId"=>"",
5021
										"fromUserId"=>$unConMsgInfo["fromUserId"],
5022
										"toUserId"=>$unConMsgInfo["toUserId"],
5023
										"msg"=>$unConMsgInfo["msg"]
5024
										);
226 liveuser 5025
 
3 liveuser 5026
									}#foreach end
226 liveuser 5027
 
3 liveuser 5028
								#移除待驗證的訊息資訊
5029
								unset($this->unConfirmMsg[$unCMindex]);
226 liveuser 5030
 
3 liveuser 5031
								#將client的連線斷開
5032
								$this->clients->detach($this->connInfo[$unConMsgInfo["fromId"]]["conn"]);
226 liveuser 5033
 
3 liveuser 5034
								#移除連線的資訊
226 liveuser 5035
								unset($this->connInfo[$unConMsgInfo["fromId"]]);
5036
 
3 liveuser 5037
								}#if end
226 liveuser 5038
 
3 liveuser 5039
							}#foreach end
226 liveuser 5040
 
3 liveuser 5041
						#存在收到訊息用戶id的待確認訊息
5042
						if(isset($this->unConfirmMsg[$targetMsgId])){
226 liveuser 5043
 
3 liveuser 5044
							#如果該未確認訊息存在
5045
							if(isset($this->unConfirmMsg[$targetMsgId][$mIndex])){
226 liveuser 5046
 
3 liveuser 5047
								#debug
5048
								#var_dump("移除待確認的訊息".print_r($this->unConfirmMsg[$targetMsgId][$mIndex],true));
226 liveuser 5049
 
3 liveuser 5050
								#移除該確認訊息
5051
								unset($this->unConfirmMsg[$targetMsgId][$mIndex]);
226 liveuser 5052
 
3 liveuser 5053
								#還剩下幾個待確認訊息就執行幾次
5054
								foreach($this->unConfirmMsg[$targetMsgId] as $unCMindex=>$unCMinfo){
226 liveuser 5055
 
3 liveuser 5056
									#如果後面還有訊息
5057
									if(isset($this->unConfirmMsg[$targetMsgId][$unCMindex+1])){
226 liveuser 5058
 
3 liveuser 5059
										#如果與下一份訊息的 fromUserId一樣, toUserId 一樣, fromId一樣, toId 不同, msg 一樣.
5060
										if(
5061
											(
5062
												$this->unConfirmMsg[$targetMsgId][$unCMindex]["fromUserId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromUserId"]
5063
												)
5064
											&&
5065
											(
5066
												$this->unConfirmMsg[$targetMsgId][$unCMindex]["toUserId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toUserId"]
5067
												)
5068
											&&
5069
											(
5070
												$this->unConfirmMsg[$targetMsgId][$unCMindex]["fromId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromId"]
5071
												)
5072
											&&
5073
											(
5074
												$this->unConfirmMsg[$targetMsgId][$unCMindex]["toId"]!==$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toId"]
226 liveuser 5075
												)
3 liveuser 5076
											&&
5077
											(
5078
												$this->unConfirmMsg[$targetMsgId][$unCMindex]["msg"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["msg"]
226 liveuser 5079
												)
3 liveuser 5080
											){
226 liveuser 5081
 
3 liveuser 5082
											#卸除該筆重複的訊息
5083
											unset($this->unConfirmMsg[$targetMsgId][$unCMindex]);
226 liveuser 5084
 
3 liveuser 5085
											#跳到下一則訊息
226 liveuser 5086
											continue;
5087
 
3 liveuser 5088
											}#if end
226 liveuser 5089
 
5090
										/*
3 liveuser 5091
										#debug
5092
										else{
226 liveuser 5093
 
3 liveuser 5094
											var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["fromUserId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromUserId"]);
5095
											var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["fromId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromId"]);
226 liveuser 5096
 
3 liveuser 5097
											var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["toUserId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toUserId"]);
5098
											var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["toId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toId"]);
226 liveuser 5099
 
3 liveuser 5100
											var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["msg"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["msg"]);
226 liveuser 5101
 
3 liveuser 5102
											}#else end
5103
										*/
226 liveuser 5104
 
3 liveuser 5105
										}#if end
226 liveuser 5106
 
3 liveuser 5107
									#包裝訊息
5108
									#"type"為"msg"
5109
									#"index"為$cInfo["id"]
5110
									#"data"為實際的訊息內容
5111
									$packedMsg=array("type"=>"msg","index"=>$unCMindex,"data"=>$unCMinfo["msg"]);
226 liveuser 5112
 
3 liveuser 5113
									#傳送包裝好的待確認訊息給對方
5114
									$from->send(json_encode($packedMsg));
226 liveuser 5115
 
3 liveuser 5116
									#一次只送一則訊息
5117
									break;
226 liveuser 5118
 
3 liveuser 5119
									}#foreach end
226 liveuser 5120
 
3 liveuser 5121
								}#if end
226 liveuser 5122
 
3 liveuser 5123
							}#if end
226 liveuser 5124
 
3 liveuser 5125
						}#if end
226 liveuser 5126
 
3 liveuser 5127
					#反之為要傳送的訊息
5128
					else{
226 liveuser 5129
 
3 liveuser 5130
						#儲存對話目標的msgId
5131
						$targetMsgId=$this->connInfo[$cInfo["id"]]["msgId"];
226 liveuser 5132
 
3 liveuser 5133
						#$unConfirmMsg[$msgId],為訊息接收方的$msgId,亦即收到訊息後,要跟server說有收到訊息者.
5134
						#"fromId",訊息來源的id
5135
						#"toId",訊息目的的id
5136
						#"fromUserId",訊息來源的userId
5137
						#"toUserId",訊息目標的userId
5138
						#"msg",傳送的訊息
5139
						#"msgId",訊息目標連線的msgId
5140
						#儲存待確認傳送的訊息到 $unConfirmMsg
5141
						$this->unConfirmMsg[$targetMsgId][]=array('fromId'=>$from->resourceId,'toId'=>$cInfo["id"],'fromUserId'=>$this->connInfo[$from->resourceId]["userId"],'toUserId'=>$cInfo["userId"],'msg'=>$msg,'msgId'=>$this->connInfo[$cInfo["id"]]["msgId"]);
226 liveuser 5142
 
5143
						#var_dump($this->unConfirmMsg[$targetMsgId]);
5144
 
3 liveuser 5145
						#如果未確認的訊息數量已經達到10則
5146
						if(count($this->unConfirmMsg[$targetMsgId])>10){
226 liveuser 5147
 
3 liveuser 5148
							#代表用戶無法透過網路跟server溝通
226 liveuser 5149
 
3 liveuser 5150
							#提示 server 連線已結束
5151
							echo "Connection {$cInfo["id"]} has disconnected\n";
226 liveuser 5152
 
3 liveuser 5153
							#將待驗證的訊息變成留言訊息
226 liveuser 5154
 
3 liveuser 5155
							#有幾個未確認訊息就執行幾次
5156
							foreach($this->unConfirmMsg[$targetMsgId] as $unCMindex => $unCMinfo){
226 liveuser 5157
 
3 liveuser 5158
								#將訊息儲存起來,等對象上線後再把訊息傳過去.
5159
								$this->unSendMsg[]=array(
5160
									"fromId"=>$unCMinfo["fromId"],
5161
									"toId"=>"",
5162
									"fromUserId"=>$unCMinfo["fromUserId"],
5163
									"toUserId"=>$unCMinfo["toUserId"],
5164
									"msg"=>$unCMinfo["msg"]
5165
									);
226 liveuser 5166
 
3 liveuser 5167
								}#foreach end
226 liveuser 5168
 
3 liveuser 5169
							#移除待驗證的訊息資訊
5170
							unset($this->unConfirmMsg[$targetMsgId]);
226 liveuser 5171
 
3 liveuser 5172
							#將client的連線斷開
5173
							$this->clients->detach($this->connInfo[$cInfo["id"]]["conn"]);
226 liveuser 5174
 
3 liveuser 5175
							#移除連線的資訊
5176
							unset($this->connInfo[$cInfo["id"]]);
226 liveuser 5177
 
3 liveuser 5178
							}#if end
226 liveuser 5179
 
3 liveuser 5180
						#反之
5181
						else{
226 liveuser 5182
 
3 liveuser 5183
							#裡面有幾個待確認的訊息就執行幾次
5184
							foreach($this->unConfirmMsg[$targetMsgId] as $unCMindex=>$unCMinfo){
226 liveuser 5185
 
3 liveuser 5186
								#如果後面還有訊息
5187
								if(isset($this->unConfirmMsg[$targetMsgId][$unCMindex+1])){
226 liveuser 5188
 
3 liveuser 5189
									#debug
5190
									#var_dump($this->unConfirmMsg[$targetMsgId]);
226 liveuser 5191
 
3 liveuser 5192
									#如果與下一份訊息的 fromUserId一樣, toUserId 一樣, fromId一樣, toId 不同, msg 一樣.
5193
									if(
5194
										(
5195
											$this->unConfirmMsg[$targetMsgId][$unCMindex]["fromUserId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromUserId"]
5196
											)
5197
										&&
5198
										(
5199
											$this->unConfirmMsg[$targetMsgId][$unCMindex]["toUserId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toUserId"]
5200
											)
5201
										&&
5202
										(
5203
											$this->unConfirmMsg[$targetMsgId][$unCMindex]["fromId"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["fromId"]
5204
											)
5205
										&&
5206
										(
5207
											$this->unConfirmMsg[$targetMsgId][$unCMindex]["toId"]!==$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toId"]
226 liveuser 5208
											)
3 liveuser 5209
										&&
5210
										(
5211
											$this->unConfirmMsg[$targetMsgId][$unCMindex]["msg"]===$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["msg"]
226 liveuser 5212
											)
3 liveuser 5213
										){
226 liveuser 5214
 
3 liveuser 5215
										#卸除該筆重複的訊息
5216
										unset($this->unConfirmMsg[$targetMsgId][$unCMindex]);
226 liveuser 5217
 
3 liveuser 5218
										#跳到下一則訊息
226 liveuser 5219
										continue;
5220
 
3 liveuser 5221
										}#if end
226 liveuser 5222
 
5223
									/*
3 liveuser 5224
									#debug
5225
									else{
226 liveuser 5226
 
3 liveuser 5227
										var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["toUserId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toUserId"]);
5228
										var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["toId"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["toId"]);
5229
										var_dump($this->unConfirmMsg[$targetMsgId][$unCMindex]["msg"].":".$this->unConfirmMsg[$targetMsgId][$unCMindex+1]["msg"]);
226 liveuser 5230
 
3 liveuser 5231
										}#else end
5232
									*/
226 liveuser 5233
 
3 liveuser 5234
									}#if end
226 liveuser 5235
 
3 liveuser 5236
								#debug
5237
								#var_dump("index:".$targetMsgId.print_r($this->unConfirmMsg[$targetMsgId],true));
226 liveuser 5238
 
3 liveuser 5239
								#另存 ConnectionInterface 物件
5240
								$connObject=$this->connInfo[$cInfo["id"]]["conn"];
226 liveuser 5241
 
3 liveuser 5242
								#包裝訊息
5243
								#"type"為"msg"
5244
								#"index"為$cInfo["id"]
5245
								#"data"為實際的訊息內容
5246
								$packedMsg=array("type"=>"msg","index"=>$unCMindex,"data"=>$unCMinfo["msg"]);
226 liveuser 5247
 
3 liveuser 5248
								#傳送包裝好的訊息給對方
5249
								$connObject->send(json_encode($packedMsg));
226 liveuser 5250
 
3 liveuser 5251
								#一次只送一則訊息
5252
								break;
226 liveuser 5253
 
3 liveuser 5254
								}#foreach end
226 liveuser 5255
 
3 liveuser 5256
							}#else end
226 liveuser 5257
 
5258
						}#else end
5259
 
3 liveuser 5260
					}#else end
226 liveuser 5261
 
3 liveuser 5262
				}#foreach end
226 liveuser 5263
 
3 liveuser 5264
			}#if end
226 liveuser 5265
 
3 liveuser 5266
		#反之沒有講話的對象
5267
		else{
226 liveuser 5268
 
3 liveuser 5269
			$msg="Message 「".$msg."」 will not be received by any one";
226 liveuser 5270
 
3 liveuser 5271
			#提示server訊息被拋棄
5272
			echo $msg;
226 liveuser 5273
 
3 liveuser 5274
			#包裝訊息
226 liveuser 5275
			#"type"為"status"
5276
			#"status"為"false"
3 liveuser 5277
			#"data"為實際的訊息內容
5278
			$packedMsg=array("type"=>"status","status"=>"false","data"=>$msg);
226 liveuser 5279
 
3 liveuser 5280
			#設置要給自己看的訊息
5281
			$from->send(json_encode($packedMsg));
226 liveuser 5282
 
3 liveuser 5283
			}#else end
226 liveuser 5284
 
3 liveuser 5285
		}#function onMessage end
5286
 
5287
	#當clinet的連線斷掉前
5288
	public function onClose(ConnectionInterface $conn){
226 liveuser 5289
 
3 liveuser 5290
		// The connection is closed, remove it, as we can no longer send it messages
5291
		$this->clients->detach($conn);
5292
 
5293
		#提示 server 連線已結束
5294
	 	echo "Connection {$conn->resourceId} has disconnected\n";
226 liveuser 5295
 
3 liveuser 5296
		#取得斷線目標的待確認訊息id
5297
		$msgId=$this->connInfo[$conn->resourceId]["msgId"];
226 liveuser 5298
 
3 liveuser 5299
		#移除目標id的待確認訊息
5300
		unset($this->unConfirmMsg[$msgId]);
226 liveuser 5301
 
3 liveuser 5302
		#移除連線的資訊
5303
		unset($this->connInfo[$conn->resourceId]);
226 liveuser 5304
 
3 liveuser 5305
		}#function onClose end
5306
 
5307
	#當出現錯誤時
5308
	public function onError(ConnectionInterface $conn, \Exception $e){
226 liveuser 5309
 
3 liveuser 5310
		#提示出現連線錯誤
5311
		echo "An error has occurred: {$e->getMessage()}\n";
5312
 
5313
		#關閉socket
5314
        	$conn->close();
226 liveuser 5315
 
3 liveuser 5316
		}#fucntion onError end
226 liveuser 5317
 
3 liveuser 5318
	}#class ChatV3 end
226 liveuser 5319
 
3 liveuser 5320
#用 soldier 類別來實作 MessageComponentInterface 界面,提供驗證身份後就可以執行系統命令的界面.
5321
class soldier implements MessageComponentInterface{
226 liveuser 5322
 
3 liveuser 5323
	#初始化儲存使用者資訊的陣列
226 liveuser 5324
	private $connInfo=array();
5325
 
3 liveuser 5326
	#初始化一開始尚未能夠連線到資料庫
5327
	private static $dbTouchable=false;
226 liveuser 5328
 
3 liveuser 5329
	#初始化db的位置
226 liveuser 5330
	public static $dbAddress="localhost";
5331
 
3 liveuser 5332
	#初始化連線db用的帳戶
5333
	public static $dbAccount="root";
226 liveuser 5334
 
3 liveuser 5335
	#初始化連線的db名稱
5336
	public static $dbName="test";
226 liveuser 5337
 
3 liveuser 5338
	#初始化連線db時用的密碼
5339
	public static $dbPassword="";
226 liveuser 5340
 
3 liveuser 5341
	#初始化連線db的哪個資料表
5342
	public static $memberTableName="member";
226 liveuser 5343
 
3 liveuser 5344
	#初始化登入時用來驗證帳號的資料表欄位名稱
5345
	public static $accountCol="account";
226 liveuser 5346
 
3 liveuser 5347
	#初始化登入時用來驗證密碼的資料表欄位名稱,設為""代表不用密碼來認證
5348
	public static $passwordCol="password";
226 liveuser 5349
 
3 liveuser 5350
	#初始化用來儲存 __FILE__ 內容的變數 fileArgu
5351
	public static $fileArgu=__FILE__;
226 liveuser 5352
 
3 liveuser 5353
	#當用戶與伺服器建立連線時
5354
    	public function onOpen(ConnectionInterface $conn){
226 liveuser 5355
 
3 liveuser 5356
		// Store the new connection to send messages to later
5357
        	$this->clients->attach($conn);
5358
 
5359
		#提示server有clent連上web socket.
5360
       		echo "New connection! ({$conn->resourceId})\n";
226 liveuser 5361
 
3 liveuser 5362
        	#用client的id為index來儲存額外的資訊
5363
        	#元素 "conn" 代表已經建立連線的ConnectionInterface物件
5364
        	#元素 "talkTo" 代表要跟誰講話
5365
		#元素 "userId" 代表辨識使用者的id
5366
		#元素 "loigin=array("ac","pw")" 代表client輸入的帳號與密碼
5367
        	$this->connInfo[$conn->resourceId]=array("conn"=>$conn,"userId"=>"","login"=>array("ac"=>"","pw"=>""));
226 liveuser 5368
 
3 liveuser 5369
		#包裝訊息
226 liveuser 5370
		#"type"為"login"
5371
		#"status"為"true"
3 liveuser 5372
		#"data"為實際的訊息內容
5373
		$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your account! ex:account:ws1");
226 liveuser 5374
 
5375
		#提示輸入帳號
3 liveuser 5376
		$conn->send(json_encode($packedMsg));
226 liveuser 5377
 
3 liveuser 5378
		}#function onOpen end
226 liveuser 5379
 
3 liveuser 5380
	#當伺服器收到訊息時
5381
	public function onMessage(ConnectionInterface $from, $msg){
226 liveuser 5382
 
3 liveuser 5383
		#如果該連線沒有使用者id
5384
		if($this->connInfo[$from->resourceId]["userId"]===""){
226 liveuser 5385
 
3 liveuser 5386
			#如果尚未輸入帳戶
5387
			if($this->connInfo[$from->resourceId]["login"]["ac"]===""){
226 liveuser 5388
 
3 liveuser 5389
				#如果 $msg 長度大於 "account:"
5390
				if(strlen($msg) > strlen("account:")){
226 liveuser 5391
 
3 liveuser 5392
					#檢查有無前置字元 "account:"
5393
					#函式說明:
5394
					#將字串特定關鍵字與其前面的內容剔除
5395
					#回傳結果:
5396
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5397
					#$result["error"],錯誤訊息陣列.
5398
					#$result["warning"],警告訊息鎮列.
5399
					#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
5400
					#$result["function"],當前執行的函數名稱.
5401
					#$result["oriStr"],要處理的原始字串內容.
5402
					#$result["content"],處理好的的字串內容.
5403
					#必填的參數:
5404
					$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$msg;#要處理的字串.
5405
					$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="account:";#特定字串.
5406
					$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
5407
					unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 5408
 
3 liveuser 5409
					#如果移除前置字元失敗
5410
					if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 5411
 
3 liveuser 5412
						#設置執行失敗
5413
						$result["status"]="false";
226 liveuser 5414
 
3 liveuser 5415
						#設置執行錯誤訊息
5416
						$result["error"]=$delStrBeforeKeyWord;
226 liveuser 5417
 
3 liveuser 5418
						#回傳結果
5419
						return $result;
226 liveuser 5420
 
3 liveuser 5421
						}#if end
226 liveuser 5422
 
3 liveuser 5423
					#如果有符合條件的前置字元
5424
					if($delStrBeforeKeyWord["founded"]==="true"){
226 liveuser 5425
 
3 liveuser 5426
						#儲存帳戶
5427
						$this->connInfo[$from->resourceId]["login"]["ac"]=$delStrBeforeKeyWord["content"];
226 liveuser 5428
 
3 liveuser 5429
						}#if end
226 liveuser 5430
 
5431
					#反之代表格式錯誤
3 liveuser 5432
					else{
226 liveuser 5433
 
3 liveuser 5434
						#包裝訊息
226 liveuser 5435
						#"type"為"login"
5436
						#"status"為"true"
3 liveuser 5437
						#"data"為實際的訊息內容
5438
						$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your account! ex:account:ws1");
226 liveuser 5439
 
5440
						#提示輸入帳號
3 liveuser 5441
						$from->send(json_encode($packedMsg));
226 liveuser 5442
 
3 liveuser 5443
						#結束程式
5444
						return true;
226 liveuser 5445
 
3 liveuser 5446
						}#else end
226 liveuser 5447
 
3 liveuser 5448
					}#if end
226 liveuser 5449
 
3 liveuser 5450
				#反之代表輸入錯誤格式的account
5451
				else{
226 liveuser 5452
 
3 liveuser 5453
					#包裝訊息
226 liveuser 5454
					#"type"為"login"
5455
					#"status"為"true"
3 liveuser 5456
					#"data"為實際的訊息內容
5457
					$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your account! ex:account:ws1");
226 liveuser 5458
 
5459
					#提示輸入帳號
3 liveuser 5460
					$from->send(json_encode($packedMsg));
226 liveuser 5461
 
3 liveuser 5462
					#結束程式
5463
					return true;
226 liveuser 5464
 
3 liveuser 5465
					}#else end
226 liveuser 5466
 
3 liveuser 5467
				}#if end
226 liveuser 5468
 
3 liveuser 5469
			#如果有設置密碼欄位
5470
			if(self::$passwordCol!==""){
226 liveuser 5471
 
3 liveuser 5472
				#如果尚未輸入密碼
5473
				if($this->connInfo[$from->resourceId]["login"]["pw"]===""){
226 liveuser 5474
 
3 liveuser 5475
					#$msg 長度大於 "password:"
5476
					if(strlen($msg) > strlen("password:")){
226 liveuser 5477
 
3 liveuser 5478
						#檢查有無前置字元 "password:"
5479
						#函式說明:
5480
						#將字串特定關鍵字與其前面的內容剔除
5481
						#回傳結果:
5482
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5483
						#$result["error"],錯誤訊息陣列.
5484
						#$result["warning"],警告訊息鎮列.
5485
						#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
5486
						#$result["function"],當前執行的函數名稱.
5487
						#$result["oriStr"],要處理的原始字串內容.
5488
						#$result["content"],處理好的的字串內容.
5489
						#必填的參數:
5490
						$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$msg;#要處理的字串.
5491
						$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="password:";#特定字串.
5492
						$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
5493
						unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 5494
 
3 liveuser 5495
						#如果移除前置字元失敗
5496
						if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 5497
 
3 liveuser 5498
							#設置執行失敗
5499
							$result["status"]="false";
226 liveuser 5500
 
3 liveuser 5501
							#設置執行錯誤訊息
5502
							$result["error"]=$delStrBeforeKeyWord;
226 liveuser 5503
 
3 liveuser 5504
							#回傳結果
5505
							return $result;
226 liveuser 5506
 
3 liveuser 5507
							}#if end
226 liveuser 5508
 
3 liveuser 5509
						#如果有符合條件的前置字元
5510
						if($delStrBeforeKeyWord["founded"]==="true"){
226 liveuser 5511
 
3 liveuser 5512
							#儲存密碼
5513
							$this->connInfo[$from->resourceId]["login"]["pw"]=$delStrBeforeKeyWord["content"];
226 liveuser 5514
 
3 liveuser 5515
							}#if end
226 liveuser 5516
 
3 liveuser 5517
						#反之代表格式錯誤
5518
						else{
226 liveuser 5519
 
3 liveuser 5520
							#包裝訊息
226 liveuser 5521
							#"type"為"login"
5522
							#"status"為"true"
3 liveuser 5523
							#"data"為實際的訊息內容
5524
							$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your password! ex:password:ws1");
226 liveuser 5525
 
5526
							#提示輸入密碼
3 liveuser 5527
							$from->send(json_encode($packedMsg));
226 liveuser 5528
 
3 liveuser 5529
							#結束程式
5530
							return true;
226 liveuser 5531
 
3 liveuser 5532
							}#else end
226 liveuser 5533
 
3 liveuser 5534
						}#if end
226 liveuser 5535
 
3 liveuser 5536
					#反之代表格式錯誤
5537
					else{
226 liveuser 5538
 
3 liveuser 5539
						#包裝訊息
226 liveuser 5540
						#"type"為"login"
5541
						#"status"為"true"
3 liveuser 5542
						#"data"為實際的訊息內容
5543
						$packedMsg=array("type"=>"login","status"=>"true","data"=>"Please input your password! ex:password:ws1");
226 liveuser 5544
 
5545
						#提示輸入密碼
3 liveuser 5546
						$from->send(json_encode($packedMsg));
226 liveuser 5547
 
3 liveuser 5548
						#結束程式
5549
						return true;
226 liveuser 5550
 
3 liveuser 5551
						}#else end
226 liveuser 5552
 
3 liveuser 5553
					}#if end
226 liveuser 5554
 
3 liveuser 5555
				}#if end
226 liveuser 5556
 
3 liveuser 5557
			#如果已經輸入帳號了
5558
			if($this->connInfo[$from->resourceId]["login"]["ac"]!=""){
226 liveuser 5559
 
3 liveuser 5560
				#設置可以進行驗證
5561
				$startAuth=true;
226 liveuser 5562
 
3 liveuser 5563
				#另存帳號
5564
				$ac=$this->connInfo[$from->resourceId]["login"]["ac"];
226 liveuser 5565
 
3 liveuser 5566
				#初始化密碼
5567
				$pw="";
226 liveuser 5568
 
3 liveuser 5569
				#如果有設置密碼欄位
5570
				if(self::$passwordCol!==""){
226 liveuser 5571
 
3 liveuser 5572
					#如果client已經輸入密碼了
5573
					if($this->connInfo[$from->resourceId]["login"]["pw"]!=""){
226 liveuser 5574
 
3 liveuser 5575
						#取得密碼
5576
						$pw=$this->connInfo[$from->resourceId]["login"]["pw"];
226 liveuser 5577
 
3 liveuser 5578
						}#if end
226 liveuser 5579
 
3 liveuser 5580
					#反之
5581
					else{
226 liveuser 5582
 
3 liveuser 5583
						#設置尚不能進行認證
5584
						$startAuth=false;
226 liveuser 5585
 
3 liveuser 5586
						}#else end
226 liveuser 5587
 
3 liveuser 5588
					}#if end
226 liveuser 5589
 
3 liveuser 5590
				#如果尚不能進行驗證
5591
				if(!$startAuth){
226 liveuser 5592
 
3 liveuser 5593
					#結束程式
5594
					return true;
226 liveuser 5595
 
3 liveuser 5596
					}#if end
226 liveuser 5597
 
3 liveuser 5598
				#檢查有無符合的帳戶密碼
5599
				#涵式說明:
5600
				#一次取得資料庫、表的資料
5601
				#回傳的結果
5602
				#$result["status"],執行結果"true"為成功;"false"為執行失敗。
5603
				#$result["error"],錯誤訊息陣列。
5604
				#$result["function"],當前執行的漢書名稱.
5605
				#$result["dataColumnName"],抓取的資料欄位名稱陣列.
5606
					#$result["dataColumnName"][$i]代表第$i+1個欄位名稱
5607
				#$result["dataContent"],爲資料的內容。
5608
				#$result["dataContent"][$conf["WhereColumnName"][$i]][$dataSetNum]
5609
					#$dataSetNum 爲第$dataSetNum+1筆資料
5610
					#$conf["WhereColumnName"][$i] 爲第 $i+1 個欄位的名稱
5611
				#$result["dataCount"],爲取得的資料筆數。
5612
				#$result["sql"],執行的sql字串.
5613
				#必填的參數:
5614
				$conf["db::fastGetDbData"]["dbAddress"]=self::$dbAddress;#爲dbServer的位置。
5615
				$conf["db::fastGetDbData"]["dbAccount"]=self::$dbAccount;#爲登入dbServer的帳號。
5616
				$conf["db::fastGetDbData"]["dbName"]=self::$dbName;#爲要存取的資料庫名稱
5617
				$conf["db::fastGetDbData"]["tableName"]=self::$memberTableName;#爲要存取的資料表名稱
5618
				$conf["db::fastGetDbData"]["columnYouWant"]=array("id","password");#你想要的欄位!,若設為「array("*")」則代表全部欄位.
5619
				#可省略的參數:
5620
				$conf["db::fastGetDbData"]["dbPassword"]=self::$dbPassword;#爲要存取dbServer的密碼
5621
				$conf["db::fastGetDbData"]["WhereColumnName"]=array(self::$accountCol);#用於判斷語句的欄位項目陣列。
5622
				$conf["db::fastGetDbData"]["WhereColumnValue"]=array($ac);#用於判斷語句的欄位數值陣列,若與LIKE搭配,則可以在關鍵自字串的左右名加上「%」符號,這樣就可以搜尋具有該字串的內容。
226 liveuser 5623
 
3 liveuser 5624
				/*
226 liveuser 5625
 
3 liveuser 5626
				#如果有輸入密碼
5627
				if($pw!==""){
226 liveuser 5628
 
3 liveuser 5629
					#新增要判斷 self::$password 欄位,是否有於 $pw
5630
					$conf["db::fastGetDbData"]["WhereColumnName"][]=self::$passwordCol;
5631
					$conf["db::fastGetDbData"]["WhereColumnValue"][]=$pw;
226 liveuser 5632
 
3 liveuser 5633
					}#if end
226 liveuser 5634
 
3 liveuser 5635
				*/
226 liveuser 5636
 
3 liveuser 5637
				#$conf["WhereColumnCombine"]=array("");#用於判斷語句當中需要()起來的判斷式,須爲陣列值,"s"代表「(」,"e"代表「)」 ,若無則須設爲""。
5638
				#$conf["WhereColumnOperator"]=array("");#用於判斷語句的比較符號陣列,可以用的符號有「"="、"!="、">"、"<"、"LIKE"、"NOT LIKE"」,預設都爲「=」。
5639
				#$conf["WhereColumnAndOr"]=array("");#用於判斷語句條件之間成立的條件是AND還是OR,須爲陣列值。其數量應爲要判斷的欄位數量減一。
5640
				#$conf["orderItem"]="";#爲排序的項目依據,若要用隨機抽樣,可以用"rand()",可省略。
5641
				#$conf["ascORdesc"]="";#爲要低增還是遞減排序,asc爲遞增;desc爲遞減。
5642
				#$conf["numberStart"]="0";#為從第幾筆開始讀取,預設為0,代筆第一筆。
5643
				$conf["db::fastGetDbData"]["numLimit"]="1";#為要取幾筆資料,可以省略,省略則表示不限制數目。
5644
				#$conf["groupBy"]=array("");#爲要以哪幾個欄爲作爲分羣的依據(欄位相同的數值僅會取出一筆)。
5645
				#備註:
5646
				#建議在查詢資料前,能夠檢查是否每個欄位都存在.
5647
				$fastGetDbData=db::fastGetDbData($conf["db::fastGetDbData"]);
5648
				unset($conf["db::fastGetDbData"]);
226 liveuser 5649
 
3 liveuser 5650
				#如果取得資料失敗
5651
				if($fastGetDbData["status"]==="false"){
226 liveuser 5652
 
3 liveuser 5653
					#設置執行失敗
5654
					$result["status"]="false";
226 liveuser 5655
 
3 liveuser 5656
					#設置執行錯誤訊息
5657
					$result["error"]=$fastGetDbData;
226 liveuser 5658
 
3 liveuser 5659
					#debug in server
5660
					var_dump($result);
226 liveuser 5661
 
3 liveuser 5662
					#提示server有資料庫錯誤
5663
					echo "dbError!";
226 liveuser 5664
 
3 liveuser 5665
					#結束程式
5666
					exit;
226 liveuser 5667
 
3 liveuser 5668
					}#if end
226 liveuser 5669
 
3 liveuser 5670
				#如果沒有一筆資料
5671
				if($fastGetDbData["dataCount"]!==1){
226 liveuser 5672
 
3 liveuser 5673
					#代表登入失敗
226 liveuser 5674
 
3 liveuser 5675
					#清空登入用的帳戶
5676
					$this->connInfo[$from->resourceId]["login"]["ac"]="";
226 liveuser 5677
 
3 liveuser 5678
					#清空登入用的密碼
5679
					$this->connInfo[$from->resourceId]["login"]["pw"]="";
226 liveuser 5680
 
3 liveuser 5681
					#包裝訊息
226 liveuser 5682
					#"type"為"login"
5683
					#"status"為"false"
3 liveuser 5684
					#"data"為實際的訊息內容
5685
					$packedMsg=array("type"=>"login","status"=>"false","data"=>"Login failed, please input account. ex:account:ws1");
226 liveuser 5686
 
5687
					#提示登入失敗
3 liveuser 5688
					$from->send(json_encode($packedMsg));
226 liveuser 5689
 
3 liveuser 5690
					#執行到這即可
5691
					return true;
226 liveuser 5692
 
3 liveuser 5693
					}#if end
226 liveuser 5694
 
3 liveuser 5695
				#反之代表帳戶資訊正確
5696
				else{
5697
					#驗證密碼是否正確.
5698
					#函式說明:
5699
					#加密字串,可以用的方法有sha1,md5,password_sha,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
5700
					#回傳結果:
226 liveuser 5701
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3 liveuser 5702
					#$result["function"],當前執行的函數名稱.
5703
					#$result["content"],加密後的結果.
5704
					#$result["error"],錯誤訊息陣列.
5705
					#$result["argu"],使用的參數.
5706
					#必填參數:
5707
					#$conf["enCodeStr"],"字串",要加密的字串.
5708
					$conf["authenticate::enCodeStr"]["enCodeStr"]=$pw;
5709
					#$conf["enCodeType"],"字串",加密的類型,有"sha1"與"md5"與"p_hash"3種,"sha1"較耗時,"md5"較快,"p_hash"適用於密碼加密.
5710
					$conf["authenticate::enCodeStr"]["enCodeType"]="p_hash";
5711
					#可省略參數:
5712
					#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
5713
					#$conf["sha1Raw"]="false";
5714
					#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
5715
					$conf["authenticate::enCodeStr"]["p_hash"]=$fastGetDbData["dataContent"]["password"][0];
5716
					#參考資料來源:
5717
					#sha1=>http://php.net/manual/en/function.sha1.php
5718
					#md5=>http://php.net/manual/en/function.md5.php
5719
					#password_hash=>http://php.net/manual/en/function.password-hash.php
5720
					#password_verify=>http://php.net/manual/en/function.password-verify.php
5721
					$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
5722
					unset($conf["authenticate::enCodeStr"]);
226 liveuser 5723
 
3 liveuser 5724
					#如果加密密碼失敗
5725
					if($enCodeStr["status"]==="false"){
226 liveuser 5726
 
3 liveuser 5727
						#debug from server
5728
						var_dump($enCodeStr);
226 liveuser 5729
 
3 liveuser 5730
						#提示server有資料庫錯誤
5731
						echo "password verify error!";
226 liveuser 5732
 
3 liveuser 5733
						#代表登入失敗
226 liveuser 5734
 
3 liveuser 5735
						#清空登入用的帳戶
5736
						$this->connInfo[$from->resourceId]["login"]["ac"]="";
226 liveuser 5737
 
3 liveuser 5738
						#清空登入用的密碼
5739
						$this->connInfo[$from->resourceId]["login"]["pw"]="";
226 liveuser 5740
 
3 liveuser 5741
						#包裝訊息
226 liveuser 5742
						#"type"為"login"
5743
						#"status"為"false"
3 liveuser 5744
						#"data"為實際的訊息內容
5745
						$packedMsg=array("type"=>"login","status"=>"false","data"=>"Login failed, please input account. ex:account:ws1");
226 liveuser 5746
 
5747
						#提示登入失敗
3 liveuser 5748
						$from->send(json_encode($packedMsg));
226 liveuser 5749
 
3 liveuser 5750
						#執行到這即可
5751
						return true;
226 liveuser 5752
 
3 liveuser 5753
						}#if end
226 liveuser 5754
 
3 liveuser 5755
					#反之認證成功
5756
					else{
226 liveuser 5757
 
3 liveuser 5758
						#debug for server
5759
						echo "new login:".PHP_EOL;
5760
						var_dump($enCodeStr);
226 liveuser 5761
 
3 liveuser 5762
						}#else end
226 liveuser 5763
 
3 liveuser 5764
					#設置 $myUserId
5765
					$myUserId=$this->connInfo[$from->resourceId]["userId"]=$fastGetDbData["dataContent"]["id"][0];
226 liveuser 5766
 
3 liveuser 5767
					#設置 $myId
5768
					$myId=$from->resourceId;
226 liveuser 5769
 
3 liveuser 5770
					#包裝訊息
226 liveuser 5771
					#"type"為"login"
5772
					#"status"為"true"
3 liveuser 5773
					#"data"為實際的訊息內容
5774
					$packedMsg=array("type"=>"login","status"=>"true","data"=>"Login successfully!");
226 liveuser 5775
 
3 liveuser 5776
					#提示登入成功
5777
					$from->send(json_encode($packedMsg));
226 liveuser 5778
 
3 liveuser 5779
					#結束認證成功後的流程
5780
					return true;
226 liveuser 5781
 
3 liveuser 5782
					}#else end
226 liveuser 5783
 
3 liveuser 5784
				}#else end
226 liveuser 5785
 
3 liveuser 5786
			#結束認證流程
226 liveuser 5787
			return true;
5788
 
3 liveuser 5789
			}#if end
226 liveuser 5790
 
3 liveuser 5791
		#如果server收到訊息長度大於 "cmd:"
5792
		if(strlen($msg)>strlen("cmd:")){
226 liveuser 5793
 
5794
			#如果$msg開頭為"cmd:"
3 liveuser 5795
			#涵式說明:
5796
			#取得符合特定字首與字尾的字串
5797
			#回傳的結果:
5798
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
5799
			#$result["function"],當前執行的函數名稱.
5800
			#$result["error"],錯誤訊息陣列.
5801
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
5802
			#$result["returnString"],爲符合字首條件的字串內容。
5803
			#必填參數:
5804
			#$conf["checkString"],字串,要檢查的字串.
5805
			$conf["search::getMeetConditionsString"]["checkString"]=$msg;
5806
			#可省略參數:
5807
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
5808
			$conf["search::getMeetConditionsString"]["frontWord"]="cmd:";
5809
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
5810
			#$conf["tailWord"]="";
5811
			#參考資料:
5812
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
5813
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
5814
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 5815
 
3 liveuser 5816
			#如果選找前置字串 "cmd:" 失敗
5817
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 5818
 
3 liveuser 5819
				#設置執行失敗
5820
				$result["status"]="false";
226 liveuser 5821
 
3 liveuser 5822
				#設置執行錯誤訊息
5823
				$result["error"]=$getMeetConditionsString;
226 liveuser 5824
 
3 liveuser 5825
				#回傳結果
5826
				return $result;
226 liveuser 5827
 
3 liveuser 5828
				}#if end
226 liveuser 5829
 
3 liveuser 5830
			#如果存在 "cmd:" 前置字串
5831
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 5832
 
3 liveuser 5833
				#用 "talkTo:" 分割 $buf
5834
				#涵式說明:
5835
				#將固定格式的字串分開,並回傳分開的結果。
5836
				#回傳結果:
5837
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5838
				#$result["error"],錯誤訊息陣列
5839
				#$result["function"],當前執行的函數名稱.
5840
				#$result["oriStr"],要分割的原始字串內容
5841
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
5842
				#$result["dataCounts"],爲總共分成幾段
5843
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
5844
				#必填的參數:
5845
				$conf["stringProcess::spiltString"]["stringIn"]=$msg;#要處理的字串。
5846
				$conf["stringProcess::spiltString"]["spiltSymbol"]="cmd:";#爲以哪個符號作爲分割
5847
				#可省略參數:
5848
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
5849
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
5850
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
5851
				unset($conf["stringProcess::spiltString"]);
226 liveuser 5852
 
3 liveuser 5853
				#如果分割字串失敗
5854
				if($spiltString["status"]==="false"){
226 liveuser 5855
 
3 liveuser 5856
					#設置執行失敗
5857
					$result["status"]="false";
226 liveuser 5858
 
3 liveuser 5859
					#設置執行錯誤訊息
5860
					$result["error"]=$spiltString;
226 liveuser 5861
 
3 liveuser 5862
					#回傳結果
5863
					return $result;
226 liveuser 5864
 
3 liveuser 5865
					}#if end
226 liveuser 5866
 
3 liveuser 5867
				#如果剛好分割出一筆資料
5868
				if($spiltString["dataCounts"]===1){
226 liveuser 5869
 
3 liveuser 5870
					#取的要執行的指令
5871
					$cmd=$spiltString["dataArray"][0];
226 liveuser 5872
 
3 liveuser 5873
					#函式說明:
5874
					#呼叫shell執行系統命令,並取得回傳的內容.
5875
					#回傳的結果:
5876
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5877
					#$result["error"],錯誤訊息陣列.
5878
					#$result["function"],當前執行的函數名稱.
5879
					#$result["cmd"],執行的指令內容.
5880
					#$result["output"],爲執行完二元碼後的輸出陣列.
5881
					#必填的參數
5882
					#$conf["command"],字串,要執行的指令與.
5883
					$conf["external::callShell"]["command"]=$cmd;
5884
					#$conf["fileArgu"],字串,變數__FILE__的內容.
226 liveuser 5885
					$conf["external::callShell"]["fileArgu"]=self::$fileArgu;
3 liveuser 5886
					#可省略參數:
5887
					#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
5888
					#$conf["argu"]=array("");
5889
					#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
5890
					#$conf["arguIsAddr"]=array();
5891
					#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
5892
					#$conf["enablePrintDescription"]="true";
5893
					#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.
5894
					#$conf["printDescription"]="";
5895
					#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
5896
					$conf["external::callShell"]["escapeshellarg"]="true";
5897
					#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
5898
					#$conf["username"]="";
5899
					#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
5900
					#$conf["password"]="";
5901
					#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要;"false"代表不要,預設為"false".
5902
					#$conf["useScript"]="";
5903
					#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 ".qbpwcf_tmp/external/callShell/".
5904
					#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
5905
					#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
5906
					#$conf["inBackGround"]="";
5907
					#備註:
5908
					#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
5909
					#參考資料:
5910
					#exec=>http://php.net/manual/en/function.exec.php
5911
					#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
5912
					#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
5913
					$callShell=external::callShell($conf["external::callShell"]);
5914
					unset($conf["external::callShell"]);
226 liveuser 5915
 
3 liveuser 5916
					#如果執行外部指令失敗
5917
					if($callShell["status"]==="false"){
226 liveuser 5918
 
3 liveuser 5919
						#設置執行失敗
5920
						$result["status"]="false";
226 liveuser 5921
 
3 liveuser 5922
						#設置執行錯誤訊息
5923
						$result["error"]=$callShell;
226 liveuser 5924
 
3 liveuser 5925
						#回傳結果
5926
						return $result;
226 liveuser 5927
 
3 liveuser 5928
						}#if end
226 liveuser 5929
 
3 liveuser 5930
					#設置要傳給client的訊息
5931
					$result=array("data"=>$callShell["output"],"type"=>"cmd");
226 liveuser 5932
 
5933
					#將程式執行後的輸出傳給client
3 liveuser 5934
					$from->send(json_encode($result));
226 liveuser 5935
 
3 liveuser 5936
					}#if end
226 liveuser 5937
 
3 liveuser 5938
				}#if end
226 liveuser 5939
 
3 liveuser 5940
			}#if end
226 liveuser 5941
 
3 liveuser 5942
		#如果server收到訊息長度大於 "sql:"
5943
		if(strlen($msg)>strlen("sql:")){
226 liveuser 5944
 
5945
			#如果$msg開頭為"sql:"
3 liveuser 5946
			#涵式說明:
5947
			#取得符合特定字首與字尾的字串
5948
			#回傳的結果:
5949
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
5950
			#$result["function"],當前執行的函數名稱.
5951
			#$result["error"],錯誤訊息陣列.
5952
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
5953
			#$result["returnString"],爲符合字首條件的字串內容。
5954
			#必填參數:
5955
			#$conf["checkString"],字串,要檢查的字串.
5956
			$conf["search::getMeetConditionsString"]["checkString"]=$msg;
5957
			#可省略參數:
5958
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
5959
			$conf["search::getMeetConditionsString"]["frontWord"]="sql:";
5960
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
5961
			#$conf["tailWord"]="";
5962
			#參考資料:
5963
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
5964
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
5965
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 5966
 
3 liveuser 5967
			#如果選找前置字串 "sql:" 失敗
5968
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 5969
 
3 liveuser 5970
				#設置執行失敗
5971
				$result["status"]="false";
226 liveuser 5972
 
3 liveuser 5973
				#設置執行錯誤訊息
5974
				$result["error"]=$getMeetConditionsString;
226 liveuser 5975
 
3 liveuser 5976
				#回傳結果
5977
				return $result;
226 liveuser 5978
 
3 liveuser 5979
				}#if end
226 liveuser 5980
 
3 liveuser 5981
			#如果存在 "sql:" 前置字串
5982
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 5983
 
3 liveuser 5984
				#用 "talkTo:" 分割 $buf
5985
				#涵式說明:
5986
				#將固定格式的字串分開,並回傳分開的結果。
5987
				#回傳結果:
5988
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
5989
				#$result["error"],錯誤訊息陣列
5990
				#$result["function"],當前執行的函數名稱.
5991
				#$result["oriStr"],要分割的原始字串內容
5992
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
5993
				#$result["dataCounts"],爲總共分成幾段
5994
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
5995
				#必填的參數:
5996
				$conf["stringProcess::spiltString"]["stringIn"]=$msg;#要處理的字串。
5997
				$conf["stringProcess::spiltString"]["spiltSymbol"]="sql:";#爲以哪個符號作爲分割
5998
				#可省略參數:
5999
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
6000
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
6001
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
6002
				unset($conf["stringProcess::spiltString"]);
226 liveuser 6003
 
3 liveuser 6004
				#如果分割字串失敗
6005
				if($spiltString["status"]==="false"){
226 liveuser 6006
 
3 liveuser 6007
					#設置執行失敗
6008
					$result["status"]="false";
226 liveuser 6009
 
3 liveuser 6010
					#設置執行錯誤訊息
6011
					$result["error"]=$spiltString;
226 liveuser 6012
 
3 liveuser 6013
					#回傳結果
6014
					return $result;
226 liveuser 6015
 
3 liveuser 6016
					}#if end
226 liveuser 6017
 
3 liveuser 6018
				#如果剛好分割出一筆資料
6019
				if($spiltString["dataCounts"]===1){
226 liveuser 6020
 
3 liveuser 6021
					#取的要執行的sql指令
6022
					$sql=$spiltString["dataArray"][0];
226 liveuser 6023
 
3 liveuser 6024
					#建立要執行的指令
6025
					#$cmd="echo \"".$sql."\" | mysql -u".self::$dbAccount." -p".self::$dbPassword;
226 liveuser 6026
 
3 liveuser 6027
					#函式說明:
6028
					#呼叫shell執行系統命令,並取得回傳的內容.
6029
					#回傳的結果:
6030
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6031
					#$result["error"],錯誤訊息陣列.
6032
					#$result["function"],當前執行的函數名稱.
6033
					#$result["cmd"],執行的指令內容.
6034
					#$result["output"],爲執行完二元碼後的輸出陣列.
6035
					#必填的參數
6036
					#$conf["command"],字串,要執行的指令與.
6037
					$conf["external::callShell"]["command"]="echo";
6038
					#$conf["fileArgu"],字串,變數__FILE__的內容.
226 liveuser 6039
					$conf["external::callShell"]["fileArgu"]=self::$fileArgu;
3 liveuser 6040
					#可省略參數:
6041
					#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
6042
					$conf["external::callShell"]["argu"]=array($sql,"|","mysql","-u".self::$dbAccount,"-p".self::$dbPassword);
6043
					#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
6044
					#$conf["arguIsAddr"]=array();
6045
					#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
6046
					#$conf["enablePrintDescription"]="true";
6047
					#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.
6048
					#$conf["printDescription"]="";
6049
					#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
6050
					$conf["external::callShell"]["escapeshellarg"]="true";
6051
					#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
6052
					#$conf["username"]="";
6053
					#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
6054
					#$conf["password"]="";
6055
					#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要;"false"代表不要,預設為"false".
6056
					#$conf["useScript"]="";
6057
					#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 ".qbpwcf_tmp/external/callShell/".
6058
					#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
6059
					#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
6060
					#$conf["inBackGround"]="";
6061
					#備註:
6062
					#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
6063
					#參考資料:
6064
					#exec=>http://php.net/manual/en/function.exec.php
6065
					#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
6066
					#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
6067
					$callShell=external::callShell($conf["external::callShell"]);
6068
					unset($conf["external::callShell"]);
226 liveuser 6069
 
3 liveuser 6070
					#如果執行外部指令失敗
6071
					if($callShell["status"]==="false"){
226 liveuser 6072
 
3 liveuser 6073
						#設置執行失敗
6074
						$result["status"]="false";
226 liveuser 6075
 
3 liveuser 6076
						#設置執行錯誤訊息
6077
						$result["error"]=$callShell;
226 liveuser 6078
 
3 liveuser 6079
						#回傳結果
6080
						return $result;
226 liveuser 6081
 
3 liveuser 6082
						}#if end
226 liveuser 6083
 
3 liveuser 6084
					#設置要傳給client的訊息
6085
					$result=array("data"=>$callShell["output"],"type"=>"sql");
226 liveuser 6086
 
6087
					#將程式執行後的輸出傳給client
3 liveuser 6088
					$from->send(json_encode($result));
226 liveuser 6089
 
3 liveuser 6090
					}#if end
226 liveuser 6091
 
3 liveuser 6092
				}#if end
226 liveuser 6093
 
6094
			}#if end
6095
 
3 liveuser 6096
		}#function onMessage end
226 liveuser 6097
 
3 liveuser 6098
	#建構子
6099
	function __construct(){
226 liveuser 6100
 
3 liveuser 6101
		#實做 SplObjectStorage
6102
		$this->clients = new \SplObjectStorage;
226 liveuser 6103
 
3 liveuser 6104
		}#function __construct end
226 liveuser 6105
 
3 liveuser 6106
	#在clinet的連線斷掉前
6107
    	public function onClose(ConnectionInterface $conn){
226 liveuser 6108
 
3 liveuser 6109
		// The connection is closed, remove it, as we can no longer send it messages
6110
        $this->clients->detach($conn);
6111
 
6112
        echo "Connection {$conn->resourceId} has disconnected\n";
226 liveuser 6113
 
3 liveuser 6114
		#移除連線的資訊
6115
		unset($this->connInfo[$conn->resourceId]);
226 liveuser 6116
 
3 liveuser 6117
		}#function onClose end
226 liveuser 6118
 
3 liveuser 6119
	#當出現錯誤時
6120
    	public function onError(ConnectionInterface $conn, \Exception $e){
226 liveuser 6121
 
3 liveuser 6122
		#印出錯誤訊息
6123
		echo "An error has occurred: {$e->getMessage()}\n";
6124
 
6125
		#關閉與client的socket
6126
        	$conn->close();
226 liveuser 6127
 
3 liveuser 6128
		}#fucntion onError end
226 liveuser 6129
 
6130
	}#class soldier end
6131
 
3 liveuser 6132
#使用 Ratchet\Server\IoServer 類別
6133
use Ratchet\Server\IoServer;
6134
 
6135
#使用 Ratchet\WebSocket\WsServer 類別
6136
use Ratchet\WebSocket\WsServer;
6137
 
6138
#使用 Ratchet\Http\HttpServer類別
6139
use Ratchet\Http\HttpServer;
6140
 
6141
/*
6142
類別說明:
6143
跟webSocket應用相關的類別.
6144
備註:
6145
無.
6146
*/
226 liveuser 6147
class webSock{
3 liveuser 6148
 
6149
	/*
6150
	#函式說明:
6151
	#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.
6152
	#回傳結果:
6153
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6154
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
6155
	#$result["function"],當前執行的函式名稱.
6156
	#必填參數:
6157
	#$method,物件,為物件實體或類別名稱,會自動置入該參數.
6158
	#$arguments,陣列,為呼叫方法時所用的參數.
6159
	#參考資料:
6160
	#__call=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
6161
	*/
6162
	public function __call($method,$arguments){
226 liveuser 6163
 
3 liveuser 6164
		#取得當前執行的函式
6165
		$result["function"]=__FUNCTION__;
226 liveuser 6166
 
3 liveuser 6167
		#設置執行不正常
6168
		$result["status"]="false";
226 liveuser 6169
 
3 liveuser 6170
		#設置執行錯誤
6171
		$result["error"][]=__NAMESPACE__ ."/".$method."() 不存在!";
226 liveuser 6172
 
3 liveuser 6173
		#設置所丟入的參數
6174
		$result["error"][]=$arguments;
226 liveuser 6175
 
3 liveuser 6176
		#回傳結果
6177
		return $result;
226 liveuser 6178
 
3 liveuser 6179
		}#function __call end
226 liveuser 6180
 
3 liveuser 6181
	/*
6182
	#函式說明:
6183
	#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.
6184
	#回傳結果:
6185
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6186
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
6187
	#$result["function"],當前執行的函式名稱.
6188
	#必填參數:
6189
	#$method,物件,為物件實體或類別名稱,會自動置入該參數.
6190
	#$arguments,陣列,為呼叫方法時所用的參數.
6191
	#參考資料:
6192
	#__call=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
6193
	*/
6194
	public static function __callStatic($method,$arguments){
226 liveuser 6195
 
3 liveuser 6196
		#取得當前執行的函式
6197
		$result["function"]=__FUNCTION__;
226 liveuser 6198
 
3 liveuser 6199
		#設置執行不正常
6200
		$result["status"]="false";
226 liveuser 6201
 
3 liveuser 6202
		#設置執行錯誤
6203
		$result["error"][]="欲呼叫的". __NAMESPACE__ ."/".$method."() 不存在!";
226 liveuser 6204
 
3 liveuser 6205
		#設置所丟入的參數
6206
		$result["error"][]=$arguments;
226 liveuser 6207
 
3 liveuser 6208
		#回傳結果
6209
		return $result;
226 liveuser 6210
 
3 liveuser 6211
		}#function __callStatic end
226 liveuser 6212
 
3 liveuser 6213
	/*
6214
	#函式說明:
6215
	#擴充過的Ratchet的聊天室用戶端與伺服端範例,port為8080.
6216
	#回傳結果:
6217
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6218
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 6219
	#$result["function"],當前執行的函式名稱.
3 liveuser 6220
	#必填參數:
6221
	#$conf["fileArgu"],字串,__FILE__的內容.
6222
	$conf["fileArgu"]=__FILE__;
6223
	#可省略參數:
6224
	#$conf["disReg"],字串,是否要取消apache的passProxy檢查與設定,預設為"false"不取消,"true"為取消.
6225
	#$conf["disReg"]="";
6226
	#參考資料:
6227
	#Ratchet官網=>http://socketo.me/
6228
	#聊天室範例=>http://socketo.me/docs/hello-world
6229
	#備註:
6230
	#必須要在命令列環境下執行一次,建立webSocket Server後,再於網頁端執行即可產生webSocket Client端的code.
6231
	#僅適用於https網頁透過wss連線到web socket server.
6232
	*/
6233
	public static function chatRoomDemo(&$conf){
6234
 
6235
		#初始化要回傳的結果
6236
		$result=array();
6237
 
6238
		#取得當前執行的函數名稱
6239
		$result["function"]=__FUNCTION__;
6240
 
6241
		#涵式說明:
6242
		#判斷當前環境為web還是cmd
6243
		#回傳結果:
6244
		#$result,"web"或"cmd"
6245
		if(csInformation::getEnv()==="web"){
226 liveuser 6246
 
3 liveuser 6247
			#建立 web socket client 的 js 語法
6248
			#函式說明:
6249
			#聊天室用戶端js範例
6250
			#回傳結果:
6251
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6252
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 6253
			#$result["function"],當前執行的函式名稱.
3 liveuser 6254
			#$result["content"],js語法.
6255
			#參考資料:
6256
			#Ratchet官網=>http://socketo.me/
6257
			#聊天室範例=>http://socketo.me/docs/hello-world
6258
			$chatRoomClientDemo=webSock::chatRoomClientDemo();
226 liveuser 6259
 
3 liveuser 6260
			#如果建立聊天室用戶端失敗
6261
			if($chatRoomClientDemo["status"]==="false"){
226 liveuser 6262
 
3 liveuser 6263
				#設置執行失敗
6264
				$result["status"]="false";
226 liveuser 6265
 
3 liveuser 6266
				#設置執行錯誤訊息
6267
				$result["error"]=$chatRoomClientDemo;
226 liveuser 6268
 
3 liveuser 6269
				#回傳結果
6270
				return $result;
226 liveuser 6271
 
3 liveuser 6272
				}#if end
226 liveuser 6273
 
3 liveuser 6274
			#取得聊天室的語法
6275
			$result["content"]=$chatRoomClientDemo["content"];
226 liveuser 6276
 
3 liveuser 6277
			#設置執行正常
6278
			$result["status"]="true";
226 liveuser 6279
 
3 liveuser 6280
			#回傳結果
6281
			return $result;
226 liveuser 6282
 
3 liveuser 6283
			}#if end
6284
 
6285
		#如果沒有參數
6286
		if(func_num_args()==0){
226 liveuser 6287
 
3 liveuser 6288
			#設置執行失敗
6289
			$result["status"]="false";
226 liveuser 6290
 
3 liveuser 6291
			#設置執行錯誤訊息
6292
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 6293
 
3 liveuser 6294
			#回傳結果
6295
			return $result;
226 liveuser 6296
 
3 liveuser 6297
			}#if end
226 liveuser 6298
 
3 liveuser 6299
		#如果沒有參數
6300
		if(func_num_args()==0){
226 liveuser 6301
 
3 liveuser 6302
			#設置執行失敗
6303
			$result["status"]="false";
226 liveuser 6304
 
3 liveuser 6305
			#設置執行錯誤訊息
6306
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 6307
 
3 liveuser 6308
			#回傳結果
6309
			return $result;
226 liveuser 6310
 
3 liveuser 6311
			}#if end
226 liveuser 6312
 
3 liveuser 6313
		#取得參數
6314
		$result["argu"]=$conf;
6315
 
6316
		#如果 $conf 不為陣列
6317
		if(gettype($conf)!=="array"){
226 liveuser 6318
 
3 liveuser 6319
			#設置執行失敗
6320
			$result["status"]="false";
226 liveuser 6321
 
3 liveuser 6322
			#設置執行錯誤訊息
6323
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 6324
 
3 liveuser 6325
			#如果傳入的參數為 null
6326
			if($conf===null){
226 liveuser 6327
 
3 liveuser 6328
				#設置執行錯誤訊息
6329
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 6330
 
3 liveuser 6331
				}#if end
6332
 
6333
			#回傳結果
6334
			return $result;
226 liveuser 6335
 
3 liveuser 6336
			}#if end
226 liveuser 6337
 
3 liveuser 6338
		#檢查參數
6339
		#函式說明:
6340
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
6341
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6342
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
6343
		#$result["function"],當前執行的函式名稱.
6344
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6345
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6346
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6347
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6348
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6349
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6350
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6351
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6352
		#必填寫的參數:
6353
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6354
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
6355
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
6356
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu");
6357
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
6358
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
6359
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6360
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6361
		#可以省略的參數:
6362
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
6363
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
6364
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6365
		#$conf["canNotBeEmpty"]=array();
6366
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6367
		#$conf["canBeEmpty"]=array();
6368
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
6369
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
6370
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
6371
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("disReg");
226 liveuser 6372
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3 liveuser 6373
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
6374
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6375
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("false");
6376
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6377
		#$conf["arrayCountEqualCheck"][]=array();
6378
		#參考資料來源:
6379
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6380
		#建議:
6381
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
6382
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6383
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 6384
 
3 liveuser 6385
		#如果檢查參數失敗
6386
		if($checkArguments["status"]==="false"){
226 liveuser 6387
 
3 liveuser 6388
			#設置執行失敗
6389
			$result["status"]="false";
226 liveuser 6390
 
3 liveuser 6391
			#設置執行錯誤訊息
6392
			$result["error"]=$checkArguments;
226 liveuser 6393
 
3 liveuser 6394
			#回傳結果
6395
			return $result;
226 liveuser 6396
 
3 liveuser 6397
			}#if end
226 liveuser 6398
 
3 liveuser 6399
		#如果參數檢查不通過
6400
		if($checkArguments["passed"]==="false"){
226 liveuser 6401
 
3 liveuser 6402
			#設置執行失敗
6403
			$result["status"]="false";
226 liveuser 6404
 
3 liveuser 6405
			#設置執行錯誤訊息
6406
			$result["error"]=$checkArguments;
226 liveuser 6407
 
3 liveuser 6408
			#回傳結果
6409
			return $result;
226 liveuser 6410
 
3 liveuser 6411
			}#if end
6412
 
6413
		#執行到這邊代表是命令列環境
226 liveuser 6414
 
3 liveuser 6415
		#如果沒有要取消設定 passProxy
6416
		if($conf["disReg"]==="false"){
226 liveuser 6417
 
3 liveuser 6418
			#確認設定 passProxy
6419
			#函式說明:
6420
			#註冊聊天室範例的 passProxy 設定,本函數會用root帳戶去新增.
6421
			#會在 /etc/httpd/conf/httpd.conf 檔案裡面加上以下內容
6422
			##Enable the mod_proxy modules in the HTTPD
6423
			#LoadModule proxy_module modules/mod_proxy.so
6424
			#LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
6425
			#
6426
			##ProxyPass
6427
			##If requeted web address is begin with (ws://hostdns)/wss/chatDemo, then redirect to ws://localhost:8080
6428
			#ProxyPass /wss/chatDemo ws://localhost:8080
6429
			#回傳結果:
6430
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6431
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
6432
			#$result["function"],當前執行的函式名稱.
6433
			#必填參數:
6434
			#$conf["fileArgu"],字串,__FILE__的內容.
6435
			$conf["webSock::registerChatDemo"]["fileArgu"]=$conf["fileArgu"];
6436
			#可省略參數:
6437
			#$conf["rootPasswd"],字串,root帳戶的密碼,預設為"password".
6438
			#$conf["rootPasswd"]="password";
6439
			#$conf["httpd.conf"],字串,apache設定檔的路徑與名稱,預設為"/etc/httpd/conf/httpd.conf".
226 liveuser 6440
			#$conf["httpd.conf"]="/etc/httpd/conf/httpd.conf";
3 liveuser 6441
			#備註:
6442
			#僅能在命令列環境下執行.
6443
			#改變暫存檔案權限的功能異常.
6444
			#參考資料:
6445
			#用apache的passProxy來識別服務並轉到正確的port=>https://groups.google.com/forum/#!topic/ratchet-php/dj-PgPPO_J0
6446
			$registerChatDemo=webSock::registerChatDemo($conf["webSock::registerChatDemo"]);
6447
			unset($conf["webSock::registerChatDemo"]);
226 liveuser 6448
 
3 liveuser 6449
			#如果註冊 ChatDemo 服務失敗
6450
			if($registerChatDemo["status"]==="false"){
226 liveuser 6451
 
3 liveuser 6452
				#設置執行失敗
6453
				$result["status"]="false";
226 liveuser 6454
 
3 liveuser 6455
				#設置執行錯誤訊息
6456
				$result["error"]=$registerChatDemo;
226 liveuser 6457
 
3 liveuser 6458
				#回傳結果
6459
				return $result;
226 liveuser 6460
 
3 liveuser 6461
				}#if end
226 liveuser 6462
 
3 liveuser 6463
			}#if end
226 liveuser 6464
 
3 liveuser 6465
		#函式說明:
6466
		#擴充過的Ratchet聊天室伺服端範例,port為8080.
6467
		#回傳結果:
6468
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6469
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 6470
		#$result["function"],當前執行的函式名稱.
3 liveuser 6471
		#參考資料:
6472
		#Ratchet官網=>http://socketo.me/
6473
		#聊天室範例=>http://socketo.me/docs/hello-world
6474
		#備註:
6475
		#必須要在命令列環境下執行才行.
6476
		$chatRoomServerDemo=self::chatRoomServerDemo();
226 liveuser 6477
 
3 liveuser 6478
		#如果運行 chatRoomServerDemo 失敗
6479
		if($chatRoomServerDemo["status"]==="false"){
226 liveuser 6480
 
3 liveuser 6481
			#設置執行失敗
6482
			$result["status"]="false";
226 liveuser 6483
 
3 liveuser 6484
			#設置執行錯誤訊息
6485
			$result["error"]=$chatRoomServerDemo;
226 liveuser 6486
 
3 liveuser 6487
			#回傳結果
6488
			return $result;
226 liveuser 6489
 
6490
			}#if end
6491
 
3 liveuser 6492
		#設置執行正常
6493
		$result["status"]="true";
226 liveuser 6494
 
6495
		#回傳結果
3 liveuser 6496
		return $result;
226 liveuser 6497
 
3 liveuser 6498
		}#function chatRoomDemo end
6499
 
6500
	/*
6501
	#函式說明:
6502
	#擴充過的Ratchet的聊天室用戶端與伺服端範例第二版,port為8080.
6503
	#回傳結果:
6504
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6505
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 6506
	#$result["function"],當前執行的函式名稱.
3 liveuser 6507
	#必填參數:
6508
	#$conf["fileArgu"],字串,__FILE__的內容.
6509
	$conf["fileArgu"]=__FILE__;
6510
	#可省略參數:
6511
	#$conf["disReg"],字串,是否要取消apache的passProxy檢查與設定,預設為"false"不取消,"true"為取消.
6512
	#$conf["disReg"]="";
6513
	#參考資料:
6514
	#Ratchet官網=>http://socketo.me/
6515
	#聊天室範例=>http://socketo.me/docs/hello-world
6516
	#備註:
6517
	#必須要在命令列環境下執行一次,建立webSocket Server後,再於網頁端執行即可產生webSocket Client端的code.
6518
	#僅適用於https網頁透過wss連線到web socket server.
6519
	*/
6520
	public static function chatRoomDemoV2(&$conf){
6521
 
6522
		#初始化要回傳的結果
6523
		$result=array();
6524
 
6525
		#取得當前執行的函數名稱
6526
		$result["function"]=__FUNCTION__;
6527
 
6528
		#涵式說明:
6529
		#判斷當前環境為web還是cmd
6530
		#回傳結果:
6531
		#$result,"web"或"cmd"
6532
		if(csInformation::getEnv()==="web"){
226 liveuser 6533
 
3 liveuser 6534
			#建立 web socket client 的 js 語法
6535
			#函式說明:
6536
			#聊天室用戶端js範例
6537
			#回傳結果:
6538
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6539
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 6540
			#$result["function"],當前執行的函式名稱.
3 liveuser 6541
			#$result["content"],js語法.
6542
			#參考資料:
6543
			#Ratchet官網=>http://socketo.me/
6544
			#聊天室範例=>http://socketo.me/docs/hello-world
6545
			$chatRoomClientDemo=webSock::chatRoomClientDemoV2();
226 liveuser 6546
 
3 liveuser 6547
			#如果建立聊天室用戶端失敗
6548
			if($chatRoomClientDemo["status"]==="false"){
226 liveuser 6549
 
3 liveuser 6550
				#設置執行失敗
6551
				$result["status"]="false";
226 liveuser 6552
 
3 liveuser 6553
				#設置執行錯誤訊息
6554
				$result["error"]=$chatRoomClientDemo;
226 liveuser 6555
 
3 liveuser 6556
				#回傳結果
6557
				return $result;
226 liveuser 6558
 
3 liveuser 6559
				}#if end
226 liveuser 6560
 
3 liveuser 6561
			#取得聊天室的語法
6562
			$result["content"]=$chatRoomClientDemo["content"];
226 liveuser 6563
 
3 liveuser 6564
			#設置執行正常
6565
			$result["status"]="true";
226 liveuser 6566
 
3 liveuser 6567
			#回傳結果
6568
			return $result;
226 liveuser 6569
 
3 liveuser 6570
			}#if end
6571
 
6572
		#如果沒有參數
6573
		if(func_num_args()==0){
226 liveuser 6574
 
3 liveuser 6575
			#設置執行失敗
6576
			$result["status"]="false";
226 liveuser 6577
 
3 liveuser 6578
			#設置執行錯誤訊息
6579
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 6580
 
3 liveuser 6581
			#回傳結果
6582
			return $result;
226 liveuser 6583
 
3 liveuser 6584
			}#if end
226 liveuser 6585
 
3 liveuser 6586
		#如果沒有參數
6587
		if(func_num_args()==0){
226 liveuser 6588
 
3 liveuser 6589
			#設置執行失敗
6590
			$result["status"]="false";
226 liveuser 6591
 
3 liveuser 6592
			#設置執行錯誤訊息
6593
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 6594
 
3 liveuser 6595
			#回傳結果
6596
			return $result;
226 liveuser 6597
 
3 liveuser 6598
			}#if end
226 liveuser 6599
 
3 liveuser 6600
		#取得參數
6601
		$result["argu"]=$conf;
6602
 
6603
		#如果 $conf 不為陣列
6604
		if(gettype($conf)!=="array"){
226 liveuser 6605
 
3 liveuser 6606
			#設置執行失敗
6607
			$result["status"]="false";
226 liveuser 6608
 
3 liveuser 6609
			#設置執行錯誤訊息
6610
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 6611
 
3 liveuser 6612
			#如果傳入的參數為 null
6613
			if($conf===null){
226 liveuser 6614
 
3 liveuser 6615
				#設置執行錯誤訊息
6616
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 6617
 
3 liveuser 6618
				}#if end
6619
 
6620
			#回傳結果
6621
			return $result;
226 liveuser 6622
 
3 liveuser 6623
			}#if end
226 liveuser 6624
 
3 liveuser 6625
		#檢查參數
6626
		#函式說明:
6627
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
6628
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6629
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
6630
		#$result["function"],當前執行的函式名稱.
6631
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6632
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6633
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6634
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6635
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6636
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6637
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6638
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6639
		#必填寫的參數:
6640
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6641
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
6642
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
6643
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu");
6644
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
6645
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
6646
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6647
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6648
		#可以省略的參數:
6649
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
6650
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
6651
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6652
		#$conf["canNotBeEmpty"]=array();
6653
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6654
		#$conf["canBeEmpty"]=array();
6655
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
6656
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
6657
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
6658
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("disReg");
226 liveuser 6659
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3 liveuser 6660
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
6661
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6662
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("false");
6663
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6664
		#$conf["arrayCountEqualCheck"][]=array();
6665
		#參考資料來源:
6666
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6667
		#建議:
6668
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
6669
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6670
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 6671
 
3 liveuser 6672
		#如果檢查參數失敗
6673
		if($checkArguments["status"]==="false"){
226 liveuser 6674
 
3 liveuser 6675
			#設置執行失敗
6676
			$result["status"]="false";
226 liveuser 6677
 
3 liveuser 6678
			#設置執行錯誤訊息
6679
			$result["error"]=$checkArguments;
226 liveuser 6680
 
3 liveuser 6681
			#回傳結果
6682
			return $result;
226 liveuser 6683
 
3 liveuser 6684
			}#if end
226 liveuser 6685
 
3 liveuser 6686
		#如果參數檢查不通過
6687
		if($checkArguments["passed"]==="false"){
226 liveuser 6688
 
3 liveuser 6689
			#設置執行失敗
6690
			$result["status"]="false";
226 liveuser 6691
 
3 liveuser 6692
			#設置執行錯誤訊息
6693
			$result["error"]=$checkArguments;
226 liveuser 6694
 
3 liveuser 6695
			#回傳結果
6696
			return $result;
226 liveuser 6697
 
3 liveuser 6698
			}#if end
6699
 
6700
		#執行到這邊代表是命令列環境
226 liveuser 6701
 
3 liveuser 6702
		#如果沒有要取消設定 passProxy
6703
		if($conf["disReg"]==="false"){
226 liveuser 6704
 
3 liveuser 6705
			#確認設定 passProxy
6706
			#函式說明:
6707
			#註冊聊天室範例的 passProxy 設定,本函數會用root帳戶去新增.
6708
			#會在 /etc/httpd/conf/httpd.conf 檔案裡面加上以下內容
6709
			##Enable the mod_proxy modules in the HTTPD
6710
			#LoadModule proxy_module modules/mod_proxy.so
6711
			#LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
6712
			#
6713
			##ProxyPass
6714
			##If requeted web address is begin with (ws://hostdns)/wss/chatDemo, then redirect to ws://localhost:8080
6715
			#ProxyPass /wss/chatDemo ws://localhost:8080
6716
			#回傳結果:
6717
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6718
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
6719
			#$result["function"],當前執行的函式名稱.
6720
			#必填參數:
6721
			#$conf["fileArgu"],字串,__FILE__的內容.
6722
			$conf["webSock::registerChatDemo"]["fileArgu"]=$conf["fileArgu"];
6723
			#可省略參數:
6724
			#$conf["rootPasswd"],字串,root帳戶的密碼,預設為"password".
6725
			#$conf["rootPasswd"]="password";
6726
			#$conf["httpd.conf"],字串,apache設定檔的路徑與名稱,預設為"/etc/httpd/conf/httpd.conf".
226 liveuser 6727
			#$conf["httpd.conf"]="/etc/httpd/conf/httpd.conf";
3 liveuser 6728
			#備註:
6729
			#僅能在命令列環境下執行.
6730
			#改變暫存檔案權限的功能異常.
6731
			#參考資料:
6732
			#用apache的passProxy來識別服務並轉到正確的port=>https://groups.google.com/forum/#!topic/ratchet-php/dj-PgPPO_J0
6733
			$registerChatDemo=webSock::registerChatDemo($conf["webSock::registerChatDemo"]);
6734
			unset($conf["webSock::registerChatDemo"]);
226 liveuser 6735
 
3 liveuser 6736
			#如果註冊 ChatDemo 服務失敗
6737
			if($registerChatDemo["status"]==="false"){
226 liveuser 6738
 
3 liveuser 6739
				#設置執行失敗
6740
				$result["status"]="false";
226 liveuser 6741
 
3 liveuser 6742
				#設置執行錯誤訊息
6743
				$result["error"]=$registerChatDemo;
226 liveuser 6744
 
3 liveuser 6745
				#回傳結果
6746
				return $result;
226 liveuser 6747
 
3 liveuser 6748
				}#if end
226 liveuser 6749
 
3 liveuser 6750
			}#if end
226 liveuser 6751
 
3 liveuser 6752
		#函式說明:
6753
		#擴充過的Ratchet聊天室伺服端範例,port為8080.
6754
		#回傳結果:
6755
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6756
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 6757
		#$result["function"],當前執行的函式名稱.
3 liveuser 6758
		#參考資料:
6759
		#Ratchet官網=>http://socketo.me/
6760
		#聊天室範例=>http://socketo.me/docs/hello-world
6761
		#備註:
6762
		#必須要在命令列環境下執行才行.
6763
		$chatRoomServerDemo=self::chatRoomServerDemoV2();
226 liveuser 6764
 
3 liveuser 6765
		#如果運行 chatRoomServerDemo 失敗
6766
		if($chatRoomServerDemo["status"]==="false"){
226 liveuser 6767
 
3 liveuser 6768
			#設置執行失敗
6769
			$result["status"]="false";
226 liveuser 6770
 
3 liveuser 6771
			#設置執行錯誤訊息
6772
			$result["error"]=$chatRoomServerDemo;
226 liveuser 6773
 
3 liveuser 6774
			#回傳結果
6775
			return $result;
226 liveuser 6776
 
6777
			}#if end
6778
 
3 liveuser 6779
		#設置執行正常
6780
		$result["status"]="true";
226 liveuser 6781
 
6782
		#回傳結果
3 liveuser 6783
		return $result;
226 liveuser 6784
 
3 liveuser 6785
		}#function chatRoomDemoV2 end
6786
 
6787
	/*
6788
	#函式說明:
6789
	#擴充過的Ratchet的聊天室用戶端與伺服端範例第二版,port為8080.
6790
	#回傳結果:
6791
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6792
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 6793
	#$result["function"],當前執行的函式名稱.
3 liveuser 6794
	#必填參數:
6795
	#$conf["fileArgu"],字串,__FILE__的內容.
6796
	$conf["fileArgu"]=__FILE__;
6797
	#可省略參數:
6798
	#$conf["disReg"],字串,是否要取消apache的passProxy檢查與設定,預設為"false"不取消,"true"為取消.
6799
	#$conf["disReg"]="";
6800
	#參考資料:
6801
	#Ratchet官網=>http://socketo.me/
6802
	#聊天室範例=>http://socketo.me/docs/hello-world
6803
	#備註:
6804
	#必須要在命令列環境下執行一次,建立webSocket Server後,再於網頁端執行即可產生webSocket Client端的code.
6805
	#僅適用於https網頁透過wss連線到web socket server.
6806
	*/
6807
	public static function chatRoomDemoV3(&$conf=array()){
6808
 
6809
		#初始化要回傳的結果
6810
		$result=array();
6811
 
6812
		#取得當前執行的函數名稱
6813
		$result["function"]=__FUNCTION__;
6814
 
6815
		#涵式說明:
6816
		#判斷當前環境為web還是cmd
6817
		#回傳結果:
6818
		#$result,"web"或"cmd"
6819
		if(csInformation::getEnv()==="web"){
226 liveuser 6820
 
3 liveuser 6821
			#建立 web socket client 的 js 語法
6822
			#函式說明:
6823
			#聊天室用戶端js範例
6824
			#回傳結果:
6825
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6826
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 6827
			#$result["function"],當前執行的函式名稱.
3 liveuser 6828
			#$result["content"],js語法.
6829
			#參考資料:
6830
			#Ratchet官網=>http://socketo.me/
6831
			#聊天室範例=>http://socketo.me/docs/hello-world
6832
			$chatRoomClientDemo=webSock::chatRoomClientDemoV3();
226 liveuser 6833
 
3 liveuser 6834
			#如果建立聊天室用戶端失敗
6835
			if($chatRoomClientDemo["status"]==="false"){
226 liveuser 6836
 
3 liveuser 6837
				#設置執行失敗
6838
				$result["status"]="false";
226 liveuser 6839
 
3 liveuser 6840
				#設置執行錯誤訊息
6841
				$result["error"]=$chatRoomClientDemo;
226 liveuser 6842
 
3 liveuser 6843
				#回傳結果
6844
				return $result;
226 liveuser 6845
 
3 liveuser 6846
				}#if end
226 liveuser 6847
 
3 liveuser 6848
			#取得聊天室的語法
6849
			$result["content"]=$chatRoomClientDemo["content"];
226 liveuser 6850
 
3 liveuser 6851
			#設置執行正常
6852
			$result["status"]="true";
226 liveuser 6853
 
3 liveuser 6854
			#回傳結果
6855
			return $result;
226 liveuser 6856
 
3 liveuser 6857
			}#if end
6858
 
6859
		#如果沒有參數
6860
		if(func_num_args()==0){
226 liveuser 6861
 
3 liveuser 6862
			#設置執行失敗
6863
			$result["status"]="false";
226 liveuser 6864
 
3 liveuser 6865
			#設置執行錯誤訊息
6866
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 6867
 
3 liveuser 6868
			#回傳結果
6869
			return $result;
226 liveuser 6870
 
3 liveuser 6871
			}#if end
226 liveuser 6872
 
3 liveuser 6873
		#如果沒有參數
6874
		if(func_num_args()==0){
226 liveuser 6875
 
3 liveuser 6876
			#設置執行失敗
6877
			$result["status"]="false";
226 liveuser 6878
 
3 liveuser 6879
			#設置執行錯誤訊息
6880
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 6881
 
3 liveuser 6882
			#回傳結果
6883
			return $result;
226 liveuser 6884
 
3 liveuser 6885
			}#if end
226 liveuser 6886
 
3 liveuser 6887
		#取得參數
6888
		$result["argu"]=$conf;
6889
 
6890
		#如果 $conf 不為陣列
6891
		if(gettype($conf)!=="array"){
226 liveuser 6892
 
3 liveuser 6893
			#設置執行失敗
6894
			$result["status"]="false";
226 liveuser 6895
 
3 liveuser 6896
			#設置執行錯誤訊息
6897
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 6898
 
3 liveuser 6899
			#如果傳入的參數為 null
6900
			if($conf===null){
226 liveuser 6901
 
3 liveuser 6902
				#設置執行錯誤訊息
6903
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 6904
 
3 liveuser 6905
				}#if end
6906
 
6907
			#回傳結果
6908
			return $result;
226 liveuser 6909
 
3 liveuser 6910
			}#if end
226 liveuser 6911
 
3 liveuser 6912
		#檢查參數
6913
		#函式說明:
6914
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
6915
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
6916
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
6917
		#$result["function"],當前執行的函式名稱.
6918
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
6919
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
6920
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
6921
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
6922
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
6923
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
6924
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
6925
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
6926
		#必填寫的參數:
6927
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
6928
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
6929
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
6930
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu");
6931
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
6932
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
6933
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
6934
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
6935
		#可以省略的參數:
6936
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
6937
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
6938
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
6939
		#$conf["canNotBeEmpty"]=array();
6940
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
6941
		#$conf["canBeEmpty"]=array();
6942
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
6943
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
6944
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
6945
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("disReg");
226 liveuser 6946
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3 liveuser 6947
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
6948
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
6949
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("false");
6950
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
6951
		#$conf["arrayCountEqualCheck"][]=array();
6952
		#參考資料來源:
6953
		#array_keys=>http://php.net/manual/en/function.array-keys.php
6954
		#建議:
6955
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
6956
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
6957
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 6958
 
3 liveuser 6959
		#如果檢查參數失敗
6960
		if($checkArguments["status"]==="false"){
226 liveuser 6961
 
3 liveuser 6962
			#設置執行失敗
6963
			$result["status"]="false";
226 liveuser 6964
 
3 liveuser 6965
			#設置執行錯誤訊息
6966
			$result["error"]=$checkArguments;
226 liveuser 6967
 
3 liveuser 6968
			#回傳結果
6969
			return $result;
226 liveuser 6970
 
3 liveuser 6971
			}#if end
226 liveuser 6972
 
3 liveuser 6973
		#如果參數檢查不通過
6974
		if($checkArguments["passed"]==="false"){
226 liveuser 6975
 
3 liveuser 6976
			#設置執行失敗
6977
			$result["status"]="false";
226 liveuser 6978
 
3 liveuser 6979
			#設置執行錯誤訊息
6980
			$result["error"]=$checkArguments;
226 liveuser 6981
 
3 liveuser 6982
			#回傳結果
6983
			return $result;
226 liveuser 6984
 
3 liveuser 6985
			}#if end
6986
 
6987
		#執行到這邊代表是命令列環境
226 liveuser 6988
 
3 liveuser 6989
		#如果沒有要取消設定 passProxy
6990
		if($conf["disReg"]==="false"){
226 liveuser 6991
 
3 liveuser 6992
			#確認設定 passProxy
6993
			#函式說明:
6994
			#註冊聊天室範例的 passProxy 設定,本函數會用root帳戶去新增.
6995
			#會在 /etc/httpd/conf/httpd.conf 檔案裡面加上以下內容
6996
			##Enable the mod_proxy modules in the HTTPD
6997
			#LoadModule proxy_module modules/mod_proxy.so
6998
			#LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
6999
			#
7000
			##ProxyPass
7001
			##If requeted web address is begin with (ws://hostdns)/wss/chatDemo, then redirect to ws://localhost:8080
7002
			#ProxyPass /wss/chatDemo ws://localhost:8080
7003
			#回傳結果:
7004
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7005
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
7006
			#$result["function"],當前執行的函式名稱.
7007
			#必填參數:
7008
			#$conf["fileArgu"],字串,__FILE__的內容.
7009
			$conf["webSock::registerChatDemo"]["fileArgu"]=$conf["fileArgu"];
7010
			#可省略參數:
7011
			#$conf["rootPasswd"],字串,root帳戶的密碼,預設為"password".
7012
			#$conf["rootPasswd"]="password";
7013
			#$conf["httpd.conf"],字串,apache設定檔的路徑與名稱,預設為"/etc/httpd/conf/httpd.conf".
226 liveuser 7014
			#$conf["httpd.conf"]="/etc/httpd/conf/httpd.conf";
3 liveuser 7015
			#備註:
7016
			#僅能在命令列環境下執行.
7017
			#改變暫存檔案權限的功能異常.
7018
			#參考資料:
7019
			#用apache的passProxy來識別服務並轉到正確的port=>https://groups.google.com/forum/#!topic/ratchet-php/dj-PgPPO_J0
7020
			$registerChatDemo=webSock::registerChatDemo($conf["webSock::registerChatDemo"]);
7021
			unset($conf["webSock::registerChatDemo"]);
226 liveuser 7022
 
3 liveuser 7023
			#如果註冊 ChatDemo 服務失敗
7024
			if($registerChatDemo["status"]==="false"){
226 liveuser 7025
 
3 liveuser 7026
				#設置執行失敗
7027
				$result["status"]="false";
226 liveuser 7028
 
3 liveuser 7029
				#設置執行錯誤訊息
7030
				$result["error"]=$registerChatDemo;
226 liveuser 7031
 
3 liveuser 7032
				#回傳結果
7033
				return $result;
226 liveuser 7034
 
3 liveuser 7035
				}#if end
226 liveuser 7036
 
3 liveuser 7037
			}#if end
226 liveuser 7038
 
3 liveuser 7039
		#函式說明:
7040
		#擴充過的Ratchet聊天室伺服端範例,port為8080.
7041
		#回傳結果:
7042
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7043
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
7044
		#$result["function"],當前執行的函式名稱.
7045
		#必填參數:
7046
		#$conf["fileArgu"],__FILE__的內容.
226 liveuser 7047
		$conf["webSock"]["chatRoomServerDemoV3"]["fileArgu"]=$conf["fileArgu"];
3 liveuser 7048
		#參考資料:
7049
		#Ratchet官網=>http://socketo.me/
7050
		#聊天室範例=>http://socketo.me/docs/hello-world
7051
		#備註:
7052
		#必須要在命令列環境下執行才行.
7053
		$chatRoomServerDemo=self::chatRoomServerDemoV3($conf["webSock"]["chatRoomServerDemoV3"]);
7054
		unset($conf["webSock"]["chatRoomServerDemoV3"]);
226 liveuser 7055
 
3 liveuser 7056
		#如果運行 chatRoomServerDemo 失敗
7057
		if($chatRoomServerDemo["status"]==="false"){
226 liveuser 7058
 
3 liveuser 7059
			#設置執行失敗
7060
			$result["status"]="false";
226 liveuser 7061
 
3 liveuser 7062
			#設置執行錯誤訊息
7063
			$result["error"]=$chatRoomServerDemo;
226 liveuser 7064
 
3 liveuser 7065
			#回傳結果
7066
			return $result;
226 liveuser 7067
 
7068
			}#if end
7069
 
3 liveuser 7070
		#設置執行正常
7071
		$result["status"]="true";
226 liveuser 7072
 
7073
		#回傳結果
3 liveuser 7074
		return $result;
226 liveuser 7075
 
3 liveuser 7076
		}#function chatRoomDemoV3 end
7077
 
7078
	/*
7079
	#函式說明:
7080
	#擴充過的Ratchet聊天室伺服端範例,port為8080.
7081
	#回傳結果:
7082
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7083
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 7084
	#$result["function"],當前執行的函式名稱.
3 liveuser 7085
	#必填參數:
7086
	#無.
7087
	#可省略參數:
7088
	#無.
7089
	#參考資料:
7090
	#Ratchet官網=>http://socketo.me/
7091
	#聊天室範例=>http://socketo.me/docs/hello-world
7092
	#備註:
7093
	#必須要在命令列環境下執行才行.
7094
	*/
7095
	public static function chatRoomServerDemo(){
7096
 
7097
		#初始化要回傳的結果
7098
		$result=array();
7099
 
7100
		#取得當前執行的函數名稱
7101
		$result["function"]=__FUNCTION__;
7102
 
7103
		#如果是在網頁環境
7104
		#涵式說明:
7105
		#判斷當前環境為web還是cmd
7106
		#回傳結果:
7107
		#$result,"web"或"cmd"
7108
		if(csInformation::getEnv()==="web"){
226 liveuser 7109
 
3 liveuser 7110
			#設置執行失敗
7111
			$result["status"]="false";
226 liveuser 7112
 
3 liveuser 7113
			#設置執行錯誤訊息
7114
			$result["error"][]="函數". __FUNCTION__ ."僅能在命令列環境下執行!";
226 liveuser 7115
 
3 liveuser 7116
			#回傳結果
7117
			return $result;
226 liveuser 7118
 
3 liveuser 7119
			}#if end
7120
 
7121
		#建立 Ratchet 提供的聊天室範例(適用於telnet)
226 liveuser 7122
		#It stores all the established connections, mediates data sent between each client and our Chat application, and catches errors.
7123
		#we tell the server to enter an event loop, listening for any incoming requests on port 8080.
3 liveuser 7124
		#$server = IoServer::factory(new Chat(),8080);
226 liveuser 7125
 
3 liveuser 7126
		#建立 Ratchet 提供的聊天室範例(適用於用webServer)
7127
		$server = IoServer::factory(
7128
			new HttpServer(
7129
				new WsServer(
7130
					new Chat()
7131
					)
7132
				),
7133
			8080
7134
			);
7135
 
7136
		#執行 server 端程式
7137
		$server->run();
226 liveuser 7138
 
3 liveuser 7139
		#設置執行正常
7140
		$result["status"]="true";
226 liveuser 7141
 
7142
		#回傳結果
3 liveuser 7143
		return $result;
226 liveuser 7144
 
3 liveuser 7145
		}#function chatRoomServerDemo end
226 liveuser 7146
 
3 liveuser 7147
	/*
7148
	#函式說明:
7149
	#擴充過的Ratchet聊天室伺服端範例第二版,port為8080.
7150
	#回傳結果:
7151
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7152
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 7153
	#$result["function"],當前執行的函式名稱.
3 liveuser 7154
	#必填參數:
7155
	#無.
7156
	#可省略參數:
7157
	#無.
7158
	#參考資料:
7159
	#Ratchet官網=>http://socketo.me/
7160
	#聊天室範例=>http://socketo.me/docs/hello-world
7161
	#備註:
7162
	#必須要在命令列環境下執行才行.
7163
	*/
7164
	public static function chatRoomServerDemoV2(){
7165
 
7166
		#初始化要回傳的結果
7167
		$result=array();
7168
 
7169
		#取得當前執行的函數名稱
7170
		$result["function"]=__FUNCTION__;
7171
 
7172
		#如果是在網頁環境
7173
		#涵式說明:
7174
		#判斷當前環境為web還是cmd
7175
		#回傳結果:
7176
		#$result,"web"或"cmd"
7177
		if(csInformation::getEnv()==="web"){
226 liveuser 7178
 
3 liveuser 7179
			#設置執行失敗
7180
			$result["status"]="false";
226 liveuser 7181
 
3 liveuser 7182
			#設置執行錯誤訊息
7183
			$result["error"][]="函數". __FUNCTION__ ."僅能在命令列環境下執行!";
226 liveuser 7184
 
3 liveuser 7185
			#回傳結果
7186
			return $result;
226 liveuser 7187
 
3 liveuser 7188
			}#if end
7189
 
7190
		#建立 Ratchet 提供的聊天室範例(適用於telnet)
226 liveuser 7191
		#It stores all the established connections, mediates data sent between each client and our Chat application, and catches errors.
7192
		#we tell the server to enter an event loop, listening for any incoming requests on port 8080.
3 liveuser 7193
		#$server = IoServer::factory(new Chat(),8080);
226 liveuser 7194
 
3 liveuser 7195
		#建立 Ratchet 提供的聊天室範例(適用於用webServer)
7196
		$server = IoServer::factory(
7197
			new HttpServer(
7198
				new WsServer(
7199
					new ChatV2()
7200
					)
7201
				),
7202
			8080
7203
			);
7204
 
7205
		#執行 server 端程式
7206
		$server->run();
226 liveuser 7207
 
3 liveuser 7208
		#設置執行正常
7209
		$result["status"]="true";
226 liveuser 7210
 
7211
		#回傳結果
3 liveuser 7212
		return $result;
226 liveuser 7213
 
7214
		}#function chatRoomServerDemoV2 end
7215
 
3 liveuser 7216
	/*
7217
	#函式說明:
7218
	#擴充過的Ratchet聊天室伺服端範例第三版,port為8080.
7219
	#回傳結果:
7220
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7221
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 7222
	#$result["function"],當前執行的函式名稱.
3 liveuser 7223
	#必填參數:
7224
	#$conf["fileArgu"],__FILE__的內容.
7225
	$conf["fileArgu"]=__FILE__;
7226
	#可省略參數:
7227
	#無.
7228
	#參考資料:
7229
	#Ratchet官網=>http://socketo.me/
7230
	#聊天室範例=>http://socketo.me/docs/hello-world
7231
	#備註:
7232
	#必須要在命令列環境下執行才行.
7233
	*/
7234
	public static function chatRoomServerDemoV3(&$conf=array()){
7235
 
7236
		#初始化要回傳的結果
7237
		$result=array();
7238
 
7239
		#取得當前執行的函數名稱
7240
		$result["function"]=__FUNCTION__;
7241
 
7242
		#如果沒有參數
7243
		if(func_num_args()==0){
226 liveuser 7244
 
3 liveuser 7245
			#設置執行失敗
7246
			$result["status"]="false";
226 liveuser 7247
 
3 liveuser 7248
			#設置執行錯誤訊息
7249
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 7250
 
3 liveuser 7251
			#回傳結果
7252
			return $result;
226 liveuser 7253
 
3 liveuser 7254
			}#if end
7255
 
7256
		#涵式說明:
7257
		#判斷當前環境為web還是cmd
7258
		#回傳結果:
7259
		#$result,"web"或"cmd"
7260
		if(csInformation::getEnv()==="web"){
226 liveuser 7261
 
3 liveuser 7262
			#設置執行失敗
7263
			$result["status"]="false";
226 liveuser 7264
 
3 liveuser 7265
			#設置執行錯誤訊息
7266
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 7267
 
3 liveuser 7268
			#回傳結果
7269
			return $result;
226 liveuser 7270
 
3 liveuser 7271
			}#if end
7272
 
7273
		#取得參數
7274
		$result["argu"]=$conf;
7275
 
7276
		#如果 $conf 不為陣列
7277
		if(gettype($conf)!=="array"){
226 liveuser 7278
 
3 liveuser 7279
			#設置執行失敗
7280
			$result["status"]="false";
226 liveuser 7281
 
3 liveuser 7282
			#設置執行錯誤訊息
7283
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 7284
 
3 liveuser 7285
			#如果傳入的參數為 null
7286
			if($conf===null){
226 liveuser 7287
 
3 liveuser 7288
				#設置執行錯誤訊息
7289
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 7290
 
3 liveuser 7291
				}#if end
7292
 
7293
			#回傳結果
7294
			return $result;
226 liveuser 7295
 
3 liveuser 7296
			}#if end
7297
 
7298
		#檢查參數
7299
		#函式說明:
7300
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
7301
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7302
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
7303
		#$result["function"],當前執行的函式名稱.
7304
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
7305
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
7306
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
7307
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
7308
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
7309
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
7310
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
7311
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
7312
		#必填寫的參數:
7313
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
7314
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
7315
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
7316
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu");
7317
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
7318
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
7319
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
7320
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
7321
		#可以省略的參數:
7322
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
7323
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
7324
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
7325
		#$conf["canNotBeEmpty"]=array();
7326
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
7327
		#$conf["canBeEmpty"]=array();
7328
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
7329
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
7330
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
7331
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("entry","connVar","disReg");
226 liveuser 7332
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3 liveuser 7333
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string");
7334
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
7335
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("false","conn","false");
7336
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
7337
		#$conf["arrayCountEqualCheck"][]=array();
7338
		#參考資料來源:
7339
		#array_keys=>http://php.net/manual/en/function.array-keys.php
7340
		#建議:
7341
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
7342
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
7343
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 7344
 
3 liveuser 7345
		#如果檢查參數失敗
7346
		if($checkArguments["status"]==="false"){
226 liveuser 7347
 
3 liveuser 7348
			#設置執行失敗
7349
			$result["status"]="false";
226 liveuser 7350
 
3 liveuser 7351
			#設置執行錯誤訊息
7352
			$result["error"]=$checkArguments;
226 liveuser 7353
 
3 liveuser 7354
			#回傳結果
7355
			return $result;
226 liveuser 7356
 
3 liveuser 7357
			}#if end
226 liveuser 7358
 
3 liveuser 7359
		#如果參數檢查不通過
7360
		if($checkArguments["passed"]==="false"){
226 liveuser 7361
 
3 liveuser 7362
			#設置執行失敗
7363
			$result["status"]="false";
226 liveuser 7364
 
3 liveuser 7365
			#設置執行錯誤訊息
7366
			$result["error"]=$checkArguments;
226 liveuser 7367
 
3 liveuser 7368
			#回傳結果
7369
			return $result;
226 liveuser 7370
 
3 liveuser 7371
			}#if end
7372
 
7373
		#物件化ChatV3類別
7374
		$Chat3=new ChatV3();
226 liveuser 7375
 
3 liveuser 7376
		#設置屬性 fileArgu
7377
		$Chat3::$fileArgu=$conf["fileArgu"];
7378
 
7379
		#建立 Ratchet 提供的聊天室範例(適用於telnet)
226 liveuser 7380
		#It stores all the established connections, mediates data sent between each client and our Chat application, and catches errors.
7381
		#we tell the server to enter an event loop, listening for any incoming requests on port 8080.
3 liveuser 7382
		#$server = IoServer::factory(new Chat(),8080);
226 liveuser 7383
 
3 liveuser 7384
		#建立 Ratchet 提供的聊天室範例(適用於用webServer)
7385
		$server = IoServer::factory(
7386
			new HttpServer(
7387
				new WsServer(
7388
					$Chat3
7389
					)
7390
				),
7391
			8080
7392
			);
7393
 
7394
		#執行 server 端程式
7395
		$server->run();
226 liveuser 7396
 
3 liveuser 7397
		#設置執行正常
7398
		$result["status"]="true";
226 liveuser 7399
 
7400
		#回傳結果
3 liveuser 7401
		return $result;
226 liveuser 7402
 
7403
		}#function chatRoomServerDemoV3 end
7404
 
3 liveuser 7405
	/*
7406
	#函式說明:
7407
	#擴充過的Ratchet聊天室伺服端soldier範例.提供cmd:跟sql:指令支援.
7408
	#回傳結果:
7409
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7410
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 7411
	#$result["function"],當前執行的函式名稱.
3 liveuser 7412
	#必填參數:
7413
	#$conf["fileArgu"],__FILE__的內容.
7414
	$conf["fileArgu"]=__FILE__;
7415
	#可省略參數:
7416
	#$conf["port"],要 listen 的 port
7417
	#$conf["port"]="8080";
7418
	#參考資料:
7419
	#Ratchet官網=>http://socketo.me/
7420
	#聊天室範例=>http://socketo.me/docs/hello-world
7421
	#備註:
7422
	#必須要在命令列環境下執行才行.
7423
	*/
7424
	public static function soldierServerDemo(&$conf){
7425
 
7426
		#初始化要回傳的結果
7427
		$result=array();
7428
 
7429
		#取得當前執行的函數名稱
7430
		$result["function"]=__FUNCTION__;
7431
 
7432
		#如果沒有參數
7433
		if(func_num_args()==0){
226 liveuser 7434
 
3 liveuser 7435
			#設置執行失敗
7436
			$result["status"]="false";
226 liveuser 7437
 
3 liveuser 7438
			#設置執行錯誤訊息
7439
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 7440
 
3 liveuser 7441
			#回傳結果
7442
			return $result;
226 liveuser 7443
 
3 liveuser 7444
			}#if end
7445
 
7446
		#涵式說明:
7447
		#判斷當前環境為web還是cmd
7448
		#回傳結果:
7449
		#$result,"web"或"cmd"
7450
		if(csInformation::getEnv()==="web"){
226 liveuser 7451
 
3 liveuser 7452
			#設置執行失敗
7453
			$result["status"]="false";
226 liveuser 7454
 
3 liveuser 7455
			#設置執行錯誤訊息
7456
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 7457
 
3 liveuser 7458
			#回傳結果
7459
			return $result;
226 liveuser 7460
 
3 liveuser 7461
			}#if end
7462
 
7463
		#取得參數
7464
		$result["argu"]=$conf;
7465
 
7466
		#如果 $conf 不為陣列
7467
		if(gettype($conf)!=="array"){
226 liveuser 7468
 
3 liveuser 7469
			#設置執行失敗
7470
			$result["status"]="false";
226 liveuser 7471
 
3 liveuser 7472
			#設置執行錯誤訊息
7473
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 7474
 
3 liveuser 7475
			#如果傳入的參數為 null
7476
			if($conf===null){
226 liveuser 7477
 
3 liveuser 7478
				#設置執行錯誤訊息
7479
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 7480
 
3 liveuser 7481
				}#if end
7482
 
7483
			#回傳結果
7484
			return $result;
226 liveuser 7485
 
3 liveuser 7486
			}#if end
7487
 
7488
		#檢查參數
7489
		#函式說明:
7490
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
7491
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7492
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
7493
		#$result["function"],當前執行的函式名稱.
7494
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
7495
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
7496
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
7497
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
7498
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
7499
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
7500
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
7501
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
7502
		#必填寫的參數:
7503
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
7504
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
7505
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
7506
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu");
7507
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
7508
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
7509
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
7510
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
7511
		#可以省略的參數:
7512
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
7513
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
7514
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
7515
		#$conf["canNotBeEmpty"]=array();
7516
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
7517
		#$conf["canBeEmpty"]=array();
7518
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
7519
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
7520
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
7521
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("port");
226 liveuser 7522
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3 liveuser 7523
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("integer");
7524
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
7525
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(8080);
7526
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
7527
		#$conf["arrayCountEqualCheck"][]=array();
7528
		#參考資料來源:
7529
		#array_keys=>http://php.net/manual/en/function.array-keys.php
7530
		#建議:
7531
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
7532
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
7533
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 7534
 
3 liveuser 7535
		#如果檢查參數失敗
7536
		if($checkArguments["status"]==="false"){
226 liveuser 7537
 
3 liveuser 7538
			#設置執行失敗
7539
			$result["status"]="false";
226 liveuser 7540
 
3 liveuser 7541
			#設置執行錯誤訊息
7542
			$result["error"]=$checkArguments;
226 liveuser 7543
 
3 liveuser 7544
			#回傳結果
7545
			return $result;
226 liveuser 7546
 
3 liveuser 7547
			}#if end
226 liveuser 7548
 
3 liveuser 7549
		#如果參數檢查不通過
7550
		if($checkArguments["passed"]==="false"){
226 liveuser 7551
 
3 liveuser 7552
			#設置執行失敗
7553
			$result["status"]="false";
226 liveuser 7554
 
3 liveuser 7555
			#設置執行錯誤訊息
7556
			$result["error"]=$checkArguments;
226 liveuser 7557
 
3 liveuser 7558
			#回傳結果
7559
			return $result;
226 liveuser 7560
 
3 liveuser 7561
			}#if end
7562
 
7563
		#建立 Ratchet 提供的聊天室範例(適用於telnet)
226 liveuser 7564
		#It stores all the established connections, mediates data sent between each client and our Chat application, and catches errors.
7565
		#we tell the server to enter an event loop, listening for any incoming requests on port 8080.
3 liveuser 7566
		#$server = IoServer::factory(new Chat(),8080);
226 liveuser 7567
 
3 liveuser 7568
		#建立 soldier 物件
7569
		$soldier=new soldier();
226 liveuser 7570
 
3 liveuser 7571
		#設置fileArgu屬性
7572
		$soldier::$fileArgu=$conf["fileArgu"];
226 liveuser 7573
 
3 liveuser 7574
		#建立 Ratchet 提供的聊天室範例(適用於用webServer)
7575
		$server = IoServer::factory(
7576
			new HttpServer(
7577
				new WsServer(
7578
					$soldier
7579
					)
7580
				),
7581
			$conf["port"]
7582
			);
7583
 
7584
		#執行 server 端程式
7585
		$server->run();
226 liveuser 7586
 
3 liveuser 7587
		#設置執行正常
7588
		$result["status"]="true";
226 liveuser 7589
 
7590
		#回傳結果
3 liveuser 7591
		return $result;
226 liveuser 7592
 
7593
		}#function soldierServerDemo end
7594
 
3 liveuser 7595
	/*
7596
	#函式說明:
7597
	#擴充過的Ratchet聊天室用戶端js範例
7598
	#回傳結果:
7599
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7600
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 7601
	#$result["function"],當前執行的函式名稱.
3 liveuser 7602
	#$result["content"],html.
7603
	#必填參數:
7604
	#無.
7605
	#可省略參數:
7606
	#無.
7607
	#參考資料:
7608
	#Ratchet官網=>http://socketo.me/
7609
	#用apache的proxy來判斷為哪個服務,導到對應的port裡面=>https://groups.google.com/forum/#!topic/ratchet-php/dj-PgPPO_J0
7610
	#聊天室範例=>http://socketo.me/docs/hello-world
7611
	#備註:
226 liveuser 7612
	#僅適用於https網頁透過wss連線到web socket server.
3 liveuser 7613
	*/
7614
	public static function chatRoomClientDemo(){
226 liveuser 7615
 
3 liveuser 7616
		#初始化要回傳的結果
7617
		$result=array();
7618
 
7619
		#初始化儲存html的變數
7620
		$result["content"]="";
7621
 
7622
		#取得當前執行的函數名稱
7623
		$result["function"]=__FUNCTION__;
226 liveuser 7624
 
3 liveuser 7625
		#初始化帳號密碼
7626
		$ac="";
7627
		$pw="";
226 liveuser 7628
 
3 liveuser 7629
		#如果存在 $_SESSION["account"]
7630
		if(isset($_SESSION["account"])){
226 liveuser 7631
 
3 liveuser 7632
			#取得帳戶
7633
			$ac=$_SESSION["account"];
226 liveuser 7634
 
3 liveuser 7635
			}#if end
226 liveuser 7636
 
3 liveuser 7637
		#如果 this->$passwordCol 不為 ""
7638
		if(Chat::$passwordCol!==""){
226 liveuser 7639
 
3 liveuser 7640
			#如果存在 $_SESSION["password"]
7641
			if(isset($_SESSION["password"])){
226 liveuser 7642
 
3 liveuser 7643
				#取得帳戶
7644
				$pw=$_SESSION["password"];
226 liveuser 7645
 
3 liveuser 7646
				}#if end
226 liveuser 7647
 
3 liveuser 7648
			}#if end
226 liveuser 7649
 
3 liveuser 7650
		#取得 server 的 ip
7651
		#涵式說明:
7652
		#取得伺服器的IP,並回傳。
7653
		#回傳的結果:
7654
		#$result,伺服端的IP
7655
		#備註:
7656
		#伺服端必須被 localhost 以外的網址連結才會出現正確的IP
7657
		$getServerIP=csInformation::getServerIP();
226 liveuser 7658
 
3 liveuser 7659
		#設置用戶端連線到webSocket的範例
7660
		$script="<script>
226 liveuser 7661
 
3 liveuser 7662
			//取得帳號密碼
7663
			ac='".$ac."';
7664
			pw='".$pw."';
226 liveuser 7665
 
3 liveuser 7666
			//設置目前尚為連線到 webSocket Server
7667
			connected='false';
226 liveuser 7668
 
3 liveuser 7669
			//設置儲存應該要斷線的webSocket,避免太多連線在伺服器.
7670
			//wbClosed='';
226 liveuser 7671
 
3 liveuser 7672
			//設置儲存webSocket連線的變數
7673
			wb='';
226 liveuser 7674
 
3 liveuser 7675
			//連線到 web socket
7676
			connWebSock();
226 liveuser 7677
 
3 liveuser 7678
			//連線到 web socket
7679
			function connWebSock()
7680
			{
7681
				//建立 web socket 連線到 wss://localhost/wss/chatDemo
7682
				var conn = new WebSocket('wss://".$getServerIP."/wss/chatDemo');
226 liveuser 7683
 
3 liveuser 7684
				//當連線成功後
7685
				conn.onopen = function(e){
226 liveuser 7686
 
3 liveuser 7687
					//印出連線成功訊息到console
7688
					console.log(\"Connection established!\");
226 liveuser 7689
 
3 liveuser 7690
					//設置已經連上 webSocket server
7691
					connected='true';
226 liveuser 7692
 
3 liveuser 7693
					//另存 webSocket 物件
7694
					wb=conn;
226 liveuser 7695
 
3 liveuser 7696
					/*
7697
					//如果存在前一個連線物件
7698
					if(wbClosed!==''){
226 liveuser 7699
 
3 liveuser 7700
						//提示關閉前個連線
7701
						console.log(\"close last connection!\");
226 liveuser 7702
 
3 liveuser 7703
						//關閉之前的連線
7704
						wbClosed.close();
226 liveuser 7705
 
3 liveuser 7706
						//清空
7707
						wbClosed='';
226 liveuser 7708
 
3 liveuser 7709
						}
7710
					*/
226 liveuser 7711
 
3 liveuser 7712
					}
7713
 
7714
				//當有收到訊息時
7715
				conn.onmessage = function(e){
226 liveuser 7716
 
3 liveuser 7717
					//將訊息顯現在console
7718
					console.log(e.data);
226 liveuser 7719
 
3 liveuser 7720
					//將訊息寫到文字方框裡面
7721
					$('#history').val(e.data+'\\r\\n'+$('#history').val());
226 liveuser 7722
 
3 liveuser 7723
					//解析json字串
226 liveuser 7724
					data=JSON.parse(e.data);
7725
 
3 liveuser 7726
					//如果有查到帳號
7727
					if(ac!==''){
226 liveuser 7728
 
3 liveuser 7729
						//如果要求輸入帳號
7730
						if(data==='Please input your account! ex:account:ws1'){
226 liveuser 7731
 
3 liveuser 7732
							//傳送帳號
7733
							conn.send('account:'+ac);
226 liveuser 7734
 
3 liveuser 7735
							}
226 liveuser 7736
 
3 liveuser 7737
						//如果有查到密碼
7738
						if(pw!==''){
226 liveuser 7739
 
7740
							//如果要求輸入密碼
3 liveuser 7741
							if(data==='Please input your password! ex:password:ws1'){
226 liveuser 7742
 
3 liveuser 7743
								//傳送密碼
7744
								conn.send('password:'+pw);
226 liveuser 7745
 
3 liveuser 7746
								}
226 liveuser 7747
 
3 liveuser 7748
							}
226 liveuser 7749
 
3 liveuser 7750
						}
226 liveuser 7751
 
3 liveuser 7752
					}
226 liveuser 7753
 
3 liveuser 7754
				//當連線斷開後
7755
				conn.onclose = function(e){
226 liveuser 7756
 
3 liveuser 7757
					//印出連線斷開的訊息到console
7758
					//console.log(\"Connection end!\");
226 liveuser 7759
 
3 liveuser 7760
					//設置未連上 webSocket server
7761
					connected='false';
226 liveuser 7762
 
3 liveuser 7763
					/*
7764
					//如果有之前的連線物件
7765
					if(wb!==''){
226 liveuser 7766
 
3 liveuser 7767
						//儲存應該要斷線的webSocket,避免太多連線在伺服器.
7768
						wbClosed=wb;
226 liveuser 7769
 
3 liveuser 7770
						}
7771
					*/
226 liveuser 7772
 
3 liveuser 7773
					//清空 webSocket 物件
7774
					wb='';
226 liveuser 7775
 
3 liveuser 7776
					//指定1秒刷新一次
226 liveuser 7777
					setTimeout('connWebSock()',1000);
7778
 
3 liveuser 7779
					}
226 liveuser 7780
 
7781
				}
7782
 
3 liveuser 7783
			//當按下送出按鈕
7784
			$('#send').on('click',function(){
226 liveuser 7785
 
3 liveuser 7786
				//如果已經連到 webSocket server 了
7787
				if(connected==='true'){
226 liveuser 7788
 
3 liveuser 7789
					//傳送訊息
7790
					wb.send($('#input').val());
226 liveuser 7791
 
3 liveuser 7792
					//清空訊息輸入欄
7793
					$('#input').val('');
226 liveuser 7794
 
3 liveuser 7795
					}
226 liveuser 7796
 
3 liveuser 7797
				});
226 liveuser 7798
 
3 liveuser 7799
			//重新整理頁面
7800
			function myrefresh(){
226 liveuser 7801
 
3 liveuser 7802
				//重新整理頁面
7803
				window.location.reload();
226 liveuser 7804
 
3 liveuser 7805
				}
226 liveuser 7806
 
3 liveuser 7807
			</script>";
226 liveuser 7808
 
3 liveuser 7809
		#設置存放歷史訊息的方框
7810
		#涵式說明:
7811
		#可以輸入文字的區塊
7812
		#回傳結果:
7813
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7814
		#$result["function"],當前執行的函數.
7815
		#$result["error"],錯誤訊息陣列.
226 liveuser 7816
		#$result["content"],按鈕語法.
3 liveuser 7817
		#必填的參數:
7818
		$conf["form::inputTextArea"]["name"]="history";#爲文字輸入框的名稱,供接收端辨識用。
7819
		$conf["form::inputTextArea"]["readOnly"]="true";#爲是否要爲唯讀,如果爲"true",則爲唯讀。反之則爲"false"。
7820
		#可省略的參數:
7821
		#$conf["id"],字串,文字區塊的id,供javaScript呼叫用.
7822
		$conf["form::inputTextArea"]["id"]="history";
7823
		#$conf["width"]="";#為輸入框的寬度,預設不指定.
7824
		#$conf["cols"]="";#爲文字輸入框的欄位數(寬),預設爲按照瀏覽器設定值。
7825
		#$conf["rows"]="";#爲文字輸入框的列數(高),預設爲按照瀏覽器設定值。
7826
		#$conf["maxInputLength"]="";#爲文字輸入的長度限制,預設無限制。
7827
		#$conf["defaultText"]="";#爲文字輸入框裏面的預設文字內容,預設是空的。
7828
		#$conf["class"]=;#爲要套用的css樣式。如果沒有指定 ,則採用預設的css樣式,"__inputTextAreaCssStyle",其屬性爲 "width:100%","height:120px","font-size:30px"
7829
		#$conf["jsActivitor"]="";#爲觸發js的條件,可以是"onChange"(已改變內容時)...,須搭配$conf["jsSubmitActionTarget"]參數。
7830
		#$conf["jsAction"]="";#爲該js是要做什麼,可以是"document.testForm.submit()"(傳送名爲testForm的表單內容)...,須搭配$conf["jsActivitor"]參數。
7831
		#$conf["formStart"]="true";#爲是否要以<form>開頭,"true"表示"是",也可以看成表單的開始,預設為"false".
7832
		#$conf["formAction"]="";#表單遞交的目的地,若$conf["formStart"]為"true",則該參數不能省略.
7833
		#$conf["formName"]="";#爲該表單的名稱
7834
		#$conf["formMethod"]="";#爲傳輸的方法,若沒設定則預設爲post,其他可用的參數爲get。
7835
		#$conf["formTarget"]="";#為顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。
7836
		#$conf["formEnd"]="true";#爲是否要以<form>結尾,"true"表示"是",也可以看成表單的結束,預設為"false".
7837
		#$conf["comment"],字串,輸入方框上面要放哪些註解文字,亦即用label來呈現,同時指定"for"屬性的數值為當前"input"標籤的id,意即參數"name"的內容.
7838
		#$conf["comment"]="";
7839
		#$conf["required"],字串,該欄位是否必填,"true"為必填,"false"為可留空,預設為"false".
7840
		#$conf["required"]="true";
7841
		#$conf["placeholder"],字串,當沒有內容時要顯示的內容.
7842
		#$conf["placeholder"]="";
7843
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是",也可以看作新的一列開始,預設為"false".
7844
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是",也可以看成列裏面的元素開始,預設為"false".
7845
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是",也可以看成列裏面的元素結束,預設為"false".
7846
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是",也可以看作該列結束,預設為"false".
7847
		#參考資料來源:
7848
		#input=>http://www.w3schools.com/tags/tag_input.asp
7849
		$inputTextArea=form::inputTextArea($conf["form::inputTextArea"]);
7850
		unset($conf["form::inputTextArea"]);
226 liveuser 7851
 
3 liveuser 7852
		#如果建立文字方框失敗
7853
		if($inputTextArea["status"]==="false"){
226 liveuser 7854
 
3 liveuser 7855
			#設置執行失敗
7856
			$result["status"]="false";
226 liveuser 7857
 
3 liveuser 7858
			#設置執行錯誤訊息
7859
			$result["error"]=$inputTextArea;
226 liveuser 7860
 
3 liveuser 7861
			#回傳結果
7862
			return $result;
226 liveuser 7863
 
7864
			}#if end
7865
 
3 liveuser 7866
		#串連文字訊息方框
7867
		$result["content"]=$result["content"].$inputTextArea["content"];
226 liveuser 7868
 
3 liveuser 7869
		#設置填寫要傳送的訊息輸入方框
7870
		#涵式說明:
7871
		#可以輸入文字的表單
7872
		#回傳的結果:
7873
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7874
		#$result["function"],當前執行的函數.
7875
		#$result["error"],錯誤訊息陣列.
226 liveuser 7876
		#$result["content"],按鈕語法.
3 liveuser 7877
		#必填的參數
7878
		$conf["form::inputText"]["name"]="data";#爲該文字輸入框的名稱,用於讓接收頁面讀取的名稱。
7879
		$conf["form::inputText"]["readOnly"]="false";#爲該文字框是否可以填寫資料,若要只能觀看不能填寫,那麼就必須將其值設爲"true",反之要設爲"false"
7880
		#可省略的參數:
7881
		#$conf["width"]="";#爲文字框的外觀長度,預設為"100%".
7882
		#$conf["maxInputLength"]="";#爲可輸入的最大位元長度,預設不限制。
7883
		#$conf["autoFocus"]="true";#是否為將填寫的指標移到該表單,"true"代表要,預設為"false".
226 liveuser 7884
		#$conf["value"]="";#爲該文字框預設要顯示的文字,預設爲""。
3 liveuser 7885
		#$conf["class"]="";#爲要套用的css樣式,若省略,則會套用預設的 "__inputTextCssStyle" 樣式,其屬性爲 "width:100%","font-size:30px"
7886
		#$conf["jsActivitor"]="";#爲觸發js的條件,可以是"onChange"(已改變內容時)、"onClick"(按下按鈕時)、"onkeyup"(當鍵盤按下放開後)、"onmouseover"(當滑鼠移過去的時候)...,須搭配$conf["jsSubmitActionTarget"]參數。
226 liveuser 7887
		#$conf["jsAction"]="";#爲該js是要做什麼,可以是"document.testForm.submit()"(傳送名爲testForm的表單內容)...,須搭配$conf["jsActivitor"]參數。
3 liveuser 7888
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是"。也可以看作新的一列開始,預設為"false".
7889
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是"。也可以看成列裏面的元素開始,預設為"false".
7890
		#$conf["formStart"]="true";#爲是否要以<form>開頭,"true"表示"是",也可以看成表單的開始,預設為"false".
7891
		#$conf["formAction"]="";#表單遞交的目的地,若$conf["formStart"]為"true",則該參數不能省略.
7892
		#$conf["formName"]="";#爲該表單的名稱
7893
		#$conf["formMethod"]="";#爲傳輸的方法,若沒設定則預設爲post,其他可用的參數爲get。
7894
		#$conf["formTarget"]="";#為顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。
7895
		#$conf["tableStart"]="true";#爲該表單是否要以<table>開始。"true"爲是,預設為"false".
7896
		#$conf["tableClass"]="";#表格要套用的css樣式,若爲"__withoutBorder"的話則套用無框線的預設樣式;若爲"__withBorder"的話,則爲有框線的預設樣式,預設為"__withoutBorder".
7897
		#$conf["formEnd"]="true";#爲是否要以<form>結尾,"true"表示"是",也可以看成表單的結束,預設為"false".
7898
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是"。也可以看成列裏面的元素結束,預設為"false".
7899
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是"。也可以看作該列結束,預設為"false".
7900
		#$conf["tableEnd"]="true";#爲該表單是否要以</table>結尾,"true"爲是,預設為"false".
7901
		#$conf["autocomplete"],字串,是否依據使用者過往輸入的記錄來提示可能要的輸入內容,"on"為啟用,"off"為停用,預設為"on".
7902
		#$conf["autocomplete"]="off";
7903
		#$conf["required"],字串,該欄位是否必填,"true"為必填,"false"為可留空,預設為"false".
7904
		#$conf["required"]="true";
7905
		#$conf["comment"],字串,輸入方框上面要放哪些註解文字,亦即用label來呈現,同時指定"for"屬性的數值為當前"input"標籤的id,意即參數"name"的內容.
7906
		#$conf["comment"]="";
7907
		#$conf["placeholder"],字串,當沒有內容時要顯示的內容.
7908
		#$conf["placeholder"]="";
7909
		#$conf["br"],字串,"true"代表最後要換行,預設為"false".
7910
		#$conf["br"]="true";
7911
		#$conf["p"],字串,"true"代表最後要空一行,預設為"false".
7912
		#$conf["p"]="true";
7913
		#$conf["id"],字串,該元素的id,預設不使用.
7914
		$conf["form::inputText"]["id"]="input";
7915
		#參考資料來源:
7916
		#input=>http://www.w3schools.com/tags/tag_input.asp
7917
		$inputText=form::inputText($conf["form::inputText"]);
7918
		unset($conf["form::inputText"]);
226 liveuser 7919
 
3 liveuser 7920
		#如果輸入文字框失敗
7921
		if($inputText["status"]==="false"){
226 liveuser 7922
 
3 liveuser 7923
			#設置執行失敗
7924
			$result["status"]="false";
226 liveuser 7925
 
3 liveuser 7926
			#設置執行錯誤訊息
7927
			$result["error"]=$inputText;
226 liveuser 7928
 
3 liveuser 7929
			#回傳結果
7930
			return $result;
226 liveuser 7931
 
7932
			}#if end
7933
 
3 liveuser 7934
		#文字輸入框
7935
		$result["content"]=$result["content"].$inputText["content"];
226 liveuser 7936
 
3 liveuser 7937
		#設置觸發的按鈕
7938
		#函式說明:
7939
		#放置按鈕
7940
		#回傳結果:
7941
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7942
		#$result["function"],當前執行的函數.
7943
		#$result["error"],錯誤訊息陣列.
226 liveuser 7944
		#$result["content"],按鈕語法.
3 liveuser 7945
		#必要的參數:
7946
		$conf["form::button"]["buttonDisplayValue"]="Send";#爲按鈕上顯示的文字。
7947
		#可省略的參數:
7948
		#$conf["buttonStyleName"]="";#可省略,爲按鈕所要使用的css樣式類別名稱,預設的css樣式爲 __simpleButtonLinkDefaultButtonCssStyle 。
7949
			#其屬性爲   "width","height","font-size","text-align"
7950
			#其屬性值爲 "100%" ,  "50"  ,    "30"   ,   "center"
7951
		#$conf["form::button"]["buttonActionScriptFunction"]="conn.send('Hello!');";#可省略,爲按下按鈕時所要執行的javaScript函式或程式,預設不設定。
7952
			#"document.forms.formName.submit()"爲傳送名爲testForm的表單內容
7953
			#"window.print()"爲使用瀏覽器內建工具列印當前網頁
7954
			#若搭配 javaScript 類別的 confirmWindow 函數的回傳結果,則會有確認視窗的效果.
7955
		#$conf["buttonBorder"]="";#可省略,爲IE9內會自動產生外框,此爲外框的厚度,屬性值爲正整數,預設爲0。
7956
		#$conf["disabled"]="true";#可省略,為按鈕的功能是否要取消,若為"true"則代表要取消,若為"false"則代表功能正常,預設為"false".
7957
		#$conf["tableStart"]="true";#爲是否要表格開始。"false"代表否,"true"代表是。預設爲"false"。
7958
		#$conf["tableClass"]="";#表格要套用的css樣式,若省略的話,則預設爲 __defaultTbaleCsssStyle 其屬性爲 table-layout:fixed word-break:break-all width:100% ,須搭配 $conf["tablStart"] 與 $conf["tableEnd"] 使用。
7959
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是"。也可以看作新的一列開始,預設為"false".
7960
		#$conf["trClass"]="__withoutBorder";#<tr>要套用的css樣式,預設為"__withoutBorder",亦即沒有框線的樣式;"__withBorder"則爲有框線的樣式
7961
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是"。也可以看成列裏面的元素開始,預設為"false".
7962
		#$conf["tdClass"]="__withoutBorder";#<td>要套用的css樣式,"__withoutBorder"爲沒有框線的樣式;__withBorder爲有框線的樣式
7963
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是"。也可以看成列裏面的元素結束,預設為"false".
7964
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是"。也可以看作該列結束,預設為"false".
7965
		#$conf["tableEnd"]="true";#爲是否要表格結束。"false"代表否,"true"代表是,預設爲"false"。
7966
		#$conf["formStart"]="true";#爲是否要表單開始,如果爲"true"則代表要表單開始,預設為"false".
7967
		#$conf["action"]="";#爲表單要傳送到哪個頁面,須搭配$conf["formStart"]與$conf["formEnd"]參數使用
7968
		#$conf["target"]="";#為目標表單顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。須搭配$conf["formStart"]與$conf["formEnd"]參數使用
7969
		#$conf["formEnd"]="true";#爲是否要表單結束,如果爲"true"則代表要表單結束,預設為"false".
7970
		#$conf["formId"],字串,表單的id.
7971
		#$conf["formId"]="";
7972
		#$conf["buttonId"],字串,按鈕的id.
7973
		$conf["form::button"]["buttonId"]="send";
7974
		#參考資料來源:
7975
		#http://stackoverflow.com/questions/3014649/how-to-disable-html-button-using-javascript
7976
		$button=form::button($conf["form::button"]);
7977
		unset($conf["form::button"]);
226 liveuser 7978
 
3 liveuser 7979
		#如果建立按鈕失敗
7980
		if($button["status"]==="false"){
226 liveuser 7981
 
3 liveuser 7982
			#設置執行失敗
7983
			$result["status"]="false";
226 liveuser 7984
 
3 liveuser 7985
			#設置執行錯誤訊息
7986
			$result["error"]=$button;
226 liveuser 7987
 
3 liveuser 7988
			#回傳結果
7989
			return $result;
226 liveuser 7990
 
7991
			}#if end
7992
 
3 liveuser 7993
		#建立跳到別的頁面的連結
7994
		#涵式說明:
7995
		#放置超鏈結
7996
		#回傳的結果:
7997
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
7998
		#$result["error"],錯誤訊息
7999
		#$result["content"],語法
8000
		#$result["function"],當前執行的函數名稱
8001
		#必填的參數:
226 liveuser 8002
		#$conf["position"],字串,爲要連結到的位置,若留空,將回自動變成"#",則可以搭配ajax傳值.
3 liveuser 8003
		$conf["link::show_link"]["position"]="webSocketT/hangFewSecs.php";
8004
		#$conf["linkName",字串,爲連結的顯示名稱
8005
		$conf["link::show_link"]["linkName"]="到別的頁面轉轉";
8006
		#可省略的參數:
8007
		#$conf["method"],字串,爲點選連結後,新畫面要如何呈現,可省略預設爲"_self",可用的選項有 _top(覆蓋目前的視窗來顯現新內容) _parent _self _blank(跳新視窗)
226 liveuser 8008
		#$conf["method"]="";
3 liveuser 8009
		#$conf["class"],字串,爲要套用的css超連節樣式,可省略.
8010
		#$conf["class"]="";
8011
		#$conf["id"],字串,超連結的id.
8012
		#$conf["id"]="";
8013
		#$conf["no_outline"],字串,是否要取消連結的框線,"false為不取消,"true"代表要取消,預設為"false".
8014
		#$conf["no_outline"]="";
8015
		$show_link=link::show_link($conf["link::show_link"]);
8016
		unset($conf["link::show_link"]);
226 liveuser 8017
 
3 liveuser 8018
		#串接超連結
8019
		$result["content"]=$result["content"].$show_link["content"];
226 liveuser 8020
 
3 liveuser 8021
		#設置用戶端的html與js語法
8022
		$result["content"]=$result["content"].$button["content"].$script;
226 liveuser 8023
 
3 liveuser 8024
		#設置執行正常
8025
		$result["status"]="true";
226 liveuser 8026
 
3 liveuser 8027
		#回傳結果
8028
		return $result;
226 liveuser 8029
 
3 liveuser 8030
		}#function chatRoomClientDemo end
226 liveuser 8031
 
3 liveuser 8032
	/*
8033
	#函式說明:
8034
	#擴充過的Ratchet聊天室用戶端js範例第二版
8035
	#回傳結果:
8036
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
8037
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 8038
	#$result["function"],當前執行的函式名稱.
3 liveuser 8039
	#$result["content"],html.
8040
	#必填參數:
8041
	#無.
8042
	#可省略參數:
8043
	#無.
8044
	#參考資料:
8045
	#Ratchet官網=>http://socketo.me/
8046
	#用apache的proxy來判斷為哪個服務,導到對應的port裡面=>https://groups.google.com/forum/#!topic/ratchet-php/dj-PgPPO_J0
8047
	#聊天室範例=>http://socketo.me/docs/hello-world
8048
	#備註:
226 liveuser 8049
	#僅適用於https網頁透過wss連線到web socket server.
3 liveuser 8050
	*/
8051
	public static function chatRoomClientDemoV2(){
226 liveuser 8052
 
3 liveuser 8053
		#初始化要回傳的結果
8054
		$result=array();
8055
 
8056
		#初始化儲存html的變數
8057
		$result["content"]="";
8058
 
8059
		#取得當前執行的函數名稱
8060
		$result["function"]=__FUNCTION__;
226 liveuser 8061
 
3 liveuser 8062
		#初始化帳號密碼
8063
		$ac="";
8064
		$pw="";
226 liveuser 8065
 
3 liveuser 8066
		#如果存在 $_SESSION["account"]
8067
		if(isset($_SESSION["account"])){
226 liveuser 8068
 
3 liveuser 8069
			#取得帳戶
8070
			$ac=$_SESSION["account"];
226 liveuser 8071
 
3 liveuser 8072
			}#if end
226 liveuser 8073
 
3 liveuser 8074
		#如果 this->$passwordCol 不為 ""
8075
		if(Chat::$passwordCol!==""){
226 liveuser 8076
 
3 liveuser 8077
			#如果存在 $_SESSION["password"]
8078
			if(isset($_SESSION["password"])){
226 liveuser 8079
 
3 liveuser 8080
				#取得帳戶
8081
				$pw=$_SESSION["password"];
226 liveuser 8082
 
3 liveuser 8083
				}#if end
226 liveuser 8084
 
3 liveuser 8085
			}#if end
226 liveuser 8086
 
3 liveuser 8087
		#取得 server 的 ip
8088
		#涵式說明:
8089
		#取得伺服器的IP,並回傳。
8090
		#回傳的結果:
8091
		#$result,伺服端的IP
8092
		#備註:
8093
		#伺服端必須被 localhost 以外的網址連結才會出現正確的IP
8094
		$getServerIP=csInformation::getServerIP();
226 liveuser 8095
 
3 liveuser 8096
		#設置用戶端連線到webSocket的範例
8097
		$script="<script>
226 liveuser 8098
 
3 liveuser 8099
			//取得帳號密碼
8100
			ac='".$ac."';
8101
			pw='".$pw."';
226 liveuser 8102
 
3 liveuser 8103
			//設置目前尚為連線到 webSocket Server
8104
			connected='false';
226 liveuser 8105
 
3 liveuser 8106
			//設置儲存應該要斷線的webSocket,避免太多連線在伺服器.
8107
			wbClosed='';
226 liveuser 8108
 
3 liveuser 8109
			//設置儲存webSocket連線的變數
8110
			wb='';
226 liveuser 8111
 
3 liveuser 8112
			//設置儲存msgId的變數
8113
			msgId='';
226 liveuser 8114
 
3 liveuser 8115
			//連線到 web socket
8116
			connWebSock();
226 liveuser 8117
 
3 liveuser 8118
			//連線到 web socket
8119
			function connWebSock()
8120
			{
8121
				//建立 web socket 連線到 wss://localhost/wss/chatDemo
8122
				var conn = new WebSocket('wss://".$getServerIP."/wss/chatDemo');
226 liveuser 8123
 
3 liveuser 8124
				//當連線成功後
8125
				conn.onopen = function(e){
226 liveuser 8126
 
3 liveuser 8127
					//印出連線成功訊息到console
8128
					console.log(\"Connection established!\");
226 liveuser 8129
 
3 liveuser 8130
					//設置已經連上 webSocket server
8131
					connected='true';
226 liveuser 8132
 
3 liveuser 8133
					//另存 webSocket 物件
8134
					wb=conn;
226 liveuser 8135
 
3 liveuser 8136
					//如果存在前一個連線物件
8137
					if(wbClosed!==''){
226 liveuser 8138
 
3 liveuser 8139
						//提示關閉前個連線
8140
						console.log(\"close last connection!\");
226 liveuser 8141
 
3 liveuser 8142
						//關閉之前的連線
8143
						wbClosed.close();
226 liveuser 8144
 
3 liveuser 8145
						//清空
8146
						wbClosed='';
226 liveuser 8147
 
3 liveuser 8148
						}
226 liveuser 8149
 
3 liveuser 8150
					}
8151
 
8152
				//當有收到訊息時
8153
				conn.onmessage = function(e){
226 liveuser 8154
 
3 liveuser 8155
					//將訊息顯現在console
8156
					console.log(e.data);
226 liveuser 8157
 
3 liveuser 8158
					//將訊息寫到文字方框裡面
8159
					$('#history').val(e.data+'\\r\\n'+$('#history').val());
226 liveuser 8160
 
3 liveuser 8161
					//解析json字串
8162
					data=JSON.parse(e.data);
226 liveuser 8163
 
3 liveuser 8164
					//如果要要求login的訊息
8165
					if(data.type==='login'){
226 liveuser 8166
 
3 liveuser 8167
						//如果有查到帳號
8168
						if(ac!==''){
226 liveuser 8169
 
3 liveuser 8170
							//如果要求輸入帳號
8171
							if(data.data==='Please input your account! ex:account:ws1'){
226 liveuser 8172
 
3 liveuser 8173
								//傳送帳號
8174
								conn.send('account:'+ac);
226 liveuser 8175
 
3 liveuser 8176
								}
226 liveuser 8177
 
3 liveuser 8178
							//如果有查到密碼
8179
							if(pw!==''){
226 liveuser 8180
 
8181
								//如果要求輸入密碼
3 liveuser 8182
								if(data.data==='Please input your password! ex:password:ws1'){
226 liveuser 8183
 
3 liveuser 8184
									//傳送密碼
8185
									conn.send('password:'+pw);
226 liveuser 8186
 
3 liveuser 8187
									}
226 liveuser 8188
 
3 liveuser 8189
								}
226 liveuser 8190
 
3 liveuser 8191
							//如果存在既有的msgId,且剛登入成功
8192
							if(msgId!=='' && data.data==='Login successfully!'){
226 liveuser 8193
 
3 liveuser 8194
								//設置既有的msgId
8195
								conn.send('msgId:'+msgId);
226 liveuser 8196
 
3 liveuser 8197
								}
226 liveuser 8198
 
3 liveuser 8199
							//反之如果登入成功
8200
							else if(data.data==='Login successfully!'){
226 liveuser 8201
 
3 liveuser 8202
								//查詢自己的msgId
8203
								conn.send('msgId?');
226 liveuser 8204
 
3 liveuser 8205
								}
226 liveuser 8206
 
3 liveuser 8207
							}
226 liveuser 8208
 
3 liveuser 8209
						}
226 liveuser 8210
 
3 liveuser 8211
					//如果收到的是 'msgId?'
8212
					else if(data.type==='msgId?'){
226 liveuser 8213
 
3 liveuser 8214
						//設置自己的msgId
8215
						msgId=data.data;
226 liveuser 8216
 
3 liveuser 8217
						}
226 liveuser 8218
 
3 liveuser 8219
					//如果收到的是 'msg' 類型
8220
					else if(data.type==='msg'){
226 liveuser 8221
 
3 liveuser 8222
						//回傳有收到訊息的確認
8223
						conn.send('mIndex:'+data.index);
226 liveuser 8224
 
3 liveuser 8225
						}
226 liveuser 8226
 
8227
					//如果收到的是 'status' 類型
3 liveuser 8228
					else if(data.type==='status'){
226 liveuser 8229
 
3 liveuser 8230
						//如果內容為設置msgId失敗
8231
						if(data.data==='set msgId failed'){
226 liveuser 8232
 
3 liveuser 8233
							//查詢自己的msgId
8234
							conn.send('msgId?');
226 liveuser 8235
 
3 liveuser 8236
							}
226 liveuser 8237
 
3 liveuser 8238
						}
226 liveuser 8239
 
3 liveuser 8240
					}
226 liveuser 8241
 
3 liveuser 8242
				//當連線斷開後
8243
				conn.onclose = function(e){
226 liveuser 8244
 
3 liveuser 8245
					//設置未連上 webSocket server
8246
					connected='false';
226 liveuser 8247
 
3 liveuser 8248
					//如果有之前的連線物件
8249
					if(wb!==''){
226 liveuser 8250
 
3 liveuser 8251
						//儲存應該要斷線的webSocket,避免太多連線在伺服器.
8252
						wbClosed=wb;
226 liveuser 8253
 
3 liveuser 8254
						}
226 liveuser 8255
 
3 liveuser 8256
					//清空 webSocket 物件
8257
					wb='';
226 liveuser 8258
 
3 liveuser 8259
					//指定1秒刷新一次
226 liveuser 8260
					setTimeout('connWebSock()',1000);
8261
 
3 liveuser 8262
					}
226 liveuser 8263
 
8264
				}
8265
 
3 liveuser 8266
			//當按下送出按鈕
8267
			$('#send').on('click',function(){
226 liveuser 8268
 
3 liveuser 8269
				//如果已經連到 webSocket server 了
8270
				if(connected==='true'){
226 liveuser 8271
 
3 liveuser 8272
					//傳送訊息
8273
					wb.send($('#input').val());
226 liveuser 8274
 
3 liveuser 8275
					//清空訊息輸入欄
8276
					$('#input').val('');
226 liveuser 8277
 
3 liveuser 8278
					}
226 liveuser 8279
 
3 liveuser 8280
				});
226 liveuser 8281
 
3 liveuser 8282
			//重新整理頁面
8283
			function myrefresh(){
226 liveuser 8284
 
3 liveuser 8285
				//重新整理頁面
8286
				window.location.reload();
226 liveuser 8287
 
3 liveuser 8288
				}
226 liveuser 8289
 
3 liveuser 8290
			</script>";
226 liveuser 8291
 
3 liveuser 8292
		#設置存放歷史訊息的方框
8293
		#涵式說明:
8294
		#可以輸入文字的區塊
8295
		#回傳結果:
8296
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
8297
		#$result["function"],當前執行的函數.
8298
		#$result["error"],錯誤訊息陣列.
226 liveuser 8299
		#$result["content"],按鈕語法.
3 liveuser 8300
		#必填的參數:
8301
		$conf["form::inputTextArea"]["name"]="history";#爲文字輸入框的名稱,供接收端辨識用。
8302
		$conf["form::inputTextArea"]["readOnly"]="true";#爲是否要爲唯讀,如果爲"true",則爲唯讀。反之則爲"false"。
8303
		#可省略的參數:
8304
		#$conf["id"],字串,文字區塊的id,供javaScript呼叫用.
8305
		$conf["form::inputTextArea"]["id"]="history";
8306
		#$conf["width"]="";#為輸入框的寬度,預設不指定.
8307
		#$conf["cols"]="";#爲文字輸入框的欄位數(寬),預設爲按照瀏覽器設定值。
8308
		#$conf["rows"]="";#爲文字輸入框的列數(高),預設爲按照瀏覽器設定值。
8309
		#$conf["maxInputLength"]="";#爲文字輸入的長度限制,預設無限制。
8310
		#$conf["defaultText"]="";#爲文字輸入框裏面的預設文字內容,預設是空的。
8311
		#$conf["class"]=;#爲要套用的css樣式。如果沒有指定 ,則採用預設的css樣式,"__inputTextAreaCssStyle",其屬性爲 "width:100%","height:120px","font-size:30px"
8312
		#$conf["jsActivitor"]="";#爲觸發js的條件,可以是"onChange"(已改變內容時)...,須搭配$conf["jsSubmitActionTarget"]參數。
8313
		#$conf["jsAction"]="";#爲該js是要做什麼,可以是"document.testForm.submit()"(傳送名爲testForm的表單內容)...,須搭配$conf["jsActivitor"]參數。
8314
		#$conf["formStart"]="true";#爲是否要以<form>開頭,"true"表示"是",也可以看成表單的開始,預設為"false".
8315
		#$conf["formAction"]="";#表單遞交的目的地,若$conf["formStart"]為"true",則該參數不能省略.
8316
		#$conf["formName"]="";#爲該表單的名稱
8317
		#$conf["formMethod"]="";#爲傳輸的方法,若沒設定則預設爲post,其他可用的參數爲get。
8318
		#$conf["formTarget"]="";#為顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。
8319
		#$conf["formEnd"]="true";#爲是否要以<form>結尾,"true"表示"是",也可以看成表單的結束,預設為"false".
8320
		#$conf["comment"],字串,輸入方框上面要放哪些註解文字,亦即用label來呈現,同時指定"for"屬性的數值為當前"input"標籤的id,意即參數"name"的內容.
8321
		#$conf["comment"]="";
8322
		#$conf["required"],字串,該欄位是否必填,"true"為必填,"false"為可留空,預設為"false".
8323
		#$conf["required"]="true";
8324
		#$conf["placeholder"],字串,當沒有內容時要顯示的內容.
8325
		#$conf["placeholder"]="";
8326
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是",也可以看作新的一列開始,預設為"false".
8327
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是",也可以看成列裏面的元素開始,預設為"false".
8328
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是",也可以看成列裏面的元素結束,預設為"false".
8329
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是",也可以看作該列結束,預設為"false".
8330
		#參考資料來源:
8331
		#input=>http://www.w3schools.com/tags/tag_input.asp
8332
		$inputTextArea=form::inputTextArea($conf["form::inputTextArea"]);
8333
		unset($conf["form::inputTextArea"]);
226 liveuser 8334
 
3 liveuser 8335
		#如果建立文字方框失敗
8336
		if($inputTextArea["status"]==="false"){
226 liveuser 8337
 
3 liveuser 8338
			#設置執行失敗
8339
			$result["status"]="false";
226 liveuser 8340
 
3 liveuser 8341
			#設置執行錯誤訊息
8342
			$result["error"]=$inputTextArea;
226 liveuser 8343
 
3 liveuser 8344
			#回傳結果
8345
			return $result;
226 liveuser 8346
 
8347
			}#if end
8348
 
3 liveuser 8349
		#串連文字訊息方框
8350
		$result["content"]=$result["content"].$inputTextArea["content"];
226 liveuser 8351
 
3 liveuser 8352
		#設置填寫要傳送的訊息輸入方框
8353
		#涵式說明:
8354
		#可以輸入文字的表單
8355
		#回傳的結果:
8356
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
8357
		#$result["function"],當前執行的函數.
8358
		#$result["error"],錯誤訊息陣列.
226 liveuser 8359
		#$result["content"],按鈕語法.
3 liveuser 8360
		#必填的參數
8361
		$conf["form::inputText"]["name"]="data";#爲該文字輸入框的名稱,用於讓接收頁面讀取的名稱。
8362
		$conf["form::inputText"]["readOnly"]="false";#爲該文字框是否可以填寫資料,若要只能觀看不能填寫,那麼就必須將其值設爲"true",反之要設爲"false"
8363
		#可省略的參數:
8364
		#$conf["width"]="";#爲文字框的外觀長度,預設為"100%".
8365
		#$conf["maxInputLength"]="";#爲可輸入的最大位元長度,預設不限制。
8366
		#$conf["autoFocus"]="true";#是否為將填寫的指標移到該表單,"true"代表要,預設為"false".
226 liveuser 8367
		#$conf["value"]="";#爲該文字框預設要顯示的文字,預設爲""。
3 liveuser 8368
		#$conf["class"]="";#爲要套用的css樣式,若省略,則會套用預設的 "__inputTextCssStyle" 樣式,其屬性爲 "width:100%","font-size:30px"
8369
		#$conf["jsActivitor"]="";#爲觸發js的條件,可以是"onChange"(已改變內容時)、"onClick"(按下按鈕時)、"onkeyup"(當鍵盤按下放開後)、"onmouseover"(當滑鼠移過去的時候)...,須搭配$conf["jsSubmitActionTarget"]參數。
226 liveuser 8370
		#$conf["jsAction"]="";#爲該js是要做什麼,可以是"document.testForm.submit()"(傳送名爲testForm的表單內容)...,須搭配$conf["jsActivitor"]參數。
3 liveuser 8371
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是"。也可以看作新的一列開始,預設為"false".
8372
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是"。也可以看成列裏面的元素開始,預設為"false".
8373
		#$conf["formStart"]="true";#爲是否要以<form>開頭,"true"表示"是",也可以看成表單的開始,預設為"false".
8374
		#$conf["formAction"]="";#表單遞交的目的地,若$conf["formStart"]為"true",則該參數不能省略.
8375
		#$conf["formName"]="";#爲該表單的名稱
8376
		#$conf["formMethod"]="";#爲傳輸的方法,若沒設定則預設爲post,其他可用的參數爲get。
8377
		#$conf["formTarget"]="";#為顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。
8378
		#$conf["tableStart"]="true";#爲該表單是否要以<table>開始。"true"爲是,預設為"false".
8379
		#$conf["tableClass"]="";#表格要套用的css樣式,若爲"__withoutBorder"的話則套用無框線的預設樣式;若爲"__withBorder"的話,則爲有框線的預設樣式,預設為"__withoutBorder".
8380
		#$conf["formEnd"]="true";#爲是否要以<form>結尾,"true"表示"是",也可以看成表單的結束,預設為"false".
8381
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是"。也可以看成列裏面的元素結束,預設為"false".
8382
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是"。也可以看作該列結束,預設為"false".
8383
		#$conf["tableEnd"]="true";#爲該表單是否要以</table>結尾,"true"爲是,預設為"false".
8384
		#$conf["autocomplete"],字串,是否依據使用者過往輸入的記錄來提示可能要的輸入內容,"on"為啟用,"off"為停用,預設為"on".
8385
		#$conf["autocomplete"]="off";
8386
		#$conf["required"],字串,該欄位是否必填,"true"為必填,"false"為可留空,預設為"false".
8387
		#$conf["required"]="true";
8388
		#$conf["comment"],字串,輸入方框上面要放哪些註解文字,亦即用label來呈現,同時指定"for"屬性的數值為當前"input"標籤的id,意即參數"name"的內容.
8389
		#$conf["comment"]="";
8390
		#$conf["placeholder"],字串,當沒有內容時要顯示的內容.
8391
		#$conf["placeholder"]="";
8392
		#$conf["br"],字串,"true"代表最後要換行,預設為"false".
8393
		#$conf["br"]="true";
8394
		#$conf["p"],字串,"true"代表最後要空一行,預設為"false".
8395
		#$conf["p"]="true";
8396
		#$conf["id"],字串,該元素的id,預設不使用.
8397
		$conf["form::inputText"]["id"]="input";
8398
		#參考資料來源:
8399
		#input=>http://www.w3schools.com/tags/tag_input.asp
8400
		$inputText=form::inputText($conf["form::inputText"]);
8401
		unset($conf["form::inputText"]);
226 liveuser 8402
 
3 liveuser 8403
		#如果輸入文字框失敗
8404
		if($inputText["status"]==="false"){
226 liveuser 8405
 
3 liveuser 8406
			#設置執行失敗
8407
			$result["status"]="false";
226 liveuser 8408
 
3 liveuser 8409
			#設置執行錯誤訊息
8410
			$result["error"]=$inputText;
226 liveuser 8411
 
3 liveuser 8412
			#回傳結果
8413
			return $result;
226 liveuser 8414
 
8415
			}#if end
8416
 
3 liveuser 8417
		#文字輸入框
8418
		$result["content"]=$result["content"].$inputText["content"];
226 liveuser 8419
 
3 liveuser 8420
		#設置觸發的按鈕
8421
		#函式說明:
8422
		#放置按鈕
8423
		#回傳結果:
8424
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
8425
		#$result["function"],當前執行的函數.
8426
		#$result["error"],錯誤訊息陣列.
226 liveuser 8427
		#$result["content"],按鈕語法.
3 liveuser 8428
		#必要的參數:
8429
		$conf["form::button"]["buttonDisplayValue"]="Send";#爲按鈕上顯示的文字。
8430
		#可省略的參數:
8431
		#$conf["buttonStyleName"]="";#可省略,爲按鈕所要使用的css樣式類別名稱,預設的css樣式爲 __simpleButtonLinkDefaultButtonCssStyle 。
8432
			#其屬性爲   "width","height","font-size","text-align"
8433
			#其屬性值爲 "100%" ,  "50"  ,    "30"   ,   "center"
8434
		#$conf["form::button"]["buttonActionScriptFunction"]="conn.send('Hello!');";#可省略,爲按下按鈕時所要執行的javaScript函式或程式,預設不設定。
8435
			#"document.forms.formName.submit()"爲傳送名爲testForm的表單內容
8436
			#"window.print()"爲使用瀏覽器內建工具列印當前網頁
8437
			#若搭配 javaScript 類別的 confirmWindow 函數的回傳結果,則會有確認視窗的效果.
8438
		#$conf["buttonBorder"]="";#可省略,爲IE9內會自動產生外框,此爲外框的厚度,屬性值爲正整數,預設爲0。
8439
		#$conf["disabled"]="true";#可省略,為按鈕的功能是否要取消,若為"true"則代表要取消,若為"false"則代表功能正常,預設為"false".
8440
		#$conf["tableStart"]="true";#爲是否要表格開始。"false"代表否,"true"代表是。預設爲"false"。
8441
		#$conf["tableClass"]="";#表格要套用的css樣式,若省略的話,則預設爲 __defaultTbaleCsssStyle 其屬性爲 table-layout:fixed word-break:break-all width:100% ,須搭配 $conf["tablStart"] 與 $conf["tableEnd"] 使用。
8442
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是"。也可以看作新的一列開始,預設為"false".
8443
		#$conf["trClass"]="__withoutBorder";#<tr>要套用的css樣式,預設為"__withoutBorder",亦即沒有框線的樣式;"__withBorder"則爲有框線的樣式
8444
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是"。也可以看成列裏面的元素開始,預設為"false".
8445
		#$conf["tdClass"]="__withoutBorder";#<td>要套用的css樣式,"__withoutBorder"爲沒有框線的樣式;__withBorder爲有框線的樣式
8446
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是"。也可以看成列裏面的元素結束,預設為"false".
8447
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是"。也可以看作該列結束,預設為"false".
8448
		#$conf["tableEnd"]="true";#爲是否要表格結束。"false"代表否,"true"代表是,預設爲"false"。
8449
		#$conf["formStart"]="true";#爲是否要表單開始,如果爲"true"則代表要表單開始,預設為"false".
8450
		#$conf["action"]="";#爲表單要傳送到哪個頁面,須搭配$conf["formStart"]與$conf["formEnd"]參數使用
8451
		#$conf["target"]="";#為目標表單顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。須搭配$conf["formStart"]與$conf["formEnd"]參數使用
8452
		#$conf["formEnd"]="true";#爲是否要表單結束,如果爲"true"則代表要表單結束,預設為"false".
8453
		#$conf["formId"],字串,表單的id.
8454
		#$conf["formId"]="";
8455
		#$conf["buttonId"],字串,按鈕的id.
8456
		$conf["form::button"]["buttonId"]="send";
8457
		#參考資料來源:
8458
		#http://stackoverflow.com/questions/3014649/how-to-disable-html-button-using-javascript
8459
		$button=form::button($conf["form::button"]);
8460
		unset($conf["form::button"]);
226 liveuser 8461
 
3 liveuser 8462
		#如果建立按鈕失敗
8463
		if($button["status"]==="false"){
226 liveuser 8464
 
3 liveuser 8465
			#設置執行失敗
8466
			$result["status"]="false";
226 liveuser 8467
 
3 liveuser 8468
			#設置執行錯誤訊息
8469
			$result["error"]=$button;
226 liveuser 8470
 
3 liveuser 8471
			#回傳結果
8472
			return $result;
226 liveuser 8473
 
8474
			}#if end
8475
 
3 liveuser 8476
		#建立跳到別的頁面的連結
8477
		#涵式說明:
8478
		#放置超鏈結
8479
		#回傳的結果:
8480
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
8481
		#$result["error"],錯誤訊息
8482
		#$result["content"],語法
8483
		#$result["function"],當前執行的函數名稱
8484
		#必填的參數:
226 liveuser 8485
		#$conf["position"],字串,爲要連結到的位置,若留空,將回自動變成"#",則可以搭配ajax傳值.
3 liveuser 8486
		$conf["link::show_link"]["position"]="webSocketT/hangFewSecs.php";
8487
		#$conf["linkName",字串,爲連結的顯示名稱
8488
		$conf["link::show_link"]["linkName"]="到別的頁面轉轉";
8489
		#可省略的參數:
8490
		#$conf["method"],字串,爲點選連結後,新畫面要如何呈現,可省略預設爲"_self",可用的選項有 _top(覆蓋目前的視窗來顯現新內容) _parent _self _blank(跳新視窗)
226 liveuser 8491
		#$conf["method"]="";
3 liveuser 8492
		#$conf["class"],字串,爲要套用的css超連節樣式,可省略.
8493
		#$conf["class"]="";
8494
		#$conf["id"],字串,超連結的id.
8495
		#$conf["id"]="";
8496
		#$conf["no_outline"],字串,是否要取消連結的框線,"false為不取消,"true"代表要取消,預設為"false".
8497
		#$conf["no_outline"]="";
8498
		$show_link=link::show_link($conf["link::show_link"]);
8499
		unset($conf["link::show_link"]);
226 liveuser 8500
 
3 liveuser 8501
		#串接超連結
8502
		$result["content"]=$result["content"].$show_link["content"];
226 liveuser 8503
 
3 liveuser 8504
		#設置用戶端的html與js語法
8505
		$result["content"]=$result["content"].$button["content"].$script;
226 liveuser 8506
 
3 liveuser 8507
		#設置執行正常
8508
		$result["status"]="true";
226 liveuser 8509
 
3 liveuser 8510
		#回傳結果
8511
		return $result;
226 liveuser 8512
 
8513
		}#function chatRoomClientDemoV2 end
8514
 
3 liveuser 8515
	/*
8516
	#函式說明:
8517
	#擴充過的Ratchet聊天室用戶端js範例第三版,擁有在伺服器上執行指令的功能.
8518
	#回傳結果:
8519
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
8520
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 8521
	#$result["function"],當前執行的函式名稱.
3 liveuser 8522
	#$result["content"],html.
8523
	#必填參數:
8524
	#無.
8525
	#可省略參數:
8526
	#無.
8527
	#參考資料:
8528
	#Ratchet官網=>http://socketo.me/
8529
	#用apache的proxy來判斷為哪個服務,導到對應的port裡面=>https://groups.google.com/forum/#!topic/ratchet-php/dj-PgPPO_J0
8530
	#聊天室範例=>http://socketo.me/docs/hello-world
8531
	#備註:
226 liveuser 8532
	#僅適用於https網頁透過wss連線到web socket server.
3 liveuser 8533
	*/
8534
	public static function chatRoomClientDemoV3(){
226 liveuser 8535
 
3 liveuser 8536
		#初始化要回傳的結果
8537
		$result=array();
8538
 
8539
		#初始化儲存html的變數
8540
		$result["content"]="";
8541
 
8542
		#取得當前執行的函數名稱
8543
		$result["function"]=__FUNCTION__;
226 liveuser 8544
 
3 liveuser 8545
		#初始化帳號密碼
8546
		$ac="";
8547
		$pw="";
226 liveuser 8548
 
3 liveuser 8549
		#如果存在 $_SESSION["account"]
8550
		if(isset($_SESSION["account"])){
226 liveuser 8551
 
3 liveuser 8552
			#取得帳戶
8553
			$ac=$_SESSION["account"];
226 liveuser 8554
 
3 liveuser 8555
			}#if end
226 liveuser 8556
 
3 liveuser 8557
		#如果 this->$passwordCol 不為 ""
8558
		if(Chat::$passwordCol!==""){
226 liveuser 8559
 
3 liveuser 8560
			#如果存在 $_SESSION["password"]
8561
			if(isset($_SESSION["password"])){
226 liveuser 8562
 
3 liveuser 8563
				#取得帳戶
8564
				$pw=$_SESSION["password"];
226 liveuser 8565
 
3 liveuser 8566
				}#if end
226 liveuser 8567
 
3 liveuser 8568
			}#if end
226 liveuser 8569
 
3 liveuser 8570
		#取得 server 的 ip
8571
		#涵式說明:
8572
		#取得伺服器的IP,並回傳。
8573
		#回傳的結果:
8574
		#$result,伺服端的IP
8575
		#備註:
8576
		#伺服端必須被 localhost 以外的網址連結才會出現正確的IP
8577
		$getServerIP=csInformation::getServerIP();
226 liveuser 8578
 
3 liveuser 8579
		#設置用戶端連線到webSocket的範例
8580
		$script="<script>
226 liveuser 8581
 
3 liveuser 8582
			//ready 後執行
8583
			$(document).ready(function()
8584
			{
226 liveuser 8585
 
3 liveuser 8586
				//取得帳號密碼
8587
				ac='".$ac."';
8588
				pw='".$pw."';
226 liveuser 8589
 
3 liveuser 8590
				//設置目前尚為連線到 webSocket Server
8591
				connected='false';
226 liveuser 8592
 
3 liveuser 8593
				//設置儲存應該要斷線的webSocket,避免太多連線在伺服器.
8594
				wbClosed='';
226 liveuser 8595
 
3 liveuser 8596
				//設置儲存webSocket連線的變數
8597
				wb='';
226 liveuser 8598
 
3 liveuser 8599
				//設置儲存msgId的變數
8600
				msgId='';
226 liveuser 8601
 
3 liveuser 8602
				//連線到 web socket
8603
				connWebSock();
226 liveuser 8604
 
3 liveuser 8605
			});
226 liveuser 8606
 
3 liveuser 8607
			//連線到 web socket
8608
			function connWebSock()
8609
			{
8610
				//建立 web socket 連線到 wss://localhost/wss/chatDemo
8611
				var conn = new WebSocket('wss://".$getServerIP."/wss/chatDemo');
226 liveuser 8612
 
3 liveuser 8613
				//當連線成功後
8614
				conn.onopen = function(e){
226 liveuser 8615
 
3 liveuser 8616
					//印出連線成功訊息到console
8617
					console.log(\"Connection established!\");
226 liveuser 8618
 
3 liveuser 8619
					//設置已經連上 webSocket server
8620
					connected='true';
226 liveuser 8621
 
3 liveuser 8622
					//另存 webSocket 物件
8623
					wb=conn;
226 liveuser 8624
 
3 liveuser 8625
					//如果存在前一個連線物件
8626
					if(wbClosed!==''){
226 liveuser 8627
 
3 liveuser 8628
						//提示關閉前個連線
8629
						console.log(\"close last connection!\");
226 liveuser 8630
 
3 liveuser 8631
						//關閉之前的連線
8632
						wbClosed.close();
226 liveuser 8633
 
3 liveuser 8634
						//清空
8635
						wbClosed='';
226 liveuser 8636
 
3 liveuser 8637
						}
226 liveuser 8638
 
3 liveuser 8639
					}
8640
 
8641
				//當有收到訊息時
8642
				conn.onmessage = function(e){
226 liveuser 8643
 
3 liveuser 8644
					//將訊息顯現在console
8645
					console.log(e.data);
226 liveuser 8646
 
3 liveuser 8647
					//將訊息寫到文字方框裡面
8648
					$('#history').val(e.data+'\\r\\n'+$('#history').val());
226 liveuser 8649
 
3 liveuser 8650
					//解析json字串
8651
					data=JSON.parse(e.data);
226 liveuser 8652
 
3 liveuser 8653
					//如果要要求login的訊息
8654
					if(data.type==='login'){
226 liveuser 8655
 
3 liveuser 8656
						//如果有查到帳號
8657
						if(ac!==''){
226 liveuser 8658
 
3 liveuser 8659
							//如果要求輸入帳號
8660
							if(data.data==='Please input your account! ex:account:ws1'){
226 liveuser 8661
 
3 liveuser 8662
								//傳送帳號
8663
								conn.send('account:'+ac);
226 liveuser 8664
 
3 liveuser 8665
								}
226 liveuser 8666
 
3 liveuser 8667
							//如果有查到密碼
8668
							if(pw!==''){
226 liveuser 8669
 
8670
								//如果要求輸入密碼
3 liveuser 8671
								if(data.data==='Please input your password! ex:password:ws1'){
226 liveuser 8672
 
3 liveuser 8673
									//傳送密碼
8674
									conn.send('password:'+pw);
226 liveuser 8675
 
3 liveuser 8676
									}
226 liveuser 8677
 
3 liveuser 8678
								}
226 liveuser 8679
 
3 liveuser 8680
							//如果存在既有的msgId,且剛登入成功
8681
							if(msgId!=='' && data.data==='Login successfully!'){
226 liveuser 8682
 
3 liveuser 8683
								//設置既有的msgId
8684
								conn.send('msgId:'+msgId);
226 liveuser 8685
 
3 liveuser 8686
								}
226 liveuser 8687
 
3 liveuser 8688
							//反之如果登入成功
8689
							else if(data.data==='Login successfully!'){
226 liveuser 8690
 
3 liveuser 8691
								//查詢自己的msgId
8692
								conn.send('msgId?');
226 liveuser 8693
 
3 liveuser 8694
								}
226 liveuser 8695
 
3 liveuser 8696
							}
226 liveuser 8697
 
3 liveuser 8698
						}
226 liveuser 8699
 
3 liveuser 8700
					//如果收到的是 'msgId?'
8701
					else if(data.type==='msgId?'){
226 liveuser 8702
 
3 liveuser 8703
						//設置自己的msgId
8704
						msgId=data.data;
226 liveuser 8705
 
3 liveuser 8706
						}
226 liveuser 8707
 
3 liveuser 8708
					//如果收到的是 'msg' 類型
8709
					else if(data.type==='msg'){
226 liveuser 8710
 
3 liveuser 8711
						//回傳有收到訊息的確認
8712
						conn.send('mIndex:'+data.index);
226 liveuser 8713
 
3 liveuser 8714
						}
226 liveuser 8715
 
8716
					//如果收到的是 'status' 類型
3 liveuser 8717
					else if(data.type==='status'){
226 liveuser 8718
 
3 liveuser 8719
						//如果內容為設置msgId失敗
8720
						if(data.data==='set msgId failed'){
226 liveuser 8721
 
3 liveuser 8722
							//查詢自己的msgId
8723
							conn.send('msgId?');
226 liveuser 8724
 
3 liveuser 8725
							}
226 liveuser 8726
 
3 liveuser 8727
						}
226 liveuser 8728
 
8729
					//如果收到的是 'cmd' 類型
3 liveuser 8730
					else if(data.type==='cmd'){
226 liveuser 8731
 
3 liveuser 8732
						//將訊息顯現在console
8733
						//console.log(e.data);
226 liveuser 8734
 
3 liveuser 8735
						}
226 liveuser 8736
 
3 liveuser 8737
					}
226 liveuser 8738
 
3 liveuser 8739
				//當連線斷開後
8740
				conn.onclose = function(e){
226 liveuser 8741
 
3 liveuser 8742
					//設置未連上 webSocket server
8743
					connected='false';
226 liveuser 8744
 
3 liveuser 8745
					//如果有之前的連線物件
8746
					if(wb!==''){
226 liveuser 8747
 
3 liveuser 8748
						//儲存應該要斷線的webSocket,避免太多連線在伺服器.
8749
						wbClosed=wb;
226 liveuser 8750
 
3 liveuser 8751
						}
226 liveuser 8752
 
3 liveuser 8753
					//清空 webSocket 物件
8754
					wb='';
226 liveuser 8755
 
3 liveuser 8756
					//指定1秒刷新一次
226 liveuser 8757
					setTimeout('connWebSock()',1000);
8758
 
3 liveuser 8759
					}
226 liveuser 8760
 
8761
				}
8762
 
3 liveuser 8763
			//當按下送出按鈕
8764
			$('#send').on('click',function(){
226 liveuser 8765
 
3 liveuser 8766
				//如果已經連到 webSocket server 了
8767
				if(connected==='true'){
226 liveuser 8768
 
3 liveuser 8769
					//傳送訊息
8770
					wb.send($('#input').val());
226 liveuser 8771
 
3 liveuser 8772
					//清空訊息輸入欄
8773
					$('#input').val('');
226 liveuser 8774
 
3 liveuser 8775
					}
226 liveuser 8776
 
3 liveuser 8777
				});
226 liveuser 8778
 
3 liveuser 8779
			//重新整理頁面
8780
			function myrefresh(){
226 liveuser 8781
 
3 liveuser 8782
				//重新整理頁面
8783
				window.location.reload();
226 liveuser 8784
 
3 liveuser 8785
				}
226 liveuser 8786
 
3 liveuser 8787
			</script>";
226 liveuser 8788
 
3 liveuser 8789
		#設置存放歷史訊息的方框
8790
		#涵式說明:
8791
		#可以輸入文字的區塊
8792
		#回傳結果:
8793
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
8794
		#$result["function"],當前執行的函數.
8795
		#$result["error"],錯誤訊息陣列.
226 liveuser 8796
		#$result["content"],按鈕語法.
3 liveuser 8797
		#必填的參數:
8798
		$conf["form::inputTextArea"]["name"]="history";#爲文字輸入框的名稱,供接收端辨識用。
8799
		$conf["form::inputTextArea"]["readOnly"]="true";#爲是否要爲唯讀,如果爲"true",則爲唯讀。反之則爲"false"。
8800
		#可省略的參數:
8801
		#$conf["id"],字串,文字區塊的id,供javaScript呼叫用.
8802
		$conf["form::inputTextArea"]["id"]="history";
8803
		#$conf["width"]="";#為輸入框的寬度,預設不指定.
8804
		#$conf["cols"]="";#爲文字輸入框的欄位數(寬),預設爲按照瀏覽器設定值。
8805
		#$conf["rows"]="";#爲文字輸入框的列數(高),預設爲按照瀏覽器設定值。
8806
		#$conf["maxInputLength"]="";#爲文字輸入的長度限制,預設無限制。
8807
		#$conf["defaultText"]="";#爲文字輸入框裏面的預設文字內容,預設是空的。
8808
		#$conf["class"]=;#爲要套用的css樣式。如果沒有指定 ,則採用預設的css樣式,"__inputTextAreaCssStyle",其屬性爲 "width:100%","height:120px","font-size:30px"
8809
		#$conf["jsActivitor"]="";#爲觸發js的條件,可以是"onChange"(已改變內容時)...,須搭配$conf["jsSubmitActionTarget"]參數。
8810
		#$conf["jsAction"]="";#爲該js是要做什麼,可以是"document.testForm.submit()"(傳送名爲testForm的表單內容)...,須搭配$conf["jsActivitor"]參數。
8811
		#$conf["formStart"]="true";#爲是否要以<form>開頭,"true"表示"是",也可以看成表單的開始,預設為"false".
8812
		#$conf["formAction"]="";#表單遞交的目的地,若$conf["formStart"]為"true",則該參數不能省略.
8813
		#$conf["formName"]="";#爲該表單的名稱
8814
		#$conf["formMethod"]="";#爲傳輸的方法,若沒設定則預設爲post,其他可用的參數爲get。
8815
		#$conf["formTarget"]="";#為顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。
8816
		#$conf["formEnd"]="true";#爲是否要以<form>結尾,"true"表示"是",也可以看成表單的結束,預設為"false".
8817
		#$conf["comment"],字串,輸入方框上面要放哪些註解文字,亦即用label來呈現,同時指定"for"屬性的數值為當前"input"標籤的id,意即參數"name"的內容.
8818
		#$conf["comment"]="";
8819
		#$conf["required"],字串,該欄位是否必填,"true"為必填,"false"為可留空,預設為"false".
8820
		#$conf["required"]="true";
8821
		#$conf["placeholder"],字串,當沒有內容時要顯示的內容.
8822
		#$conf["placeholder"]="";
8823
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是",也可以看作新的一列開始,預設為"false".
8824
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是",也可以看成列裏面的元素開始,預設為"false".
8825
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是",也可以看成列裏面的元素結束,預設為"false".
8826
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是",也可以看作該列結束,預設為"false".
8827
		#參考資料來源:
8828
		#input=>http://www.w3schools.com/tags/tag_input.asp
8829
		$inputTextArea=form::inputTextArea($conf["form::inputTextArea"]);
8830
		unset($conf["form::inputTextArea"]);
226 liveuser 8831
 
3 liveuser 8832
		#如果建立文字方框失敗
8833
		if($inputTextArea["status"]==="false"){
226 liveuser 8834
 
3 liveuser 8835
			#設置執行失敗
8836
			$result["status"]="false";
226 liveuser 8837
 
3 liveuser 8838
			#設置執行錯誤訊息
8839
			$result["error"]=$inputTextArea;
226 liveuser 8840
 
3 liveuser 8841
			#回傳結果
8842
			return $result;
226 liveuser 8843
 
8844
			}#if end
8845
 
3 liveuser 8846
		#串連文字訊息方框
8847
		$result["content"]=$result["content"].$inputTextArea["content"];
226 liveuser 8848
 
3 liveuser 8849
		#設置填寫要傳送的訊息輸入方框
8850
		#涵式說明:
8851
		#可以輸入文字的表單
8852
		#回傳的結果:
8853
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
8854
		#$result["function"],當前執行的函數.
8855
		#$result["error"],錯誤訊息陣列.
226 liveuser 8856
		#$result["content"],按鈕語法.
3 liveuser 8857
		#必填的參數
8858
		$conf["form::inputText"]["name"]="data";#爲該文字輸入框的名稱,用於讓接收頁面讀取的名稱。
8859
		$conf["form::inputText"]["readOnly"]="false";#爲該文字框是否可以填寫資料,若要只能觀看不能填寫,那麼就必須將其值設爲"true",反之要設爲"false"
8860
		#可省略的參數:
8861
		#$conf["width"]="";#爲文字框的外觀長度,預設為"100%".
8862
		#$conf["maxInputLength"]="";#爲可輸入的最大位元長度,預設不限制。
8863
		#$conf["autoFocus"]="true";#是否為將填寫的指標移到該表單,"true"代表要,預設為"false".
226 liveuser 8864
		#$conf["value"]="";#爲該文字框預設要顯示的文字,預設爲""。
3 liveuser 8865
		#$conf["class"]="";#爲要套用的css樣式,若省略,則會套用預設的 "__inputTextCssStyle" 樣式,其屬性爲 "width:100%","font-size:30px"
8866
		#$conf["jsActivitor"]="";#爲觸發js的條件,可以是"onChange"(已改變內容時)、"onClick"(按下按鈕時)、"onkeyup"(當鍵盤按下放開後)、"onmouseover"(當滑鼠移過去的時候)...,須搭配$conf["jsSubmitActionTarget"]參數。
226 liveuser 8867
		#$conf["jsAction"]="";#爲該js是要做什麼,可以是"document.testForm.submit()"(傳送名爲testForm的表單內容)...,須搭配$conf["jsActivitor"]參數。
3 liveuser 8868
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是"。也可以看作新的一列開始,預設為"false".
8869
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是"。也可以看成列裏面的元素開始,預設為"false".
8870
		#$conf["formStart"]="true";#爲是否要以<form>開頭,"true"表示"是",也可以看成表單的開始,預設為"false".
8871
		#$conf["formAction"]="";#表單遞交的目的地,若$conf["formStart"]為"true",則該參數不能省略.
8872
		#$conf["formName"]="";#爲該表單的名稱
8873
		#$conf["formMethod"]="";#爲傳輸的方法,若沒設定則預設爲post,其他可用的參數爲get。
8874
		#$conf["formTarget"]="";#為顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。
8875
		#$conf["tableStart"]="true";#爲該表單是否要以<table>開始。"true"爲是,預設為"false".
8876
		#$conf["tableClass"]="";#表格要套用的css樣式,若爲"__withoutBorder"的話則套用無框線的預設樣式;若爲"__withBorder"的話,則爲有框線的預設樣式,預設為"__withoutBorder".
8877
		#$conf["formEnd"]="true";#爲是否要以<form>結尾,"true"表示"是",也可以看成表單的結束,預設為"false".
8878
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是"。也可以看成列裏面的元素結束,預設為"false".
8879
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是"。也可以看作該列結束,預設為"false".
8880
		#$conf["tableEnd"]="true";#爲該表單是否要以</table>結尾,"true"爲是,預設為"false".
8881
		#$conf["autocomplete"],字串,是否依據使用者過往輸入的記錄來提示可能要的輸入內容,"on"為啟用,"off"為停用,預設為"on".
8882
		#$conf["autocomplete"]="off";
8883
		#$conf["required"],字串,該欄位是否必填,"true"為必填,"false"為可留空,預設為"false".
8884
		#$conf["required"]="true";
8885
		#$conf["comment"],字串,輸入方框上面要放哪些註解文字,亦即用label來呈現,同時指定"for"屬性的數值為當前"input"標籤的id,意即參數"name"的內容.
8886
		#$conf["comment"]="";
8887
		#$conf["placeholder"],字串,當沒有內容時要顯示的內容.
8888
		#$conf["placeholder"]="";
8889
		#$conf["br"],字串,"true"代表最後要換行,預設為"false".
8890
		#$conf["br"]="true";
8891
		#$conf["p"],字串,"true"代表最後要空一行,預設為"false".
8892
		#$conf["p"]="true";
8893
		#$conf["id"],字串,該元素的id,預設不使用.
8894
		$conf["form::inputText"]["id"]="input";
8895
		#參考資料來源:
8896
		#input=>http://www.w3schools.com/tags/tag_input.asp
8897
		$inputText=form::inputText($conf["form::inputText"]);
8898
		unset($conf["form::inputText"]);
226 liveuser 8899
 
3 liveuser 8900
		#如果輸入文字框失敗
8901
		if($inputText["status"]==="false"){
226 liveuser 8902
 
3 liveuser 8903
			#設置執行失敗
8904
			$result["status"]="false";
226 liveuser 8905
 
3 liveuser 8906
			#設置執行錯誤訊息
8907
			$result["error"]=$inputText;
226 liveuser 8908
 
3 liveuser 8909
			#回傳結果
8910
			return $result;
226 liveuser 8911
 
8912
			}#if end
8913
 
3 liveuser 8914
		#文字輸入框
8915
		$result["content"]=$result["content"].$inputText["content"];
226 liveuser 8916
 
3 liveuser 8917
		#設置觸發的按鈕
8918
		#函式說明:
8919
		#放置按鈕
8920
		#回傳結果:
8921
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
8922
		#$result["function"],當前執行的函數.
8923
		#$result["error"],錯誤訊息陣列.
226 liveuser 8924
		#$result["content"],按鈕語法.
3 liveuser 8925
		#必要的參數:
8926
		$conf["form::button"]["buttonDisplayValue"]="Send";#爲按鈕上顯示的文字。
8927
		#可省略的參數:
8928
		#$conf["buttonStyleName"]="";#可省略,爲按鈕所要使用的css樣式類別名稱,預設的css樣式爲 __simpleButtonLinkDefaultButtonCssStyle 。
8929
			#其屬性爲   "width","height","font-size","text-align"
8930
			#其屬性值爲 "100%" ,  "50"  ,    "30"   ,   "center"
8931
		#$conf["form::button"]["buttonActionScriptFunction"]="conn.send('Hello!');";#可省略,爲按下按鈕時所要執行的javaScript函式或程式,預設不設定。
8932
			#"document.forms.formName.submit()"爲傳送名爲testForm的表單內容
8933
			#"window.print()"爲使用瀏覽器內建工具列印當前網頁
8934
			#若搭配 javaScript 類別的 confirmWindow 函數的回傳結果,則會有確認視窗的效果.
8935
		#$conf["buttonBorder"]="";#可省略,爲IE9內會自動產生外框,此爲外框的厚度,屬性值爲正整數,預設爲0。
8936
		#$conf["disabled"]="true";#可省略,為按鈕的功能是否要取消,若為"true"則代表要取消,若為"false"則代表功能正常,預設為"false".
8937
		#$conf["tableStart"]="true";#爲是否要表格開始。"false"代表否,"true"代表是。預設爲"false"。
8938
		#$conf["tableClass"]="";#表格要套用的css樣式,若省略的話,則預設爲 __defaultTbaleCsssStyle 其屬性爲 table-layout:fixed word-break:break-all width:100% ,須搭配 $conf["tablStart"] 與 $conf["tableEnd"] 使用。
8939
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是"。也可以看作新的一列開始,預設為"false".
8940
		#$conf["trClass"]="__withoutBorder";#<tr>要套用的css樣式,預設為"__withoutBorder",亦即沒有框線的樣式;"__withBorder"則爲有框線的樣式
8941
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是"。也可以看成列裏面的元素開始,預設為"false".
8942
		#$conf["tdClass"]="__withoutBorder";#<td>要套用的css樣式,"__withoutBorder"爲沒有框線的樣式;__withBorder爲有框線的樣式
8943
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是"。也可以看成列裏面的元素結束,預設為"false".
8944
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是"。也可以看作該列結束,預設為"false".
8945
		#$conf["tableEnd"]="true";#爲是否要表格結束。"false"代表否,"true"代表是,預設爲"false"。
8946
		#$conf["formStart"]="true";#爲是否要表單開始,如果爲"true"則代表要表單開始,預設為"false".
8947
		#$conf["action"]="";#爲表單要傳送到哪個頁面,須搭配$conf["formStart"]與$conf["formEnd"]參數使用
8948
		#$conf["target"]="";#為目標表單顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。須搭配$conf["formStart"]與$conf["formEnd"]參數使用
8949
		#$conf["formEnd"]="true";#爲是否要表單結束,如果爲"true"則代表要表單結束,預設為"false".
8950
		#$conf["formId"],字串,表單的id.
8951
		#$conf["formId"]="";
8952
		#$conf["buttonId"],字串,按鈕的id.
8953
		$conf["form::button"]["buttonId"]="send";
8954
		#參考資料來源:
8955
		#http://stackoverflow.com/questions/3014649/how-to-disable-html-button-using-javascript
8956
		$button=form::button($conf["form::button"]);
8957
		unset($conf["form::button"]);
226 liveuser 8958
 
3 liveuser 8959
		#如果建立按鈕失敗
8960
		if($button["status"]==="false"){
226 liveuser 8961
 
3 liveuser 8962
			#設置執行失敗
8963
			$result["status"]="false";
226 liveuser 8964
 
3 liveuser 8965
			#設置執行錯誤訊息
8966
			$result["error"]=$button;
226 liveuser 8967
 
3 liveuser 8968
			#回傳結果
8969
			return $result;
226 liveuser 8970
 
8971
			}#if end
8972
 
3 liveuser 8973
		#建立跳到別的頁面的連結
8974
		#涵式說明:
8975
		#放置超鏈結
8976
		#回傳的結果:
8977
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
8978
		#$result["error"],錯誤訊息
8979
		#$result["content"],語法
8980
		#$result["function"],當前執行的函數名稱
8981
		#必填的參數:
226 liveuser 8982
		#$conf["position"],字串,爲要連結到的位置,若留空,將回自動變成"#",則可以搭配ajax傳值.
3 liveuser 8983
		$conf["link::show_link"]["position"]="webSocketT/hangFewSecs.php";
8984
		#$conf["linkName",字串,爲連結的顯示名稱
8985
		$conf["link::show_link"]["linkName"]="到別的頁面轉轉";
8986
		#可省略的參數:
8987
		#$conf["method"],字串,爲點選連結後,新畫面要如何呈現,可省略預設爲"_self",可用的選項有 _top(覆蓋目前的視窗來顯現新內容) _parent _self _blank(跳新視窗)
226 liveuser 8988
		#$conf["method"]="";
3 liveuser 8989
		#$conf["class"],字串,爲要套用的css超連節樣式,可省略.
8990
		#$conf["class"]="";
8991
		#$conf["id"],字串,超連結的id.
8992
		#$conf["id"]="";
8993
		#$conf["no_outline"],字串,是否要取消連結的框線,"false為不取消,"true"代表要取消,預設為"false".
8994
		#$conf["no_outline"]="";
8995
		$show_link=link::show_link($conf["link::show_link"]);
8996
		unset($conf["link::show_link"]);
226 liveuser 8997
 
3 liveuser 8998
		#串接超連結
8999
		$result["content"]=$result["content"].$show_link["content"];
226 liveuser 9000
 
3 liveuser 9001
		#設置用戶端的html與js語法
9002
		$result["content"]=$result["content"].$button["content"].$script;
226 liveuser 9003
 
3 liveuser 9004
		#設置執行正常
9005
		$result["status"]="true";
226 liveuser 9006
 
3 liveuser 9007
		#回傳結果
9008
		return $result;
226 liveuser 9009
 
9010
		}#function chatRoomClientDemoV3 end
9011
 
3 liveuser 9012
	/*
9013
	#函式說明:
9014
	#擴充過的Ratchet聊天室silder用戶端js範例,可以不跟ajax排隊.
9015
	#回傳結果:
9016
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9017
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 9018
	#$result["function"],當前執行的函式名稱.
3 liveuser 9019
	#$result["content"],html.
9020
	#必填參數:
9021
	#無.
9022
	#可省略參數:
9023
	#無.
9024
	#參考資料:
9025
	#Ratchet官網=>http://socketo.me/
9026
	#用apache的proxy來判斷為哪個服務,導到對應的port裡面=>https://groups.google.com/forum/#!topic/ratchet-php/dj-PgPPO_J0
9027
	#聊天室範例=>http://socketo.me/docs/hello-world
9028
	#備註:
226 liveuser 9029
	#僅適用於https網頁透過wss連線到web socket server.
3 liveuser 9030
	*/
9031
	public static function soldierClientDemo(){
226 liveuser 9032
 
3 liveuser 9033
		#初始化要回傳的結果
9034
		$result=array();
9035
 
9036
		#初始化儲存html的變數
9037
		$result["content"]="";
9038
 
9039
		#取得當前執行的函數名稱
9040
		$result["function"]=__FUNCTION__;
226 liveuser 9041
 
3 liveuser 9042
		#初始化帳號密碼
9043
		$ac="";
9044
		$pw="";
226 liveuser 9045
 
3 liveuser 9046
		#如果存在 $_SESSION["account"]
9047
		if(isset($_SESSION["account"])){
226 liveuser 9048
 
3 liveuser 9049
			#取得帳戶
9050
			$ac=$_SESSION["account"];
226 liveuser 9051
 
3 liveuser 9052
			}#if end
226 liveuser 9053
 
3 liveuser 9054
		#如果 this->$passwordCol 不為 ""
9055
		if(Chat::$passwordCol!==""){
226 liveuser 9056
 
3 liveuser 9057
			#如果存在 $_SESSION["password"]
9058
			if(isset($_SESSION["password"])){
226 liveuser 9059
 
3 liveuser 9060
				#取得帳戶
9061
				$pw=$_SESSION["password"];
226 liveuser 9062
 
3 liveuser 9063
				}#if end
226 liveuser 9064
 
3 liveuser 9065
			}#if end
226 liveuser 9066
 
3 liveuser 9067
		#取得 server 的 ip
9068
		#涵式說明:
9069
		#取得伺服器的IP,並回傳。
9070
		#回傳的結果:
9071
		#$result,伺服端的IP
9072
		#備註:
9073
		#伺服端必須被 localhost 以外的網址連結才會出現正確的IP
9074
		$getServerIP=csInformation::getServerIP();
226 liveuser 9075
 
3 liveuser 9076
		#設置用戶端連線到webSocket的範例
9077
		$script="<script>
226 liveuser 9078
 
3 liveuser 9079
			//ready 後執行
9080
			$(document).ready(function(){
226 liveuser 9081
 
3 liveuser 9082
				//取得帳號密碼
9083
				ac='".$ac."';
9084
				pw='".$pw."';
226 liveuser 9085
 
3 liveuser 9086
				//設置目前尚為連線到 webSocket Server
9087
				connected='false';
226 liveuser 9088
 
3 liveuser 9089
				//設置儲存應該要斷線的webSocket,避免太多連線在伺服器.
9090
				wbClosed='';
226 liveuser 9091
 
3 liveuser 9092
				//設置儲存webSocket連線的變數
9093
				wb='';
226 liveuser 9094
 
3 liveuser 9095
				//告訴server要執行的指令
9096
				cmd='ls -al';
226 liveuser 9097
 
3 liveuser 9098
				//連線到 web socket
9099
				connWebSock();
226 liveuser 9100
 
3 liveuser 9101
				//榜定按鈕事件
9102
				buttonEvent();
226 liveuser 9103
 
3 liveuser 9104
				});
226 liveuser 9105
 
3 liveuser 9106
			//連線到 web socket
9107
			function connWebSock()
9108
			{
9109
				//建立 web socket 連線到 wss://localhost/wss/chatDemo
9110
				var conn = new WebSocket('wss://".$getServerIP."/wss/chatDemo');
226 liveuser 9111
 
3 liveuser 9112
				//當連線成功後
9113
				conn.onopen = function(e){
226 liveuser 9114
 
3 liveuser 9115
					//印出連線成功訊息到console
9116
					console.log(\"Connection established!\");
226 liveuser 9117
 
3 liveuser 9118
					//設置已經連上 webSocket server
9119
					connected='true';
226 liveuser 9120
 
3 liveuser 9121
					//另存 webSocket 物件
9122
					wb=conn;
226 liveuser 9123
 
3 liveuser 9124
					//如果存在前一個連線物件
9125
					if(wbClosed!==''){
226 liveuser 9126
 
3 liveuser 9127
						//提示關閉前個連線
9128
						console.log(\"close last connection!\");
226 liveuser 9129
 
3 liveuser 9130
						//關閉之前的連線
9131
						wbClosed.close();
226 liveuser 9132
 
3 liveuser 9133
						//清空
9134
						wbClosed='';
226 liveuser 9135
 
3 liveuser 9136
						}
226 liveuser 9137
 
3 liveuser 9138
					}
9139
 
9140
				//當有收到訊息時
9141
				conn.onmessage = function(e){
226 liveuser 9142
 
3 liveuser 9143
					//將訊息顯現在console
9144
					console.log(e.data);
226 liveuser 9145
 
3 liveuser 9146
					//解析json字串
9147
					data=JSON.parse(e.data);
226 liveuser 9148
 
3 liveuser 9149
					//如果要要求login的訊息
9150
					if(data.type==='login'){
226 liveuser 9151
 
3 liveuser 9152
						//如果有查到帳號
9153
						if(ac!==''){
226 liveuser 9154
 
3 liveuser 9155
							//如果要求輸入帳號
9156
							if(data.data==='Please input your account! ex:account:ws1'){
226 liveuser 9157
 
3 liveuser 9158
								//傳送帳號
9159
								conn.send('account:'+ac);
226 liveuser 9160
 
3 liveuser 9161
								}
226 liveuser 9162
 
3 liveuser 9163
							//如果有查到密碼
9164
							if(pw!==''){
226 liveuser 9165
 
9166
								//如果要求輸入密碼
3 liveuser 9167
								if(data.data==='Please input your password! ex:password:ws1'){
226 liveuser 9168
 
3 liveuser 9169
									//傳送密碼
9170
									conn.send('password:'+pw);
226 liveuser 9171
 
3 liveuser 9172
									}
226 liveuser 9173
 
3 liveuser 9174
								}
226 liveuser 9175
 
3 liveuser 9176
							}
226 liveuser 9177
 
3 liveuser 9178
						//反之如果登入成功
9179
						else if(data.data==='Login successfully!'){
226 liveuser 9180
 
3 liveuser 9181
							//設置已經驗證成功
9182
							connected='true';
226 liveuser 9183
 
3 liveuser 9184
							}
226 liveuser 9185
 
3 liveuser 9186
						}
226 liveuser 9187
 
9188
					//如果收到的是 'cmd' 類型
3 liveuser 9189
					else if(data.type==='cmd'){
226 liveuser 9190
 
3 liveuser 9191
						//將訊息顯現在console
9192
						//console.log(data.data);
226 liveuser 9193
 
3 liveuser 9194
						}
226 liveuser 9195
 
3 liveuser 9196
					}
226 liveuser 9197
 
3 liveuser 9198
				//當連線斷開後
9199
				conn.onclose = function(e){
226 liveuser 9200
 
3 liveuser 9201
					//設置未連上 webSocket server
9202
					connected='false';
226 liveuser 9203
 
3 liveuser 9204
					//如果有之前的連線物件
9205
					if(wb!==''){
226 liveuser 9206
 
3 liveuser 9207
						//儲存應該要斷線的webSocket,避免太多連線在伺服器.
9208
						wbClosed=wb;
226 liveuser 9209
 
3 liveuser 9210
						}
226 liveuser 9211
 
3 liveuser 9212
					//清空 webSocket 物件
9213
					wb='';
226 liveuser 9214
 
3 liveuser 9215
					//指定1秒刷新一次
226 liveuser 9216
					setTimeout('connWebSock()',1000);
9217
 
3 liveuser 9218
					}
226 liveuser 9219
 
9220
				}
9221
 
3 liveuser 9222
			//榜定下達命令的按鈕事件
9223
			function buttonEvent(){
226 liveuser 9224
 
3 liveuser 9225
				//當按下送出按鈕
9226
				$('#send').on('click',function(){
226 liveuser 9227
 
3 liveuser 9228
					//如果已經連到 webSocket server 了
9229
					if(connected==='true'){
226 liveuser 9230
 
3 liveuser 9231
						//傳送訊息
9232
						wb.send('cmd:'+cmd);
226 liveuser 9233
 
3 liveuser 9234
						}
226 liveuser 9235
 
3 liveuser 9236
					});
226 liveuser 9237
 
9238
				//榜定ajax要求
3 liveuser 9239
				$('#run').on('click',function(){
226 liveuser 9240
 
3 liveuser 9241
					$.ajax({
226 liveuser 9242
 
3 liveuser 9243
						url: 'webSocketT/sleep.php',
9244
						type:'GET',
9245
						async:true,
9246
						data:{},
9247
						success:function(data, status){
226 liveuser 9248
 
3 liveuser 9249
							console.log(data.toSource());
226 liveuser 9250
 
3 liveuser 9251
							}
226 liveuser 9252
 
3 liveuser 9253
						});
226 liveuser 9254
 
3 liveuser 9255
					});
226 liveuser 9256
 
3 liveuser 9257
				}
226 liveuser 9258
 
9259
			</script>";
9260
 
3 liveuser 9261
		#串接script語法
9262
		$result["content"]=$result["content"].$script;
226 liveuser 9263
 
3 liveuser 9264
		#設置觸發ajax的按鈕
9265
		#函式說明:
9266
		#放置按鈕
9267
		#回傳結果:
9268
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9269
		#$result["function"],當前執行的函數.
9270
		#$result["error"],錯誤訊息陣列.
226 liveuser 9271
		#$result["content"],按鈕語法.
3 liveuser 9272
		#必要的參數:
9273
		$conf["form::button"]["buttonDisplayValue"]="ajax";#爲按鈕上顯示的文字。
9274
		#可省略的參數:
9275
		#$conf["buttonStyleName"]="";#可省略,爲按鈕所要使用的css樣式類別名稱,預設的css樣式爲 __simpleButtonLinkDefaultButtonCssStyle 。
9276
			#其屬性爲   "width","height","font-size","text-align"
9277
			#其屬性值爲 "100%" ,  "50"  ,    "30"   ,   "center"
9278
		#$conf["form::button"]["buttonActionScriptFunction"]="conn.send('Hello!');";#可省略,爲按下按鈕時所要執行的javaScript函式或程式,預設不設定。
9279
			#"document.forms.formName.submit()"爲傳送名爲testForm的表單內容
9280
			#"window.print()"爲使用瀏覽器內建工具列印當前網頁
9281
			#若搭配 javaScript 類別的 confirmWindow 函數的回傳結果,則會有確認視窗的效果.
9282
		#$conf["buttonBorder"]="";#可省略,爲IE9內會自動產生外框,此爲外框的厚度,屬性值爲正整數,預設爲0。
9283
		#$conf["disabled"]="true";#可省略,為按鈕的功能是否要取消,若為"true"則代表要取消,若為"false"則代表功能正常,預設為"false".
9284
		#$conf["tableStart"]="true";#爲是否要表格開始。"false"代表否,"true"代表是。預設爲"false"。
9285
		#$conf["tableClass"]="";#表格要套用的css樣式,若省略的話,則預設爲 __defaultTbaleCsssStyle 其屬性爲 table-layout:fixed word-break:break-all width:100% ,須搭配 $conf["tablStart"] 與 $conf["tableEnd"] 使用。
9286
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是"。也可以看作新的一列開始,預設為"false".
9287
		#$conf["trClass"]="__withoutBorder";#<tr>要套用的css樣式,預設為"__withoutBorder",亦即沒有框線的樣式;"__withBorder"則爲有框線的樣式
9288
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是"。也可以看成列裏面的元素開始,預設為"false".
9289
		#$conf["tdClass"]="__withoutBorder";#<td>要套用的css樣式,"__withoutBorder"爲沒有框線的樣式;__withBorder爲有框線的樣式
9290
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是"。也可以看成列裏面的元素結束,預設為"false".
9291
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是"。也可以看作該列結束,預設為"false".
9292
		#$conf["tableEnd"]="true";#爲是否要表格結束。"false"代表否,"true"代表是,預設爲"false"。
9293
		#$conf["formStart"]="true";#爲是否要表單開始,如果爲"true"則代表要表單開始,預設為"false".
9294
		#$conf["action"]="";#爲表單要傳送到哪個頁面,須搭配$conf["formStart"]與$conf["formEnd"]參數使用
9295
		#$conf["target"]="";#為目標表單顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。須搭配$conf["formStart"]與$conf["formEnd"]參數使用
9296
		#$conf["formEnd"]="true";#爲是否要表單結束,如果爲"true"則代表要表單結束,預設為"false".
9297
		#$conf["formId"],字串,表單的id.
9298
		#$conf["formId"]="";
9299
		#$conf["buttonId"],字串,按鈕的id.
9300
		$conf["form::button"]["buttonId"]="run";
9301
		#參考資料來源:
9302
		#http://stackoverflow.com/questions/3014649/how-to-disable-html-button-using-javascript
9303
		$button=form::button($conf["form::button"]);
9304
		unset($conf["form::button"]);
226 liveuser 9305
 
3 liveuser 9306
		#如果建立按鈕失敗
9307
		if($button["status"]==="false"){
226 liveuser 9308
 
3 liveuser 9309
			#設置執行失敗
9310
			$result["status"]="false";
226 liveuser 9311
 
3 liveuser 9312
			#設置執行錯誤訊息
9313
			$result["error"]=$button;
226 liveuser 9314
 
3 liveuser 9315
			#回傳結果
9316
			return $result;
226 liveuser 9317
 
3 liveuser 9318
			}#if end
226 liveuser 9319
 
3 liveuser 9320
		#串接按鈕語法
9321
		$result["content"]=$result["content"].$button["content"];
226 liveuser 9322
 
3 liveuser 9323
		#設置觸發命令的按鈕
9324
		#函式說明:
9325
		#放置按鈕
9326
		#回傳結果:
9327
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9328
		#$result["function"],當前執行的函數.
9329
		#$result["error"],錯誤訊息陣列.
226 liveuser 9330
		#$result["content"],按鈕語法.
3 liveuser 9331
		#必要的參數:
9332
		$conf["form::button"]["buttonDisplayValue"]="Send cmd";#爲按鈕上顯示的文字。
9333
		#可省略的參數:
9334
		#$conf["buttonStyleName"]="";#可省略,爲按鈕所要使用的css樣式類別名稱,預設的css樣式爲 __simpleButtonLinkDefaultButtonCssStyle 。
9335
			#其屬性爲   "width","height","font-size","text-align"
9336
			#其屬性值爲 "100%" ,  "50"  ,    "30"   ,   "center"
9337
		#$conf["form::button"]["buttonActionScriptFunction"]="conn.send('Hello!');";#可省略,爲按下按鈕時所要執行的javaScript函式或程式,預設不設定。
9338
			#"document.forms.formName.submit()"爲傳送名爲testForm的表單內容
9339
			#"window.print()"爲使用瀏覽器內建工具列印當前網頁
9340
			#若搭配 javaScript 類別的 confirmWindow 函數的回傳結果,則會有確認視窗的效果.
9341
		#$conf["buttonBorder"]="";#可省略,爲IE9內會自動產生外框,此爲外框的厚度,屬性值爲正整數,預設爲0。
9342
		#$conf["disabled"]="true";#可省略,為按鈕的功能是否要取消,若為"true"則代表要取消,若為"false"則代表功能正常,預設為"false".
9343
		#$conf["tableStart"]="true";#爲是否要表格開始。"false"代表否,"true"代表是。預設爲"false"。
9344
		#$conf["tableClass"]="";#表格要套用的css樣式,若省略的話,則預設爲 __defaultTbaleCsssStyle 其屬性爲 table-layout:fixed word-break:break-all width:100% ,須搭配 $conf["tablStart"] 與 $conf["tableEnd"] 使用。
9345
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是"。也可以看作新的一列開始,預設為"false".
9346
		#$conf["trClass"]="__withoutBorder";#<tr>要套用的css樣式,預設為"__withoutBorder",亦即沒有框線的樣式;"__withBorder"則爲有框線的樣式
9347
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是"。也可以看成列裏面的元素開始,預設為"false".
9348
		#$conf["tdClass"]="__withoutBorder";#<td>要套用的css樣式,"__withoutBorder"爲沒有框線的樣式;__withBorder爲有框線的樣式
9349
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是"。也可以看成列裏面的元素結束,預設為"false".
9350
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是"。也可以看作該列結束,預設為"false".
9351
		#$conf["tableEnd"]="true";#爲是否要表格結束。"false"代表否,"true"代表是,預設爲"false"。
9352
		#$conf["formStart"]="true";#爲是否要表單開始,如果爲"true"則代表要表單開始,預設為"false".
9353
		#$conf["action"]="";#爲表單要傳送到哪個頁面,須搭配$conf["formStart"]與$conf["formEnd"]參數使用
9354
		#$conf["target"]="";#為目標表單顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。須搭配$conf["formStart"]與$conf["formEnd"]參數使用
9355
		#$conf["formEnd"]="true";#爲是否要表單結束,如果爲"true"則代表要表單結束,預設為"false".
9356
		#$conf["formId"],字串,表單的id.
9357
		#$conf["formId"]="";
9358
		#$conf["buttonId"],字串,按鈕的id.
9359
		$conf["form::button"]["buttonId"]="send";
9360
		#參考資料來源:
9361
		#http://stackoverflow.com/questions/3014649/how-to-disable-html-button-using-javascript
9362
		$button=form::button($conf["form::button"]);
9363
		unset($conf["form::button"]);
226 liveuser 9364
 
3 liveuser 9365
		#如果建立按鈕失敗
9366
		if($button["status"]==="false"){
226 liveuser 9367
 
3 liveuser 9368
			#設置執行失敗
9369
			$result["status"]="false";
226 liveuser 9370
 
3 liveuser 9371
			#設置執行錯誤訊息
9372
			$result["error"]=$button;
226 liveuser 9373
 
3 liveuser 9374
			#回傳結果
9375
			return $result;
226 liveuser 9376
 
3 liveuser 9377
			}#if end
226 liveuser 9378
 
3 liveuser 9379
		#串接按鈕語法
9380
		$result["content"]=$result["content"].$button["content"];
226 liveuser 9381
 
3 liveuser 9382
		#設置執行正常
9383
		$result["status"]="true";
226 liveuser 9384
 
3 liveuser 9385
		#回傳結果
9386
		return $result;
226 liveuser 9387
 
3 liveuser 9388
		}#function soldierClientDemo end
226 liveuser 9389
 
3 liveuser 9390
	/*
9391
	#函式說明:
9392
	#擴充過的Ratchet的聊天室soilier用戶端與伺服端範例,port為8080.
9393
	#回傳結果:
9394
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9395
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 9396
	#$result["function"],當前執行的函式名稱.
3 liveuser 9397
	#必填參數:
9398
	#$conf["fileArgu"],字串,__FILE__的內容.
9399
	$conf["fileArgu"]=__FILE__;
9400
	#可省略參數:
9401
	#$conf["disReg"],字串,是否要取消apache的passProxy檢查與設定,預設為"false"不取消,"true"為取消.
9402
	#$conf["disReg"]="";
9403
	#參考資料:
9404
	#Ratchet官網=>http://socketo.me/
9405
	#聊天室範例=>http://socketo.me/docs/hello-world
9406
	#備註:
9407
	#必須要在命令列環境下執行一次,建立webSocket Server後,再於網頁端執行即可產生webSocket Client端的code.
9408
	#僅適用於https網頁透過wss連線到web socket server.
9409
	*/
9410
	public static function soldierDemo(&$conf){
226 liveuser 9411
 
3 liveuser 9412
		#初始化要回傳的結果
9413
		$result=array();
9414
 
9415
		#取得當前執行的函數名稱
9416
		$result["function"]=__FUNCTION__;
9417
 
9418
		#涵式說明:
9419
		#判斷當前環境為web還是cmd
9420
		#回傳結果:
9421
		#$result,"web"或"cmd"
9422
		if(csInformation::getEnv()==="web"){
226 liveuser 9423
 
3 liveuser 9424
			#建立 web socket client 的 js 語法
9425
			#函式說明:
9426
			#聊天室用戶端js範例
9427
			#回傳結果:
9428
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9429
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 9430
			#$result["function"],當前執行的函式名稱.
3 liveuser 9431
			#$result["content"],js語法.
9432
			#參考資料:
9433
			#Ratchet官網=>http://socketo.me/
9434
			#聊天室範例=>http://socketo.me/docs/hello-world
9435
			$soldierClientDemo=webSock::soldierClientDemo();
226 liveuser 9436
 
3 liveuser 9437
			#如果建立聊天室用戶端失敗
9438
			if($soldierClientDemo["status"]==="false"){
226 liveuser 9439
 
3 liveuser 9440
				#設置執行失敗
9441
				$result["status"]="false";
226 liveuser 9442
 
3 liveuser 9443
				#設置執行錯誤訊息
9444
				$result["error"]=$soldierClientDemo;
226 liveuser 9445
 
3 liveuser 9446
				#回傳結果
9447
				return $result;
226 liveuser 9448
 
3 liveuser 9449
				}#if end
226 liveuser 9450
 
3 liveuser 9451
			#取得聊天室的語法
9452
			$result["content"]=$soldierClientDemo["content"];
226 liveuser 9453
 
3 liveuser 9454
			#設置執行正常
9455
			$result["status"]="true";
226 liveuser 9456
 
3 liveuser 9457
			#回傳結果
9458
			return $result;
226 liveuser 9459
 
3 liveuser 9460
			}#if end
9461
 
9462
		#如果沒有參數
9463
		if(func_num_args()==0){
226 liveuser 9464
 
3 liveuser 9465
			#設置執行失敗
9466
			$result["status"]="false";
226 liveuser 9467
 
3 liveuser 9468
			#設置執行錯誤訊息
9469
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 9470
 
3 liveuser 9471
			#回傳結果
9472
			return $result;
226 liveuser 9473
 
3 liveuser 9474
			}#if end
226 liveuser 9475
 
3 liveuser 9476
		#如果沒有參數
9477
		if(func_num_args()==0){
226 liveuser 9478
 
3 liveuser 9479
			#設置執行失敗
9480
			$result["status"]="false";
226 liveuser 9481
 
3 liveuser 9482
			#設置執行錯誤訊息
9483
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 9484
 
3 liveuser 9485
			#回傳結果
9486
			return $result;
226 liveuser 9487
 
3 liveuser 9488
			}#if end
226 liveuser 9489
 
3 liveuser 9490
		#取得參數
9491
		$result["argu"]=$conf;
9492
 
9493
		#如果 $conf 不為陣列
9494
		if(gettype($conf)!=="array"){
226 liveuser 9495
 
3 liveuser 9496
			#設置執行失敗
9497
			$result["status"]="false";
226 liveuser 9498
 
3 liveuser 9499
			#設置執行錯誤訊息
9500
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 9501
 
3 liveuser 9502
			#如果傳入的參數為 null
9503
			if($conf===null){
226 liveuser 9504
 
3 liveuser 9505
				#設置執行錯誤訊息
9506
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 9507
 
3 liveuser 9508
				}#if end
9509
 
9510
			#回傳結果
9511
			return $result;
226 liveuser 9512
 
3 liveuser 9513
			}#if end
226 liveuser 9514
 
3 liveuser 9515
		#檢查參數
9516
		#函式說明:
9517
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
9518
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9519
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
9520
		#$result["function"],當前執行的函式名稱.
9521
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
9522
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
9523
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
9524
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
9525
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
9526
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
9527
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
9528
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
9529
		#必填寫的參數:
9530
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
9531
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
9532
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
9533
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu");
9534
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
9535
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
9536
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
9537
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
9538
		#可以省略的參數:
9539
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
9540
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
9541
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
9542
		#$conf["canNotBeEmpty"]=array();
9543
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
9544
		#$conf["canBeEmpty"]=array();
9545
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
9546
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
9547
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
9548
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("disReg");
226 liveuser 9549
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3 liveuser 9550
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
9551
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
9552
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("false");
9553
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
9554
		#$conf["arrayCountEqualCheck"][]=array();
9555
		#參考資料來源:
9556
		#array_keys=>http://php.net/manual/en/function.array-keys.php
9557
		#建議:
9558
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
9559
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
9560
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 9561
 
3 liveuser 9562
		#如果檢查參數失敗
9563
		if($checkArguments["status"]==="false"){
226 liveuser 9564
 
3 liveuser 9565
			#設置執行失敗
9566
			$result["status"]="false";
226 liveuser 9567
 
3 liveuser 9568
			#設置執行錯誤訊息
9569
			$result["error"]=$checkArguments;
226 liveuser 9570
 
3 liveuser 9571
			#回傳結果
9572
			return $result;
226 liveuser 9573
 
3 liveuser 9574
			}#if end
226 liveuser 9575
 
3 liveuser 9576
		#如果參數檢查不通過
9577
		if($checkArguments["passed"]==="false"){
226 liveuser 9578
 
3 liveuser 9579
			#設置執行失敗
9580
			$result["status"]="false";
226 liveuser 9581
 
3 liveuser 9582
			#設置執行錯誤訊息
9583
			$result["error"]=$checkArguments;
226 liveuser 9584
 
3 liveuser 9585
			#回傳結果
9586
			return $result;
226 liveuser 9587
 
3 liveuser 9588
			}#if end
9589
 
9590
		#執行到這邊代表是命令列環境
226 liveuser 9591
 
3 liveuser 9592
		#如果沒有要取消設定 passProxy
9593
		if($conf["disReg"]==="false"){
226 liveuser 9594
 
3 liveuser 9595
			#確認設定 passProxy
9596
			#函式說明:
9597
			#註冊聊天室範例的 passProxy 設定,本函數會用root帳戶去新增.
9598
			#會在 /etc/httpd/conf/httpd.conf 檔案裡面加上以下內容
9599
			##Enable the mod_proxy modules in the HTTPD
9600
			#LoadModule proxy_module modules/mod_proxy.so
9601
			#LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
9602
			#
9603
			##ProxyPass
9604
			##If requeted web address is begin with (ws://hostdns)/wss/chatDemo, then redirect to ws://localhost:8080
9605
			#ProxyPass /wss/chatDemo ws://localhost:8080
9606
			#回傳結果:
9607
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9608
			#$reuslt["error"],執行不正常結束的錯訊息陣列.
9609
			#$result["function"],當前執行的函式名稱.
9610
			#必填參數:
9611
			#$conf["fileArgu"],字串,__FILE__的內容.
9612
			$conf["webSock::registerChatDemo"]["fileArgu"]=$conf["fileArgu"];
9613
			#可省略參數:
9614
			#$conf["rootPasswd"],字串,root帳戶的密碼,預設為"password".
9615
			#$conf["rootPasswd"]="password";
9616
			#$conf["httpd.conf"],字串,apache設定檔的路徑與名稱,預設為"/etc/httpd/conf/httpd.conf".
226 liveuser 9617
			#$conf["httpd.conf"]="/etc/httpd/conf/httpd.conf";
3 liveuser 9618
			#備註:
9619
			#僅能在命令列環境下執行.
9620
			#改變暫存檔案權限的功能異常.
9621
			#參考資料:
9622
			#用apache的passProxy來識別服務並轉到正確的port=>https://groups.google.com/forum/#!topic/ratchet-php/dj-PgPPO_J0
9623
			$registerChatDemo=webSock::registerChatDemo($conf["webSock::registerChatDemo"]);
9624
			unset($conf["webSock::registerChatDemo"]);
226 liveuser 9625
 
3 liveuser 9626
			#如果註冊 ChatDemo 服務失敗
9627
			if($registerChatDemo["status"]==="false"){
226 liveuser 9628
 
3 liveuser 9629
				#設置執行失敗
9630
				$result["status"]="false";
226 liveuser 9631
 
3 liveuser 9632
				#設置執行錯誤訊息
9633
				$result["error"]=$registerChatDemo;
226 liveuser 9634
 
3 liveuser 9635
				#回傳結果
9636
				return $result;
226 liveuser 9637
 
3 liveuser 9638
				}#if end
226 liveuser 9639
 
3 liveuser 9640
			}#if end
226 liveuser 9641
 
3 liveuser 9642
		#函式說明:
9643
		#擴充過的Ratchet聊天室伺服端範例,port為8080.
9644
		#回傳結果:
9645
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9646
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
226 liveuser 9647
		#$result["function"],當前執行的函式名稱.
3 liveuser 9648
		#參考資料:
9649
		#Ratchet官網=>http://socketo.me/
9650
		#聊天室範例=>http://socketo.me/docs/hello-world
9651
		#備註:
9652
		#必須要在命令列環境下執行才行.
9653
		$conf["webSock"]["soldierServerDemo"]["fileArgu"]=$conf["fileArgu"];
9654
		$soldierServerDemo=webSock::soldierServerDemo($conf["webSock"]["soldierServerDemo"]);
226 liveuser 9655
		unset($conf["webSock"]["soldierServerDemo"]);
9656
 
3 liveuser 9657
		#如果運行 chatRoomServerDemo 失敗
9658
		if($soldierServerDemo["status"]==="false"){
226 liveuser 9659
 
3 liveuser 9660
			#設置執行失敗
9661
			$result["status"]="false";
226 liveuser 9662
 
3 liveuser 9663
			#設置執行錯誤訊息
9664
			$result["error"]=$soldierServerDemo;
226 liveuser 9665
 
3 liveuser 9666
			#回傳結果
9667
			return $result;
226 liveuser 9668
 
9669
			}#if end
9670
 
3 liveuser 9671
		#設置執行正常
9672
		$result["status"]="true";
226 liveuser 9673
 
9674
		#回傳結果
3 liveuser 9675
		return $result;
226 liveuser 9676
 
3 liveuser 9677
		}#function soldierDemo end
226 liveuser 9678
 
3 liveuser 9679
	/*
9680
	#函式說明:
9681
	#註冊Ratchet聊天室範例的 passProxy 設定,本函數會用root帳戶去新增.
9682
	#會在 /etc/httpd/conf/httpd.conf 檔案裡面加上以下內容
9683
	##Enable the mod_proxy modules in the HTTPD
9684
	#LoadModule proxy_module modules/mod_proxy.so
9685
	#LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
9686
	#
9687
	##ProxyPass
9688
	##If requeted web address is begin with (ws://hostdns)/wss/chatDemo, then redirect to ws://localhost:8080
9689
	#ProxyPass /wss/chatDemo ws://localhost:8080
9690
	#回傳結果:
9691
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9692
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
9693
	#$result["function"],當前執行的函式名稱.
9694
	#必填參數:
9695
	#$conf["fileArgu"],字串,__FILE__的內容.
9696
	$conf["fileArgu"]=__FILE__;
9697
	#可省略參數:
9698
	#$conf["rootPasswd"],字串,root帳戶的密碼,預設為"password".
9699
	#$conf["rootPasswd"]="password";
9700
	#$conf["httpd.conf"],字串,apache設定檔的路徑與名稱,預設為"/etc/httpd/conf/httpd.conf".
226 liveuser 9701
	#$conf["httpd.conf"]="/etc/httpd/conf/httpd.conf";
3 liveuser 9702
	#備註:
9703
	#僅能在命令列環境下執行.
9704
	#改變暫存檔案權限的功能異常.
9705
	#參考資料:
9706
	#用apache的passProxy來識別服務並轉到正確的port=>https://groups.google.com/forum/#!topic/ratchet-php/dj-PgPPO_J0
9707
	*/
9708
	public static function registerChatDemo(&$conf){
226 liveuser 9709
 
3 liveuser 9710
		#初始化要回傳的結果
9711
		$result=array();
9712
 
9713
		#取得當前執行的函數名稱
9714
		$result["function"]=__FUNCTION__;
9715
 
9716
		#涵式說明:
9717
		#判斷當前環境為web還是cmd
9718
		#回傳結果:
9719
		#$result,"web"或"cmd"
9720
		if(csInformation::getEnv()=="web"){
226 liveuser 9721
 
3 liveuser 9722
			#設置執行失敗
9723
			$result["status"]="false";
226 liveuser 9724
 
3 liveuser 9725
			#設置執行錯誤訊息
9726
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 9727
 
3 liveuser 9728
			#回傳結果
9729
			return $result;
226 liveuser 9730
 
3 liveuser 9731
			}#if end
226 liveuser 9732
 
3 liveuser 9733
		#取得參數
9734
		$result["argu"]=$conf;
9735
 
9736
		#如果 $conf 不為陣列
9737
		if(gettype($conf)!="array"){
226 liveuser 9738
 
3 liveuser 9739
			#設置執行失敗
9740
			$result["status"]="false";
226 liveuser 9741
 
3 liveuser 9742
			#設置執行錯誤訊息
9743
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 9744
 
3 liveuser 9745
			#如果傳入的參數為 null
9746
			if($conf==null){
226 liveuser 9747
 
3 liveuser 9748
				#設置執行錯誤訊息
9749
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 9750
 
3 liveuser 9751
				}#if end
9752
 
9753
			#回傳結果
9754
			return $result;
226 liveuser 9755
 
3 liveuser 9756
			}#if end
226 liveuser 9757
 
3 liveuser 9758
		#檢查參數
9759
		#函式說明:
9760
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
9761
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9762
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
9763
		#$result["function"],當前執行的函式名稱.
9764
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
9765
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
9766
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
9767
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
9768
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
9769
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
9770
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
9771
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
9772
		#必填寫的參數:
9773
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
9774
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
9775
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
9776
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu");
9777
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
9778
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
9779
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
9780
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
9781
		#可以省略的參數:
9782
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
9783
		#$conf["canBeEmptyString"]="false";
9784
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
9785
		#$conf["canNotBeEmpty"]=array();
9786
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
9787
		#$conf["canBeEmpty"]=array();
9788
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
9789
		#$conf["skipableVariableCanNotBeEmpty"]=array();
9790
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
9791
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("httpd.conf","rootPasswd");
226 liveuser 9792
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3 liveuser 9793
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
9794
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
9795
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("/etc/httpd/conf/httpd.conf","password");
9796
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
9797
		#$conf["arrayCountEqualCheck"][]=array();
9798
		#參考資料來源:
9799
		#array_keys=>http://php.net/manual/en/function.array-keys.php
9800
		#建議:
9801
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
9802
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
9803
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 9804
 
3 liveuser 9805
		#如果檢查參數失敗
9806
		if($checkArguments["status"]==="false"){
226 liveuser 9807
 
3 liveuser 9808
			#設置執行失敗
9809
			$result["status"]="false";
226 liveuser 9810
 
3 liveuser 9811
			#設置執行錯誤訊息
9812
			$result["error"]=$checkArguments;
226 liveuser 9813
 
3 liveuser 9814
			#回傳結果
9815
			return $result;
226 liveuser 9816
 
3 liveuser 9817
			}#if end
226 liveuser 9818
 
3 liveuser 9819
		#如果參數檢查不通過
9820
		if($checkArguments["passed"]==="false"){
226 liveuser 9821
 
3 liveuser 9822
			#設置執行失敗
9823
			$result["status"]="false";
226 liveuser 9824
 
3 liveuser 9825
			#設置執行錯誤訊息
9826
			$result["error"]=$checkArguments;
226 liveuser 9827
 
3 liveuser 9828
			#回傳結果
9829
			return $result;
226 liveuser 9830
 
3 liveuser 9831
			}#if end
226 liveuser 9832
 
3 liveuser 9833
		#取得root密碼
9834
		#函式說明:
9835
		#藉由使用者的輸入來確認root使用者密碼是否正確.
9836
		#回傳結果:
226 liveuser 9837
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3 liveuser 9838
		#$result["function"],當前執行的函數名稱.
9839
		#$result["error"],錯誤訊息陣列.
226 liveuser 9840
		#$result["content"],root密碼.
3 liveuser 9841
		#必填參數:
9842
		#$conf["fileArgu"],字串,__FILE__的內容.
9843
		$conf["cmd::validRootPasswd"]["fileArgu"]=$conf["fileArgu"];
9844
		#可省略參數:
9845
		#$conf["password"],字串,用於驗證root使用者的密碼,若未設定則預設為"rootPasswd".
9846
		$conf["cmd::validRootPasswd"]["password"]=$conf["rootPasswd"];
9847
		#備註:
9848
		#建構中
9849
		$validRootPasswd=cmd::validRootPasswd($conf["cmd::validRootPasswd"]);
9850
		unset($conf["cmd::validRootPasswd"]);
226 liveuser 9851
 
3 liveuser 9852
		#如果取得root密碼失敗
9853
		if($validRootPasswd["status"]==="false"){
226 liveuser 9854
 
3 liveuser 9855
			#設置執行失敗
9856
			$result["status"]="false";
226 liveuser 9857
 
3 liveuser 9858
			#設置執行錯誤訊息
9859
			$result["error"]=$validRootPasswd;
226 liveuser 9860
 
3 liveuser 9861
			#回傳結果
9862
			return $result;
226 liveuser 9863
 
3 liveuser 9864
			}#if end
226 liveuser 9865
 
3 liveuser 9866
		#取得root密碼
9867
		$conf["rootPasswd"]=$validRootPasswd["content"];
226 liveuser 9868
 
3 liveuser 9869
		#檢查httpd設定檔案有無設定載入 proxy 模組與設定 ProxyPass
9870
		#函式說明:
9871
		#取得檔的內容並以列為單位搜尋多個關鍵字.
9872
		#回傳結果:
9873
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9874
		#$result["error"],錯誤訊息.
9875
		#$result["function"],當前執行的函數名稱.
9876
		#$result["content"],取得讀取到的檔案內容.
9877
		#$result["founded"],每個關鍵字串尋找的結果,"true"代表有找到,"false"代表沒有找到.
9878
		#$result["foundedLine"],每個找到的關鍵字是在第幾列找到的,key值與$result["founded"]的key值一樣.
9879
		#必填的參數:
9880
		#$conf["file"],字串,檔案的位置與名稱.
9881
		$conf["cmd::checkFileKeyStrLBL"]["file"]=$conf["httpd.conf"];
9882
		#$conf["keyStr"],陣列字串,要搜尋每列有哪些關鍵字串.
226 liveuser 9883
		$conf["cmd::checkFileKeyStrLBL"]["keyStr"]=array("LoadModule proxy_module modules/mod_proxy.so","LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so","ProxyPass /wss/chatDemo ws://localhost:8080");
3 liveuser 9884
		#可省略參數:
9885
		#$conf["username"],字串,要以哪個使用者來執行,預設為執行該php程式的使用者.
9886
		$conf["cmd::checkFileKeyStrLBL"]["username"]="root";
9887
		#$conf["password"],字串,使用者對應的密碼,預設不使用.
9888
		$conf["cmd::checkFileKeyStrLBL"]["password"]=$conf["rootPasswd"];
9889
		#$conf["fileArgu"],字串,__FILE__的內容,預設為當前檔案的位置.
9890
		$conf["cmd::checkFileKeyStrLBL"]["fileArgu"]=$conf["fileArgu"];
9891
		#$conf["tempDir"],字串,暫存資料的目錄位置,預設為".cmd/checkFileKeyStrLBL".
9892
		#$conf["tempDir"]="";
9893
		$checkFileKeyStrLBL=cmd::checkFileKeyStrLBL($conf["cmd::checkFileKeyStrLBL"]);
9894
		unset($conf["cmd::checkFileKeyStrLBL"]);
226 liveuser 9895
 
3 liveuser 9896
		#如果檢查設定值失敗
9897
		if($checkFileKeyStrLBL["status"]==="false"){
226 liveuser 9898
 
3 liveuser 9899
			#設置執行失敗
9900
			$result["status"]="false";
226 liveuser 9901
 
3 liveuser 9902
			#設置執行錯誤訊息
9903
			$result["error"]=$checkFileKeyStrLBL;
226 liveuser 9904
 
3 liveuser 9905
			#回傳結果
9906
			return $result;
226 liveuser 9907
 
3 liveuser 9908
			}#if end
226 liveuser 9909
 
3 liveuser 9910
		#初始化要加入的設定
9911
		$settingStr=array("LoadModule proxy_module modules/mod_proxy.so","LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so","ProxyPass /wss/chatDemo ws://localhost:8080");
226 liveuser 9912
 
3 liveuser 9913
		#針對每個關鍵字串列
9914
		foreach($checkFileKeyStrLBL["founded"] as $index=>$status){
226 liveuser 9915
 
3 liveuser 9916
			#如果沒有找到符合的設定
9917
			if($status==="true"){
226 liveuser 9918
 
3 liveuser 9919
				#移除要增加到設定檔的變數
9920
				unset($settingStr[$index]);
226 liveuser 9921
 
3 liveuser 9922
				}#if end
226 liveuser 9923
 
9924
			}#foreach end
9925
 
3 liveuser 9926
		#如果有要增加的設定
9927
		if(count($settingStr)>0){
226 liveuser 9928
 
3 liveuser 9929
			#加入設定到 httpd 設定檔裡面
9930
			#函式說明:
9931
			#新增文字內容到檔案裡面
9932
			#回傳結果:
9933
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9934
			#$result["error"],錯誤訊息.
9935
			#$result["function"],當前執行的函數名稱.
9936
			#$result["content"],新增好後的檔案內容.
9937
			#必填的參數:
9938
			#$conf["file"],字串,檔案的位置與名稱.
9939
			$conf["cmd::addTextToFile"]["file"]=$conf["httpd.conf"];
9940
			#$conf["addStr"],陣列字串,要新增的字串內容.
226 liveuser 9941
			$conf["cmd::addTextToFile"]["addStr"]=$settingStr;
3 liveuser 9942
			#可省略參數:
9943
			#$conf["username"],字串,要以哪個使用者來執行,預設為執行該php程式的使用者.
9944
			$conf["cmd::addTextToFile"]["username"]="root";
9945
			#$conf["password"],字串,使用者對應的密碼,預設為"password".
9946
			$conf["cmd::addTextToFile"]["password"]=$conf["rootPasswd"];
9947
			#$conf["fileArgu"],字串,__FILE__的內容,預設為當前檔案的位置.
9948
			$conf["cmd::addTextToFile"]["fileArgu"]=$conf["fileArgu"];
9949
			$addTextToFile=cmd::addTextToFile($conf["cmd::addTextToFile"]);
9950
			unset($conf["cmd::addTextToFile"]);
226 liveuser 9951
 
3 liveuser 9952
			#如果新增內容失敗
9953
			if($addTextToFile["status"]==="false"){
226 liveuser 9954
 
3 liveuser 9955
				#設置執行失敗
9956
				$result["status"]="false";
226 liveuser 9957
 
3 liveuser 9958
				#設置執行錯誤訊息
9959
				$result["error"]=$addTextToFile;
226 liveuser 9960
 
3 liveuser 9961
				#回傳結果
9962
				return $result;
226 liveuser 9963
 
3 liveuser 9964
				}#if end
226 liveuser 9965
 
3 liveuser 9966
			#檢查是否增加成功
9967
			#檢查httpd設定檔案有無設定載入 proxy 模組與設定 ProxyPass
9968
			#函式說明:
9969
			#取得檔的內容並以列為單位搜尋多個關鍵字.
9970
			#回傳結果:
9971
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
9972
			#$result["error"],錯誤訊息.
9973
			#$result["function"],當前執行的函數名稱.
9974
			#$result["content"],取得讀取到的檔案內容.
9975
			#$result["founded"],每個關鍵字串尋找的結果,"true"代表有找到,"false"代表沒有找到.
9976
			#$result["foundedLine"],每個找到的關鍵字是在第幾列找到的,key值與$result["founded"]的key值一樣.
9977
			#必填的參數:
9978
			#$conf["file"],字串,檔案的位置與名稱.
9979
			$conf["cmd::checkFileKeyStrLBL"]["file"]=$conf["httpd.conf"];
9980
			#$conf["keyStr"],陣列字串,要搜尋每列有哪些關鍵字串.
9981
			$conf["cmd::checkFileKeyStrLBL"]["keyStr"]=$settingStr;
9982
			#可省略參數:
9983
			#$conf["username"],字串,要以哪個使用者來執行,預設為執行該php程式的使用者.
9984
			$conf["cmd::checkFileKeyStrLBL"]["username"]="root";
9985
			#$conf["password"],字串,使用者對應的密碼,預設不使用.
9986
			$conf["cmd::checkFileKeyStrLBL"]["password"]=$conf["rootPasswd"];
9987
			#$conf["fileArgu"],字串,__FILE__的內容,預設為當前檔案的位置.
9988
			$conf["cmd::checkFileKeyStrLBL"]["fileArgu"]=$conf["fileArgu"];
9989
			#$conf["tempDir"],字串,暫存資料的目錄位置,預設為".cmd/checkFileKeyStrLBL".
9990
			#$conf["tempDir"]="";
9991
			$checkFileKeyStrLBL=cmd::checkFileKeyStrLBL($conf["cmd::checkFileKeyStrLBL"]);
9992
			unset($conf["cmd::checkFileKeyStrLBL"]);
226 liveuser 9993
 
3 liveuser 9994
			#如果檢查設定值失敗
9995
			if($checkFileKeyStrLBL["status"]==="false"){
226 liveuser 9996
 
3 liveuser 9997
				#設置執行失敗
9998
				$result["status"]="false";
226 liveuser 9999
 
3 liveuser 10000
				#設置執行錯誤訊息
10001
				$result["error"]=$checkFileKeyStrLBL;
226 liveuser 10002
 
3 liveuser 10003
				#回傳結果
10004
				return $result;
226 liveuser 10005
 
3 liveuser 10006
				}#if end
226 liveuser 10007
 
3 liveuser 10008
			#如果沒有找到該有設定字串
10009
			if($checkFileKeyStrLBL["founded"]==="false"){
226 liveuser 10010
 
3 liveuser 10011
				#設置執行失敗
10012
				$result["status"]="false";
226 liveuser 10013
 
3 liveuser 10014
				#設置執行錯誤訊息
10015
				$result["error"]=$checkFileKeyStrLBL;
226 liveuser 10016
 
3 liveuser 10017
				#設置錯誤訊息
10018
				$result["error"][]="寫入設定值失敗";
226 liveuser 10019
 
3 liveuser 10020
				#回傳結果
10021
				return $result;
226 liveuser 10022
 
3 liveuser 10023
				}#if end
226 liveuser 10024
 
3 liveuser 10025
			#重新啟動 httpd 伺服器
10026
			#函式說明:
10027
			#呼叫shell執行系統命令,並取得回傳的內容.
10028
			#回傳的結果:
10029
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
10030
			#$result["error"],錯誤訊息陣列.
10031
			#$result["function"],當前執行的函數名稱.
10032
			#$result["cmd"],執行的指令內容.
10033
			#$result["output"],爲執行完二元碼後的輸出陣列.
10034
			#必填的參數
10035
			#$conf["command"],字串,要執行的指令與.
10036
			$conf["external::callShell"]["command"]="systemctl";
10037
			#$conf["fileArgu"],字串,變數__FILE__的內容.
66 liveuser 10038
			$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
3 liveuser 10039
			#可省略參數:
10040
			#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
10041
			$conf["external::callShell"]["argu"]=array("restart","httpd");
10042
			#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
10043
			#$conf["arguIsAddr"]=array();
10044
			#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
10045
			#$conf["enablePrintDescription"]="true";
10046
			#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.
10047
			#$conf["printDescription"]="";
10048
			#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
10049
			$conf["external::callShell"]["escapeshellarg"]="true";
10050
			#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
10051
			$conf["external::callShell"]["username"]="root";
10052
			#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
10053
			$conf["external::callShell"]["password"]=$conf["rootPasswd"];
10054
			#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要;"false"代表不要,預設為"false".
10055
			#$conf["useScript"]="";
10056
			#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 ".qbpwcf_tmp/external/callShell/".
10057
			#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
10058
			#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
10059
			#$conf["inBackGround"]="";
10060
			#備註:
10061
			#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
10062
			#參考資料:
10063
			#exec=>http://php.net/manual/en/function.exec.php
10064
			#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
10065
			#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
10066
			$callShell=external::callShell($conf["external::callShell"]);
10067
			unset($conf["external::callShell"]);
226 liveuser 10068
 
3 liveuser 10069
			#如果重新啟動apache失敗
10070
			if($callShell["status"]==="false"){
226 liveuser 10071
 
3 liveuser 10072
				#設置執行失敗
10073
				$result["status"]="false";
226 liveuser 10074
 
3 liveuser 10075
				#設置執行錯誤訊息
10076
				$result["error"]=$callShell;
226 liveuser 10077
 
3 liveuser 10078
				#回傳結果
10079
				return $result;
226 liveuser 10080
 
3 liveuser 10081
				}#if end
226 liveuser 10082
 
3 liveuser 10083
			}#if end
226 liveuser 10084
 
3 liveuser 10085
		#設置執行正常
10086
		$result["status"]="true";
226 liveuser 10087
 
3 liveuser 10088
		#回傳結果
10089
		return $result;
226 liveuser 10090
 
3 liveuser 10091
		}#function registerChatDemo end
226 liveuser 10092
 
3 liveuser 10093
	/*
10094
	#函式說明:
10095
	#建立php原生的socket tcp/ip server,提供webSocket server支援.
10096
	#回傳結果:
10097
	#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
10098
	#$result["error"],錯誤訊息陣列.
10099
	#$resutl["function"],當前執行的涵式名稱.
10100
	#$result["argu"],所使用的參數.
10101
	#必填參數:
10102
	#$conf["fileArgu"],字串,變數__FILE__的內容.
10103
	$conf["fileArgu"]=__FILE__;
10104
	#可省略參數:
10105
	#$conf["listenIp"],字串,要接聽的主機ip,預設為本機的ip.
10106
	#$conf["listenIp"]="";
10107
	#$conf["listenPort"],字串,要接聽的port,預設為已使用port+1.
10108
	#$conf["listenPort"]="";
10109
	#$conf["wsMode"],字串,是否要用webSocket模式,預設為"false",不使用,若為"true"則要使用.
10110
	#$conf["wsMode"]="false";
66 liveuser 10111
	#$conf["processFuncs"],陣列,針對收到的訊息要呼叫的函式,會帶入一個參數陣列,array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊),回傳的結果若為陣列$result,其$result["status"]為"true"時,會結束執行(等待下個訊息);為"false"時,會var_dump結果,然後交給下一個函式執行;為"continue"時,代表交給下一個函式執行;預設的數值為array("noAuth");
3 liveuser 10112
	#$conf["processFuncs"]=array();
66 liveuser 10113
	#$conf["idleFunc"],陣列,當沒有收到訊息時,要執行的函式順序,預設不指定.
10114
	#$conf["idleFunc"]=array();
323 liveuser 10115
	#$conf["debug"],字串,"true"代表要輸出debug訊息;反之預設為"false".
10116
	#$conf["debug"]="false";
3 liveuser 10117
	#參考資料:
10118
	#http://php.net/manual/en/sockets.examples.php
10119
	#http://us3.php.net/manual/en/function.socket-select.php
10120
	#response should at least end with "\r"=>http://stackoverflow.com/questions/25739768/websocket-communication-between-chromeclient-and-hotspotserver-status-line
10121
	#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
10122
	#webSocket實做=>http://srchea.com/build-a-real-time-application-using-html5-websockets
10123
	#webSocketServer實做=>http://www.cuelogic.com/blog/php-and-html5-websocket-server-and-client-communication/
10124
	#備註:
10125
	#僅能在命令列執行.
71 liveuser 10126
	#runPhpWhenIdle的功能尚未實作.
3 liveuser 10127
	*/
10128
	public static function nativeSocketTcpIpServer(&$conf){
226 liveuser 10129
 
3 liveuser 10130
		#初始化要回傳的結果
10131
		$result=array();
10132
 
10133
		#取得當前執行的函數名稱
10134
		$result["function"]=__FUNCTION__;
10135
 
10136
		#涵式說明:
10137
		#判斷當前環境為web還是cmd
10138
		#回傳結果:
10139
		#$result,"web"或"cmd"
10140
		if(csInformation::getEnv()==="web"){
226 liveuser 10141
 
3 liveuser 10142
			#設置執行失敗
10143
			$result["status"]="false";
226 liveuser 10144
 
3 liveuser 10145
			#設置執行錯誤訊息
10146
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 10147
 
3 liveuser 10148
			#回傳結果
10149
			return $result;
226 liveuser 10150
 
3 liveuser 10151
			}#if end
10152
 
10153
		#取得參數
10154
		$result["argu"]=$conf;
10155
 
10156
		#如果 $conf 不為陣列
10157
		if(gettype($conf)!="array"){
226 liveuser 10158
 
3 liveuser 10159
			#設置執行失敗
10160
			$result["status"]="false";
226 liveuser 10161
 
3 liveuser 10162
			#設置執行錯誤訊息
10163
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 10164
 
3 liveuser 10165
			#如果傳入的參數為 null
10166
			if($conf==null){
226 liveuser 10167
 
3 liveuser 10168
				#設置執行錯誤訊息
10169
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 10170
 
3 liveuser 10171
				}#if end
10172
 
10173
			#回傳結果
10174
			return $result;
226 liveuser 10175
 
3 liveuser 10176
			}#if end
226 liveuser 10177
 
3 liveuser 10178
		#檢查參數
10179
		#函式說明:
10180
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
10181
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
10182
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
10183
		#$result["function"],當前執行的函式名稱.
10184
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
10185
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
10186
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
10187
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
10188
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
10189
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
10190
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
10191
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
10192
		#必填寫的參數:
10193
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
10194
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
10195
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
10196
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu");
10197
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
10198
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
10199
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
10200
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
10201
		#可以省略的參數:
10202
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
10203
		#$conf["canBeEmptyString"]="false";
10204
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
10205
		#$conf["canNotBeEmpty"]=array();
10206
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
10207
		#$conf["canBeEmpty"]=array();
10208
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
10209
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
10210
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
323 liveuser 10211
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("listenIp","listenPort","wsMode","processFuncs","idleFunc","debug");
226 liveuser 10212
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
323 liveuser 10213
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","array","array","string");
3 liveuser 10214
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
323 liveuser 10215
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("127.0.0.1",null,"false",array("\qbpwcf\webSock::talk2someoneOnce","\qbpwcf\webSock::talk2everyoneOnce"),array(),"false");
3 liveuser 10216
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
10217
		#$conf["arrayCountEqualCheck"][]=array();
10218
		#參考資料來源:
10219
		#array_keys=>http://php.net/manual/en/function.array-keys.php
10220
		#建議:
10221
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
10222
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
10223
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 10224
 
3 liveuser 10225
		#如果檢查參數失敗
10226
		if($checkArguments["status"]==="false"){
226 liveuser 10227
 
3 liveuser 10228
			#設置執行失敗
10229
			$result["status"]="false";
226 liveuser 10230
 
3 liveuser 10231
			#設置執行錯誤訊息
10232
			$result["error"]=$checkArguments;
226 liveuser 10233
 
3 liveuser 10234
			#回傳結果
10235
			return $result;
226 liveuser 10236
 
3 liveuser 10237
			}#if end
226 liveuser 10238
 
3 liveuser 10239
		#如果檢查參數不通過
10240
		if($checkArguments["passed"]==="false"){
226 liveuser 10241
 
3 liveuser 10242
			#設置執行失敗
10243
			$result["status"]="false";
226 liveuser 10244
 
3 liveuser 10245
			#設置執行錯誤訊息
10246
			$result["error"]=$checkArguments;
226 liveuser 10247
 
3 liveuser 10248
			#回傳結果
10249
			return $result;
226 liveuser 10250
 
66 liveuser 10251
			}#if end
226 liveuser 10252
 
3 liveuser 10253
		#如果 $conf["listenPort"] 不存在
10254
		if(!isset($conf["listenPort"])){
226 liveuser 10255
 
3 liveuser 10256
			#用nmap掃port
10257
			#函式說明:
10258
			#掃port的程式
10259
			#回傳結果:
10260
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
10261
			#$result["error"],錯誤訊息.
10262
			#$result["function"],當前執行的函數名稱.
10263
			#$result["argu"],使用的參數.
10264
			#$result["content"],掃好可能可以使用的port資訊.
10265
			#必填參數
10266
			#無:
10267
			#可省略參數:
10268
			#$conf["target"],字串,要掃描的主機,預設為"127.0.0.1",
10269
			$conf["cmd::nmap"]["target"]=$conf["listenIp"];
10270
			#$conf["-Pn"],字串,是否要啟用避免ping不到就會掃port失敗的功能,預設為"false".
10271
			#$conf["-Pn"]="false";
10272
			$nmap=cmd::nmap($conf["cmd::nmap"]);
10273
			unset($conf["cmd::nmap"]);
226 liveuser 10274
 
3 liveuser 10275
			#如果掃port失敗
10276
			if($nmap["status"]==="false"){
226 liveuser 10277
 
3 liveuser 10278
				#設置執行失敗
10279
				$result["status"]="false";
226 liveuser 10280
 
3 liveuser 10281
				#設置執行錯誤訊息
10282
				$result["error"]=$nmap;
226 liveuser 10283
 
3 liveuser 10284
				#回傳結果
10285
				return $result;
226 liveuser 10286
 
3 liveuser 10287
				}#if end
226 liveuser 10288
 
3 liveuser 10289
			#如果有掃到port
10290
			if(count($nmap["content"])>0){
226 liveuser 10291
 
3 liveuser 10292
				#找最大的port
10293
				#涵式說明:
10294
				#找最大值,結果會回傳最大值.
10295
				#回傳的結果:
10296
				#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
10297
				#$result["error"],錯誤訊息陣列.
10298
				#$result["function"],當前執行的函數名稱.
10299
				#$result["key"],最大值原先的key.
10300
				#$result["value"],最大值的數字.
10301
				#必填的參數:
10302
				$conf["math::getMaxValue"]["rawDataArray"]=$nmap["content"];#爲原始數據
10303
				$getMaxValue=math::getMaxValue($conf["math::getMaxValue"]);
10304
				unset($conf["math::getMaxValue"]);
226 liveuser 10305
 
3 liveuser 10306
				#如果找最大port失敗
10307
				if($getMaxValue["status"]==="false"){
226 liveuser 10308
 
3 liveuser 10309
					#設置執行失敗
10310
					$result["status"]="false";
226 liveuser 10311
 
3 liveuser 10312
					#設置執行錯誤訊息
10313
					$result["error"]=$getMaxValue;
226 liveuser 10314
 
3 liveuser 10315
					#回傳結果
10316
					return $result;
226 liveuser 10317
 
3 liveuser 10318
					}#if end
226 liveuser 10319
 
3 liveuser 10320
				#設置 $conf["listenPort"] 為最大 port+1
10321
				$conf["listenPort"]=$getMaxValue["value"]+1;
226 liveuser 10322
 
3 liveuser 10323
				#如果port小於4000,會無法讓nmap偵測到有使用
10324
				if($conf["listenPort"]<4000){
226 liveuser 10325
 
3 liveuser 10326
					#設為4000
10327
					$conf["listenPort"]="4000";
226 liveuser 10328
 
3 liveuser 10329
					}#if end
226 liveuser 10330
 
66 liveuser 10331
				}#if end
226 liveuser 10332
 
3 liveuser 10333
			}#if end
226 liveuser 10334
 
3 liveuser 10335
		#反之
10336
		else{
226 liveuser 10337
 
3 liveuser 10338
			#用nmap掃port
10339
			#函式說明:
10340
			#掃port的程式
10341
			#回傳結果:
10342
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
10343
			#$result["error"],錯誤訊息.
10344
			#$result["function"],當前執行的函數名稱.
10345
			#$result["argu"],使用的參數.
10346
			#$result["content"],掃好可能可以使用的port資訊.
10347
			#必填參數
10348
			#無:
10349
			#可省略參數:
10350
			#$conf["target"],字串,要掃描的主機,預設為"127.0.0.1",
10351
			$conf["cmd::nmap"]["target"]=$conf["listenIp"];
10352
			#$conf["-Pn"],字串,是否要啟用避免ping不到就會掃port失敗的功能,預設為"false".
10353
			#$conf["-Pn"]="false";
10354
			#$conf["fileArgu"],字串,變數__FILE__的內容.
10355
			$conf["cmd::nmap"]["fileArgu"]=$conf["fileArgu"];
10356
			$nmap=cmd::nmap($conf["cmd::nmap"]);
10357
			unset($conf["cmd::nmap"]);
226 liveuser 10358
 
3 liveuser 10359
			#如果掃port失敗
10360
			if($nmap["status"]==="false"){
226 liveuser 10361
 
3 liveuser 10362
				#設置執行失敗
10363
				$result["status"]="false";
226 liveuser 10364
 
3 liveuser 10365
				#設置執行錯誤訊息
10366
				$result["error"]=$nmap;
226 liveuser 10367
 
3 liveuser 10368
				#回傳結果
10369
				return $result;
226 liveuser 10370
 
3 liveuser 10371
				}#if end
226 liveuser 10372
 
3 liveuser 10373
			#如果有掃到port
10374
			if(count($nmap["content"])>0){
226 liveuser 10375
 
3 liveuser 10376
				#如果要用來建立socket的port已被使用
10377
				if(in_array($conf["listenPort"],$nmap["content"])){
226 liveuser 10378
 
3 liveuser 10379
					#找最大的port
10380
					#涵式說明:
10381
					#找最大值,結果會回傳最大值.
10382
					#回傳的結果:
10383
					#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
10384
					#$result["error"],錯誤訊息陣列.
10385
					#$result["function"],當前執行的函數名稱.
10386
					#$result["key"],最大值原先的key.
10387
					#$result["value"],最大值的數字.
10388
					#必填的參數:
10389
					$conf["math::getMaxValue"]["rawDataArray"]=$nmap["content"];#爲原始數據
10390
					$getMaxValue=math::getMaxValue($conf["math::getMaxValue"]);
10391
					unset($conf["math::getMaxValue"]);
226 liveuser 10392
 
3 liveuser 10393
					#如果找最大port失敗
10394
					if($getMaxValue["status"]==="false"){
226 liveuser 10395
 
3 liveuser 10396
						#設置執行失敗
10397
						$result["status"]="false";
226 liveuser 10398
 
3 liveuser 10399
						#設置執行錯誤訊息
10400
						$result["error"]=$getMaxValue;
226 liveuser 10401
 
3 liveuser 10402
						#回傳結果
10403
						return $result;
226 liveuser 10404
 
3 liveuser 10405
						}#if end
226 liveuser 10406
 
3 liveuser 10407
					#設置 $conf["listenPort"] 為最大 port+1
10408
					$conf["listenPort"]=$getMaxValue["value"]+1;
226 liveuser 10409
 
3 liveuser 10410
					#如果port小於4000,會無法讓nmap偵測到有使用
10411
					if($conf["listenPort"]<4000){
226 liveuser 10412
 
3 liveuser 10413
						#設為4000
10414
						$conf["listenPort"]="4000";
226 liveuser 10415
 
3 liveuser 10416
						}#if end
226 liveuser 10417
 
3 liveuser 10418
					}#if end
226 liveuser 10419
 
3 liveuser 10420
				}#if end
226 liveuser 10421
 
3 liveuser 10422
			}#else end
226 liveuser 10423
 
3 liveuser 10424
		#回報任何錯誤
10425
		#error_reporting(E_ALL);
10426
 
10427
		/* Allow the script to hang around waiting for connections. */
10428
		set_time_limit(0);
10429
 
10430
		/* Turn on implicit output flushing so we see what we're getting as it comes in. */
10431
		#ob_implicit_flush();
10432
 
10433
		#設定要listen的主機ip
10434
		$address = $conf["listenIp"];
226 liveuser 10435
 
3 liveuser 10436
		#設定要listen的port
10437
		$port = $conf["listenPort"];
10438
 
10439
		#重複做,讓socket服務不會結束.
10440
		do{
226 liveuser 10441
 
3 liveuser 10442
			#如果建立 socket 失敗
10443
			if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false){
226 liveuser 10444
 
323 liveuser 10445
				#設置執行失敗
10446
				$result["status"]="false";
226 liveuser 10447
 
323 liveuser 10448
				#設置執行錯誤訊息
10449
				$result["error"]="socket_create() failed: reason: " . socket_strerror(socket_last_error());
10450
 
10451
				#回傳結果
10452
				return $result;
10453
 
3 liveuser 10454
				}#if end
226 liveuser 10455
 
3 liveuser 10456
			#設置不等待連線與訊息的到來,變成不會卡位
10457
			socket_set_nonblock($sock);
226 liveuser 10458
 
3 liveuser 10459
			#SOL_SOCKET => socket level
226 liveuser 10460
			#SO_REUSEADDR => Reports whether local addresses can be reused.
3 liveuser 10461
			socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
226 liveuser 10462
 
3 liveuser 10463
			#如果 Binds a name to a socket 失敗
10464
			if (@socket_bind($sock, $address, $port) === false){
226 liveuser 10465
 
3 liveuser 10466
				#儲存錯誤訊息
10467
				$error=socket_strerror(socket_last_error($sock));
226 liveuser 10468
 
3 liveuser 10469
				#印出錯誤訊息
10470
				echo "socket_bind() failed: reason: " .$error. PHP_EOL;
226 liveuser 10471
 
3 liveuser 10472
				#判斷錯誤訊息的是否有 "Address already in use"
10473
				#函式說明:
10474
				#檢查字串裡面有無指定的關鍵字
10475
				#回傳的結果:
10476
				#$result["status"],"true"代表執行成功,"false"代表執行失敗。
10477
				#$result["error"],錯誤訊息
10478
				#$result["function"],當前執行的函數名稱.
10479
				#$result["founded"],是否找到關鍵字,"true"代表有找到關鍵字;"false"代表沒有找到關鍵字。
10480
				#$result["keyWordCount"],找到的關鍵字數量.
10481
				#必填的參數:
10482
				$conf["search::findKeyWord"]["keyWord"]="Address already in use";#想要搜尋的關鍵字
10483
				$conf["search::findKeyWord"]["string"]=$error;#要被搜尋的字串內容
10484
				#可省略的參數:
10485
				#$conf["completeEqual"]="true";#是否內容要完全符合,不能多出任何不符合的內容,預設為不需要完全符合。
10486
				$findKeyWord=search::findKeyWord($conf["search::findKeyWord"]);
10487
				unset($conf["search::findKeyWord"]);
226 liveuser 10488
 
3 liveuser 10489
				#如果解析錯誤訊息失敗
10490
				if($findKeyWord["status"]==="false"){
226 liveuser 10491
 
3 liveuser 10492
					#設置執行失敗
10493
					$result["status"]="false";
226 liveuser 10494
 
3 liveuser 10495
					#設置執行錯誤訊息
10496
					$result["error"]=$getMeetConditionsString;
226 liveuser 10497
 
3 liveuser 10498
					#回傳結果
10499
					return $result;
226 liveuser 10500
 
3 liveuser 10501
					}#if end
226 liveuser 10502
 
3 liveuser 10503
				#如果錯誤原因為socket的port已經被使用了.
10504
				if($findKeyWord["founded"]==="true"){
226 liveuser 10505
 
3 liveuser 10506
					#port加1
10507
					$port++;
226 liveuser 10508
 
3 liveuser 10509
					#再次建立socket服務
10510
					continue;
226 liveuser 10511
 
3 liveuser 10512
					}#if end
226 liveuser 10513
 
3 liveuser 10514
				#反之
10515
				else{
226 liveuser 10516
 
323 liveuser 10517
					#設置執行失敗
10518
					$result["status"]="false";
226 liveuser 10519
 
323 liveuser 10520
					#設置執行錯誤訊息
10521
					$result["error"]="socket_bind() failed: reason: " .$error;
10522
 
10523
					#回傳結果
10524
					return $result;
10525
 
226 liveuser 10526
					}#else
10527
 
3 liveuser 10528
				}#if end
10529
 
10530
			#如果 listen socket 經過嘗試5次後仍然失敗
10531
			if (socket_listen($sock, 5) === false) {
226 liveuser 10532
 
323 liveuser 10533
				#設置執行失敗
10534
				$result["status"]="false";
226 liveuser 10535
 
323 liveuser 10536
				#設置執行錯誤訊息
10537
				$result["error"]="socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock));
10538
 
10539
				#回傳結果
10540
				return $result;
10541
 
3 liveuser 10542
				}#if end
10543
 
10544
			#初始化儲存已經連線到 socket service 的服務
10545
			$connections=array();
10546
 
66 liveuser 10547
			#初始化 idle 時要呼叫的函式名稱陣列
10548
			$idleFunc=array();
10549
 
323 liveuser 10550
			#如果要 debug
10551
			if($conf["debug"]==="true"){
3 liveuser 10552
 
323 liveuser 10553
				#提示 listen 的 ip 與 port
10554
				echo "Listen to:".$address.":".$port.PHP_EOL;
10555
 
10556
				}#if end
10557
 
3 liveuser 10558
			#重複做,等待別人連線.
10559
			do{
226 liveuser 10560
 
3 liveuser 10561
				#初始化儲存有需要處理的socket連線
10562
				$read = array();
226 liveuser 10563
 
3 liveuser 10564
				#初始化一開始建立的socket為要處理的項目
10565
				$read[] = $sock;
226 liveuser 10566
 
3 liveuser 10567
				#有幾個連線就執行幾次
10568
				foreach($connections as $conForSockSelect){
226 liveuser 10569
 
3 liveuser 10570
					#產生要合併的陣列
10571
					$arrayToMerage=array($conForSockSelect["connect"]);
226 liveuser 10572
 
3 liveuser 10573
					#合併陣列
10574
					$read = array_merge($read,$arrayToMerage);
226 liveuser 10575
 
3 liveuser 10576
					}#foreach end
226 liveuser 10577
 
3 liveuser 10578
				#從socket物件陣列($read)裡面取出有需要處理連線的socket物件.
10579
				#Set up a blocking call to socket_select
10580
				$write=array();
10581
				$except=array();
10582
				$tv_sec = 1;
10583
				if(socket_select($read, $write, $except, $tv_sec) < 1){
226 liveuser 10584
 
323 liveuser 10585
					#如果要 debug
10586
					if($conf["debug"]==="true"){
10587
 
10588
						#沒有事情發生
10589
						echo ".";
10590
 
10591
						}#if end
226 liveuser 10592
 
3 liveuser 10593
					#函式說明:
226 liveuser 10594
					#加密 handshake 後要傳送的訊息
3 liveuser 10595
					#回傳結果:
10596
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
10597
					#$result["error"],執行不正常結束的錯訊息陣列.
10598
					#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
10599
					#$result["argu"],陣列,使用的參數.
10600
					#必填參數:
10601
					#$conf["text"],字串,要加密的訊息.
226 liveuser 10602
					$conf["webSock::encode"]["text"]="";
3 liveuser 10603
					#可省略參數:
10604
					#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
10605
					$conf["webSock::encode"]["ping"]="true";
10606
					#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
10607
					#$conf["frames"]=array();
10608
					#參考資料:
10609
					#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
10610
					#備註:
10611
					#無.
10612
					$encode=webSock::encode($conf["webSock::encode"]);
10613
					unset($conf["webSock::encode"]);
226 liveuser 10614
 
3 liveuser 10615
					#debug
10616
					#var_dump(__LINE__,$encode);
226 liveuser 10617
 
3 liveuser 10618
					#如果執行失敗
10619
					if($encode["status"]==="false"){
226 liveuser 10620
 
3 liveuser 10621
						#設置執行失敗
10622
						$result["status"]="false";
226 liveuser 10623
 
3 liveuser 10624
						#設置執行錯誤訊息
10625
						$result["error"]=$encode;
226 liveuser 10626
 
3 liveuser 10627
						#回傳結果
10628
						return $result;
226 liveuser 10629
 
3 liveuser 10630
						}#if end
226 liveuser 10631
 
3 liveuser 10632
					#針對每個連線的 client
10633
					foreach($connections as $client){
226 liveuser 10634
 
3 liveuser 10635
						#如果有 last ping time
10636
						if(isset($client["lastPongTime"])){
226 liveuser 10637
 
3 liveuser 10638
							#如果小於5秒沒有收到pong
10639
							if(time()-$client["lastPongTime"]<5){
226 liveuser 10640
 
66 liveuser 10641
								#看下一個連線,亦即視為用戶已經斷線.
3 liveuser 10642
								continue;
226 liveuser 10643
 
3 liveuser 10644
								}#if end
226 liveuser 10645
 
3 liveuser 10646
							}#if end
226 liveuser 10647
 
3 liveuser 10648
						#取得用戶socket
10649
						$clientSock=$client["connect"];
226 liveuser 10650
 
3 liveuser 10651
						#傳送ping給client
10652
						$socket_write=socket_write($clientSock, $encode["content"][0], strlen($encode["content"][0]));
226 liveuser 10653
 
3 liveuser 10654
						#debug
10655
						#var_dump(__LINE__,"send ping",$socket_write,socket_strerror(socket_last_error($clientSock)));
226 liveuser 10656
 
3 liveuser 10657
						}#foreach end
226 liveuser 10658
 
66 liveuser 10659
					#如果有idle時要做的事情
10660
					if(count($conf["idleFunc"])>0){
226 liveuser 10661
 
66 liveuser 10662
						#取得idleFunc設定
10663
						$idleFunc=$conf["idleFunc"];
226 liveuser 10664
 
66 liveuser 10665
						#移除初始的idelFunc設定
10666
						unset($conf["idleFunc"]);
226 liveuser 10667
 
66 liveuser 10668
						}#if end
226 liveuser 10669
 
66 liveuser 10670
					#如果有idle時要做的事情
10671
					if(count($idleFunc)>0){
226 liveuser 10672
 
66 liveuser 10673
						#針對每個要執行的函式
10674
						foreach($idleFunc as $if){
226 liveuser 10675
 
66 liveuser 10676
							#設置要給予函式的參數陣列
10677
							$param=array("idleFunc"=>&$idleFunc,"serverSock"=>&$sock,"allConn"=>&$connections);
226 liveuser 10678
 
66 liveuser 10679
							#初始化給予 call_user_func_array 的第2個參數
10680
							$params=array();
226 liveuser 10681
 
66 liveuser 10682
							#設置呼叫函式 $if 時要傳遞的參數為一個 $param
10683
							$params[]=&$param;
226 liveuser 10684
 
66 liveuser 10685
							#呼叫函式 $if 與要傳遞的參數.
10686
							$result=call_user_func_array($if,$params);
226 liveuser 10687
 
66 liveuser 10688
							}#foreach end
226 liveuser 10689
 
66 liveuser 10690
						}#if end
226 liveuser 10691
 
71 liveuser 10692
					#如果有 $php2runWhenIdle
10693
					if(isset($php2runWhenIdle)){
226 liveuser 10694
 
71 liveuser 10695
						#如果有php程式要於idle時執行
10696
						while(count($php2runWhenIdle)>0){
226 liveuser 10697
 
71 liveuser 10698
							#取得要執行的 php code
10699
							$phpCode=array_shift($php2runWhenIdle);
226 liveuser 10700
 
323 liveuser 10701
							#如果要 debug
10702
							if($conf["debug"]==="true"){
10703
 
10704
								echo "尚未實作運行php code的功能".PHP_EOL;
10705
 
10706
								}#if end
10707
 
71 liveuser 10708
							#...
226 liveuser 10709
 
71 liveuser 10710
							}#while end
226 liveuser 10711
 
71 liveuser 10712
						}#if end
226 liveuser 10713
 
3 liveuser 10714
					#下一輪
10715
					continue;
226 liveuser 10716
 
3 liveuser 10717
					}#if end
226 liveuser 10718
 
323 liveuser 10719
				#如果要 debug
10720
				if($conf["debug"]==="true"){
226 liveuser 10721
 
323 liveuser 10722
					#有事情發生
10723
					echo "something happen".PHP_EOL;
10724
 
10725
					}#if end
10726
 
3 liveuser 10727
				#如果有socket要處理
10728
				if(in_array($sock,$read)){
226 liveuser 10729
 
3 liveuser 10730
					#如果有接收到 socket 連線
10731
					if (($msgsock = socket_accept($sock)) !== false) {
226 liveuser 10732
 
3 liveuser 10733
						#初始化不是既有的 sock
10734
						$existSock=false;
226 liveuser 10735
 
3 liveuser 10736
						#尋找是哪個 socket
10737
						for($i=0;$i<count($connections);$i++){
226 liveuser 10738
 
3 liveuser 10739
							#如果是既有的 sock
10740
							if($connections[$i]["connect"]===$msgsock){
226 liveuser 10741
 
3 liveuser 10742
								#設置是既有的 sock
10743
								$existSock=true;
226 liveuser 10744
 
3 liveuser 10745
								}#if end
226 liveuser 10746
 
3 liveuser 10747
							}#for end
226 liveuser 10748
 
3 liveuser 10749
						#如果該 socket 是新的
10750
						if(!$existSock){
226 liveuser 10751
 
323 liveuser 10752
							#如果要 debug
10753
							if($conf["debug"]==="true"){
10754
 
10755
								#提示有新的連線近來
10756
								echo "Receviced new connection".PHP_EOL;
10757
 
10758
								}#if end
10759
 
3 liveuser 10760
							#重複做
10761
							do{
226 liveuser 10762
 
3 liveuser 10763
								#亂數產生連線id
10764
								#涵式說明:
10765
								#建立以圖片(PNG格式)呈現的驗證碼.
10766
								#回傳的解果:
10767
								#$result["status"],執行是否正常,"true"代表執行成功,"false"代表執行失敗.
10768
								#$result["error"],錯誤訊息.
10769
								#$result["function"],檔前執行的函數名稱.
10770
								#$result["randNumberWord"],傳驗證碼的內容.
10771
								#$result["imgAddress"],圖片的位置與名稱.
10772
								#必填的參數:
10773
								#$conf["imgAddressAndName"],字串,爲驗證碼圖片儲存的位置與名稱,副檔名程式會自動產生
10774
								$conf["authenticate::validationCode"]["imgAddressAndName"]="no used!";
10775
								#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
10776
								$conf["authenticate::validationCode"]["fileArgu"]=$conf["fileArgu"];
10777
								#可省略的參數:
10778
								#$conf["num"],字串,爲驗證碼的位數,請輸入阿拉伯數字,預設為"8"位數.
10779
								#$conf["num"]="8";
10780
								#$conf["disableImg"],字串,是否要取消驗證碼圖片的輸出,"true"為要取消,預設為"false"為不取消
10781
								$conf["authenticate::validationCode"]["disableImg"]="true";
10782
								#$conf["imgToData"],字串,預設為"true"代表將圖片轉存成base64圖片,並將原始圖片移除;反之為"false"
10783
								#$conf["authenticate::validationCode"]["imgToData"]="true";
10784
								$validationCode=authenticate::validationCode($conf["authenticate::validationCode"]);
10785
								unset($conf["authenticate::validationCode"]);
226 liveuser 10786
 
3 liveuser 10787
								#如果產生亂數失敗
10788
								if($validationCode["status"]==="false"){
226 liveuser 10789
 
3 liveuser 10790
									#設置執行失敗
10791
									$result["status"]="false";
226 liveuser 10792
 
3 liveuser 10793
									#設置執行錯誤訊息
10794
									$result["error"]=$validationCode;
226 liveuser 10795
 
3 liveuser 10796
									#回傳結果
10797
									return $result;
226 liveuser 10798
 
3 liveuser 10799
									}#if end
226 liveuser 10800
 
3 liveuser 10801
								#如果不存在既有的連線資訊
10802
								if(count($connections)<1){
226 liveuser 10803
 
3 liveuser 10804
									#跳出迴圈
10805
									break;
226 liveuser 10806
 
3 liveuser 10807
									}#if end
226 liveuser 10808
 
3 liveuser 10809
								#初始化連線id的陣列
10810
								$idArray=array();
226 liveuser 10811
 
3 liveuser 10812
								#針對既有的連線
10813
								foreach($connections as $exist_conn){
226 liveuser 10814
 
3 liveuser 10815
									#儲存連線id
10816
									$idArray[]=$exist_conn["id"];
226 liveuser 10817
 
3 liveuser 10818
									}#foreach end
226 liveuser 10819
 
3 liveuser 10820
								}#do end
226 liveuser 10821
 
3 liveuser 10822
							#檢查id有無重複
10823
							while(in_array($validationCode["randNumberWord"],$idArray));
226 liveuser 10824
 
66 liveuser 10825
							#如果不是 ws 模式
3 liveuser 10826
							if($conf["wsMode"]==="false"){
226 liveuser 10827
 
3 liveuser 10828
								#儲存連線到陣列裡面
10829
								$connections[]=array("connect"=>$msgsock,"buf"=>"","id"=>$validationCode["randNumberWord"],"talkTo"=>array());
226 liveuser 10830
 
3 liveuser 10831
								}#if end
226 liveuser 10832
 
3 liveuser 10833
							#如果是 ws 模式
10834
							if($conf["wsMode"]==="true"){
226 liveuser 10835
 
3 liveuser 10836
								#儲存連線到陣列裡面
10837
								$connections[]=array("connect"=>$msgsock,"buf"=>"","id"=>$validationCode["randNumberWord"],"talkTo"=>array(),"handshaked"=>"false","unmask"=>"false","userAgent"=>"false","3rn"=>0,"receivedMsgFromServer"=>array());
226 liveuser 10838
 
3 liveuser 10839
								}#if end
226 liveuser 10840
 
323 liveuser 10841
							#如果要 debug
10842
							if($conf["debug"]==="true"){
10843
 
10844
								#提示 Server 給予的新 Id
10845
								echo "new connection(".$validationCode["randNumberWord"]."):".PHP_EOL;
10846
 
10847
								}#if end
10848
 
3 liveuser 10849
							#初始化連線後要回傳的訊息
10850
							$msg="";
226 liveuser 10851
 
3 liveuser 10852
							#如果不是 ws 模式
10853
							if($conf["wsMode"]!=="true"){
226 liveuser 10854
 
3 liveuser 10855
								#提示client連上線後得到的訊息
10856
								$msg = $msg.PHP_EOL."Welcome to the PHP Test Server.".PHP_EOL;
10857
								$msg = $msg."To quit, type 'quit'. To shut down the server type 'shutdown'.".PHP_EOL;
10858
								socket_write($msgsock, $msg, strlen($msg));
226 liveuser 10859
 
3 liveuser 10860
								}#if end
226 liveuser 10861
 
3 liveuser 10862
							}#if end
226 liveuser 10863
 
3 liveuser 10864
						}#if end
226 liveuser 10865
 
3 liveuser 10866
					}#if end
226 liveuser 10867
 
3 liveuser 10868
				#重新排序 $connections
10869
				#函式說明:
10870
				#將陣列的key重新排序,然後回傳,以便後續存取,也可以指定key的內容,但一定要跟元素數量相同。
10871
				#回傳的解果:
10872
				#$result["status"],執行是否成功,"true"代表成功,"false"代表失敗.
10873
				#$result["error"],執行錯誤的訊息.
10874
				#$result["function"],當前執行的函數名稱.
10875
				#$result["dataContent"],儲存陣列元素的內容.
10876
				#若指定了key的名稱,則 $result["dataContent"] 會變成 $result["dataContent"]["指定的key名稱"]
10877
				#$result["dataCount"],儲存陣列元素的數量。
10878
				#必填的參數:
10879
				$conf["arrays::createV2"]["arrayContent"]=$connections;#陣列變數
10880
				#可省略的參數:
10881
				#$conf["specifiesKeyArray"]=array();#指定key的名稱,須與$conf["arrayContent"]的元素數量相同
10882
				$createV2=arrays::createV2($conf["arrays::createV2"]);
10883
				unset($conf["arrays::createV2"]);
226 liveuser 10884
 
3 liveuser 10885
				#如果重新排序失敗
10886
				if($createV2["status"]==="false"){
226 liveuser 10887
 
3 liveuser 10888
					#設置執行失敗
10889
					$result["status"]="false";
226 liveuser 10890
 
3 liveuser 10891
					#設置執行錯誤訊息
10892
					$result["error"]=$createV2;
226 liveuser 10893
 
3 liveuser 10894
					#回傳結果
10895
					return $result;
226 liveuser 10896
 
3 liveuser 10897
					}#if end
226 liveuser 10898
 
3 liveuser 10899
				#取得重新排序好的陣列
10900
				$connections=$createV2["dataContent"];
323 liveuser 10901
 
10902
				#如果要 debug
10903
				if($conf["debug"]==="true"){
10904
 
10905
					#提示訊息
10906
					echo "目前的連線清單:".PHP_EOL;
10907
 
10908
					#debug
10909
					var_dump($connections);
10910
 
10911
					}#if end
226 liveuser 10912
 
3 liveuser 10913
				#依據每個 client 的連線
10914
				foreach($connections as $conIndex => $con){
226 liveuser 10915
 
3 liveuser 10916
					#如果有要處理的socket連線項目
10917
					if(in_array($con["connect"], $read)){
226 liveuser 10918
 
3 liveuser 10919
						#如果不存在 handshaked
10920
						if(!isset($con["handshaked"])){
226 liveuser 10921
 
3 liveuser 10922
							#預設為 "false"
10923
							$con["handshaked"]="false";
226 liveuser 10924
 
3 liveuser 10925
							}#if end
226 liveuser 10926
 
3 liveuser 10927
						#如果有 handshaked
10928
						if($con["handshaked"]==="true"){
226 liveuser 10929
 
66 liveuser 10930
							#讀取內容
3 liveuser 10931
							$buf = @socket_read($con["connect"], 2048, PHP_BINARY_READ);
226 liveuser 10932
 
3 liveuser 10933
							#設置要 unmask
10934
							$connections[$conIndex]["unmask"]="true";
226 liveuser 10935
 
66 liveuser 10936
							#設置尚未 auth
316 liveuser 10937
							$connections[$conIndex]["auth"]=false;
226 liveuser 10938
 
323 liveuser 10939
							#初始化儲存要傳遞的訊息
10940
							$connections[$conIndex]["msg"]=array();
10941
 
10942
							#初始化儲存要廣播的訊息
10943
							$connections[$conIndex]["broadMsg"]=array();
10944
 
324 liveuser 10945
							#初始化儲存尚未處理收到的非完整訊息
10946
							$connections[$conIndex]["buf"]=array();
10947
 
323 liveuser 10948
							#如果要 debug
10949
							if($conf["debug"]==="true"){
10950
 
10951
								#提示訊息
10952
								echo "Connection(".$connections[$conIndex]["id"].") handshaked.".PHP_EOL;
10953
 
10954
								}#if end
10955
 
3 liveuser 10956
							}#if end
226 liveuser 10957
 
3 liveuser 10958
						#反之
10959
						else{
226 liveuser 10960
 
3 liveuser 10961
							#讀取內容
10962
							$buf = @socket_read($con["connect"], 2048, PHP_NORMAL_READ);
226 liveuser 10963
 
3 liveuser 10964
							}#else end
226 liveuser 10965
 
3 liveuser 10966
						#如果讀取出錯
10967
						if($buf===false){
226 liveuser 10968
 
3 liveuser 10969
							#印出錯誤訊息
10970
							echo "socket_recv() failed: reason: " . socket_strerror(socket_last_error($con["connect"])) . PHP_EOL;
226 liveuser 10971
 
3 liveuser 10972
							#移除該連線的資料
226 liveuser 10973
							unset($connections[$conIndex]);
10974
 
3 liveuser 10975
							#跳到下一輪
10976
							continue;
226 liveuser 10977
 
3 liveuser 10978
							}#if end
226 liveuser 10979
 
3 liveuser 10980
						#如果收到的資料長度為 0 bytes
10981
						if($buf===""){
226 liveuser 10982
 
3 liveuser 10983
							#關閉 socket msg
226 liveuser 10984
							socket_close($con["connect"]);
10985
 
3 liveuser 10986
							#移除該連線的資料
10987
							unset($connections[$conIndex]);
226 liveuser 10988
 
3 liveuser 10989
							#跳到下一輪
10990
							continue;
226 liveuser 10991
 
3 liveuser 10992
							}#if end
226 liveuser 10993
 
323 liveuser 10994
						#印出收到非換行符號的內容
3 liveuser 10995
						if($buf!==PHP_EOL){
226 liveuser 10996
 
323 liveuser 10997
							#如果要 debug
10998
							if($conf["debug"]==="true"){
10999
 
11000
								#debug
11001
								echo "received:".$buf.PHP_EOL;
11002
 
11003
								}#if end
226 liveuser 11004
 
3 liveuser 11005
							}#if end
226 liveuser 11006
 
3 liveuser 11007
						#如果無 handshaked
11008
						if($con["handshaked"]!=="true"){
226 liveuser 11009
 
3 liveuser 11010
							#清除換行字元
11011
							$buf=trim($buf);
226 liveuser 11012
 
3 liveuser 11013
							}#if end
226 liveuser 11014
 
3 liveuser 11015
						#web socket mode
11016
						if($conf["wsMode"]==="true"){
226 liveuser 11017
 
3 liveuser 11018
							#如果不需要 unmask
11019
							if($connections[$conIndex]["unmask"]==="false"){
226 liveuser 11020
 
323 liveuser 11021
								#如果要 debug
11022
								if($conf["debug"]==="true"){
226 liveuser 11023
 
323 liveuser 11024
									#提示還不用 unmask
11025
									echo "don't need unmask now".PHP_EOL;
11026
 
11027
									}#if end
11028
 
3 liveuser 11029
								#重新計數 \r\n
11030
								$connections[$conIndex]["3rn"]=0;
226 liveuser 11031
 
3 liveuser 11032
								}#if end
226 liveuser 11033
 
3 liveuser 11034
							}#if end
226 liveuser 11035
 
3 liveuser 11036
						#如果有內容(不是換行符號)
323 liveuser 11037
						#$st=trim($buf);
226 liveuser 11038
 
3 liveuser 11039
						#如果是 ws 模式
11040
						if($conf["wsMode"]==="true"){
226 liveuser 11041
 
3 liveuser 11042
							#如果尚未 handshake
11043
							if($connections[$conIndex]["handshaked"]==="false"){
226 liveuser 11044
 
323 liveuser 11045
								#如果要 debug
11046
								if($conf["debug"]==="true"){
226 liveuser 11047
 
323 liveuser 11048
									#提示 server 在檢查 handshake 用的 key 是否存在.
11049
									echo "check Sec-WebSocket-Key ..".PHP_EOL;
11050
 
11051
									}#if end
11052
 
3 liveuser 11053
								#handshake
11054
								#如果收到的內容$buf含有 Sec-WebSocket-Key: 字串開頭,擷取後面的內容存到$matchs裡面.
11055
								if(preg_match("/Sec-WebSocket-Key: (.*)/",$buf,$matchs)){
226 liveuser 11056
 
323 liveuser 11057
									#如果要 debug
11058
									if($conf["debug"]==="true"){
226 liveuser 11059
 
323 liveuser 11060
										#提示server在handshake
11061
										echo "do handshake...".PHP_EOL.PHP_EOL;
11062
 
11063
										}#if end
11064
 
3 liveuser 11065
									#handshake
11066
									$key = $matchs[1].'258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
226 liveuser 11067
									$key =  base64_encode(sha1($key, true));
11068
 
3 liveuser 11069
									#設置 handshake 的 header
226 liveuser 11070
									$headers =
3 liveuser 11071
									"HTTP/1.1 101 Switching Protocols".PHP_EOL.
11072
									"Upgrade: websocket".PHP_EOL.
11073
									"Connection: Upgrade".PHP_EOL.
11074
									"Sec-WebSocket-Accept: ".$key.PHP_EOL.
11075
									"X-Powered-By: qbpwcf".PHP_EOL.
11076
									PHP_EOL;
226 liveuser 11077
 
3 liveuser 11078
									#傳送header給client
11079
									socket_write($con["connect"], $headers);
226 liveuser 11080
 
3 liveuser 11081
									#儲存server傳送給client的訊息
11082
									#$connections[$conIndex]["receivedMsgFromServer"][]=$headers;
226 liveuser 11083
 
323 liveuser 11084
									#如果要 debug
11085
									if($conf["debug"]==="true"){
226 liveuser 11086
 
323 liveuser 11087
										#提示server handshake 完畢
11088
										echo "handshak done...".PHP_EOL;
11089
 
11090
										}#if end
11091
 
3 liveuser 11092
									#設置已經 handshake
11093
									$connections[$conIndex]["handshaked"]="true";
226 liveuser 11094
 
3 liveuser 11095
									}#if end
226 liveuser 11096
 
3 liveuser 11097
								}#if end
226 liveuser 11098
 
3 liveuser 11099
							}#if end
226 liveuser 11100
 
3 liveuser 11101
						#如果是 ws 模式
11102
						if($conf["wsMode"]==="true"){
226 liveuser 11103
 
3 liveuser 11104
							#如果尚未 handshake 過
11105
							if($connections[$conIndex]["handshaked"]==="false"){
226 liveuser 11106
 
3 liveuser 11107
								#跳過
11108
								continue;
226 liveuser 11109
 
3 liveuser 11110
								}#if end
226 liveuser 11111
 
66 liveuser 11112
							#如果還不用要 unmask
3 liveuser 11113
							if($connections[$conIndex]["unmask"]==="false"){
226 liveuser 11114
 
3 liveuser 11115
								#跳過
11116
								continue;
226 liveuser 11117
 
3 liveuser 11118
								}#if end
226 liveuser 11119
 
3 liveuser 11120
							}#if end
226 liveuser 11121
 
3 liveuser 11122
						#如果是 ws 模式
11123
						if($conf["wsMode"]==="true"){
226 liveuser 11124
 
3 liveuser 11125
							#debug
11126
							#var_dump(__LINE__,$connections[$conIndex]);
226 liveuser 11127
 
3 liveuser 11128
							#如果已經 handshake 過
11129
							if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 11130
 
11131
								#如果要 unmask
3 liveuser 11132
								if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 11133
 
3 liveuser 11134
									#如果收到的訊息不為空
11135
									if(!empty($buf)){
226 liveuser 11136
 
323 liveuser 11137
										#如果要 debug
11138
										if($conf["debug"]==="true"){
226 liveuser 11139
 
323 liveuser 11140
											#提示要 unmask
11141
											echo "start unmask...".PHP_EOL;
11142
 
11143
											}#if end
11144
 
3 liveuser 11145
										#debug
11146
										#var_dump(__LINE__,$buf);
226 liveuser 11147
 
324 liveuser 11148
										#如果有尚未處理的未完整buf
11149
										if(count($connections[$conIndex]["buf"])>0){
11150
 
11151
											#如果要 debug
11152
											if($conf["debug"]==="true"){
11153
 
11154
												#提示有不完整的 buf 要處理
11155
												echo "unfinish buf found".PHP_EOL;
11156
 
11157
												}#if end
11158
 
11159
											#儲存最後一個 buf part
11160
											$lastBuf=$buf;
11161
 
11162
											#清空 buf
11163
											$buf="";
11164
 
11165
											#針對每個 不完整的 buf
11166
											foreach($connections[$conIndex]["buf"] as $bufPart){
11167
 
11168
												#串接
11169
												$buf=$buf.$bufPart;
11170
 
11171
												}#foreach end
11172
 
11173
											#清空未處理的不完整buf part
11174
											$connections[$conIndex]["buf"]=array();
11175
 
11176
											#串接 最後一個 buf part
11177
											$buf=$buf.$lastBuf;
11178
 
11179
											}#if end
11180
 
3 liveuser 11181
										#解密 $buf
11182
										#回傳結果:
11183
										#$result["function"],當前函式的名稱.
11184
										#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
11185
										#$result["content"],unmask後的內容.
324 liveuser 11186
										#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame;"waitPayloadContinue":代表尚未收到全部的payload,回傳的content為未mask處理的payload與head.
3 liveuser 11187
										#$result["error"],錯誤訊息陣列.
11188
										$conf["self::unmask"]["payload"]=$buf;
11189
										#$conf["self::unmask"]["debug"]="true";
11190
										$buf=webSock::unmask($conf["self::unmask"]);
11191
										unset($conf["self::unmask"]);
226 liveuser 11192
 
3 liveuser 11193
										#如果執行失敗
11194
										if($buf["status"]==="false"){
226 liveuser 11195
 
3 liveuser 11196
											#印出結果
11197
											var_dump($buf);
226 liveuser 11198
 
3 liveuser 11199
											#結束執行
11200
											exit;
226 liveuser 11201
 
3 liveuser 11202
											}#if end
226 liveuser 11203
 
3 liveuser 11204
										#如果是 ping 的回應 pong
11205
										if($buf["type"]==="pong"){
226 liveuser 11206
 
323 liveuser 11207
											#如果要 debug
11208
											if($conf["debug"]==="true"){
226 liveuser 11209
 
323 liveuser 11210
												#提示收到 pong
11211
												echo "got pong".PHP_EOL;
11212
 
11213
												}#if end
11214
 
3 liveuser 11215
											#更新的連線的 last pong time
11216
											$connections[$conIndex]["lastPongTime"]=time();
226 liveuser 11217
 
3 liveuser 11218
											#換處理下一則訊息
11219
											continue;
226 liveuser 11220
 
3 liveuser 11221
											}#if end
226 liveuser 11222
 
3 liveuser 11223
										#如果不是 web socket frame
11224
										if($buf["type"]==="invalid"){
226 liveuser 11225
 
323 liveuser 11226
											#如果要 debug
11227
											if($conf["debug"]==="true"){
226 liveuser 11228
 
323 liveuser 11229
												#提示收到非 web socket frame
11230
												echo "not web socket frame".PHP_EOL;
11231
 
11232
												}#if end
11233
 
3 liveuser 11234
											#debug
11235
											#var_dump(__LINE__,$buf);
226 liveuser 11236
 
3 liveuser 11237
											#換處理下一則訊息
11238
											continue;
226 liveuser 11239
 
3 liveuser 11240
											}#if end
324 liveuser 11241
 
11242
										#如果資料尚未收完整
11243
										if($buf["type"]==="waitPayloadContinue"){
11244
 
11245
											#如果要 debug
11246
											if($conf["debug"]==="true"){
226 liveuser 11247
 
324 liveuser 11248
												#提示收到非 web socket frame
11249
												echo "資料尚未收齊".PHP_EOL;
11250
 
11251
												}#if end
11252
 
11253
											#儲存尚未處理的buf
11254
											$connections[$conIndex]["buf"][]=$buf["content"];
11255
 
11256
											#換處理下一則訊息
11257
											continue;
11258
 
11259
											}#if end
11260
 
3 liveuser 11261
										#取得umask後的內容
11262
										$buf=$buf["content"];
226 liveuser 11263
 
323 liveuser 11264
										#如果要 debug
11265
										if($conf["debug"]==="true"){
226 liveuser 11266
 
323 liveuser 11267
											#提示 unmask 結束
11268
											echo "end unmask()".PHP_EOL;
226 liveuser 11269
 
323 liveuser 11270
											#提示 web socket server 收到訊息的長度(bytes)
11271
											echo "Server receviced plain content(".strlen($buf)."):".PHP_EOL;
226 liveuser 11272
 
323 liveuser 11273
											#提示 web socket server 收到的訊息內容
11274
											echo $buf.PHP_EOL;
11275
 
11276
											}#if end
11277
 
3 liveuser 11278
										}#if end
316 liveuser 11279
 
3 liveuser 11280
									}#if end
226 liveuser 11281
 
3 liveuser 11282
								}#if end
226 liveuser 11283
 
3 liveuser 11284
							}#if end
226 liveuser 11285
 
323 liveuser 11286
						# valid json - start
226 liveuser 11287
 
323 liveuser 11288
						#判斷是否為 json 字串
11289
						$json=json_validate($buf);
11290
 
11291
						#如果收到 的資料不為 json 格式
11292
						if($json===false){
11293
 
11294
							#提示格式錯誤
11295
							echo "Received format of meessage is not json.".PHP_EOL;
11296
 
3 liveuser 11297
							#debug
323 liveuser 11298
							var_dump($buf);
11299
 
11300
							#跳過
11301
							continue;
11302
 
11303
							}//if end
11304
 
11305
						#取得 json 回應
11306
						$buf=json_decode($buf);
11307
 
11308
						#如果沒有給予用戶端識別的id
11309
						if(!isset($buf->id)){
11310
 
11311
							#提示格式錯誤
11312
							echo "message id is required.".PHP_EOL;
11313
 
3 liveuser 11314
							#debug
323 liveuser 11315
							var_dump($buf);
11316
 
11317
							#跳過
3 liveuser 11318
							continue;
323 liveuser 11319
 
3 liveuser 11320
							}#if end
323 liveuser 11321
 
11322
						# valid json - end
226 liveuser 11323
 
323 liveuser 11324
						# no authentication required - start
11325
 
11326
						#如果收到 sess,更新該連線的id.
11327
						if(isset($buf->sess)){
11328
 
11329
							#gpg decret
11330
							#函式說明:
11331
							#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,gpg,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
11332
							#回傳結果:
11333
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11334
							#$result["function"],當前執行的函數名稱.
11335
							#$result["content"],加密後的結果.
11336
							#$result["error"],錯誤訊息陣列.
11337
							#$result["argu"],使用的參數.
11338
							#必填參數:
11339
							#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
11340
							$conf["authenticate::enCodeStr"]["enCodeStr"]=base64_decode($buf->sess);
11341
							#$conf["enCodeType"],"字串",加密或編碼的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin"與"gpg",8種,"sha1"較耗時;"md5"較快;"p_hash"適用於密碼加密;"aes256"是對稱式加解密;"qbpwcf"是透過先json_encdoe後再urlencode最後再base64_encode後bin2hex的結果;"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin";"gpg"是應用gpg進行加解密,需要先有ID對應的key.
11342
							$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
11343
							#可省略參數:
11344
							#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
11345
							#$conf["sha1Raw"]="false";
11346
							#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
11347
							#$conf["p_hash"]="";
11348
							#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
11349
							#$conf["keyForAes256"]="";
11350
							#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
11351
							#$conf["aes256Encode"]="";
11352
							#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
11353
							#$conf["qbpwcfDecode"]="false";
11354
							#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
11355
							$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
11356
							#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,要使用的gpg id,預設為gnupgId.
11357
							#$conf["gpgId"]="";
11358
							#參考資料:
11359
							#sha1=>http://php.net/manual/en/function.sha1.php
11360
							#md5=>http://php.net/manual/en/function.md5.php
11361
							#password_hash=>http://php.net/manual/en/function.password-hash.php
11362
							#password_verify=>http://php.net/manual/en/function.password-verify.php
11363
							#json_decode=>https://www.php.net/manual/en/function.json-decode.php
11364
							#備註:
11365
							#無.
11366
							$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
11367
							unset($conf["authenticate::enCodeStr"]);
226 liveuser 11368
 
323 liveuser 11369
							#如果執行異常
11370
							if($enCodeStr["status"]==="false"){
11371
 
11372
								#提示格式錯誤
11373
								echo "Received format of sess is not right".PHP_EOL;
11374
 
3 liveuser 11375
								#debug
323 liveuser 11376
								var_dump($enCodeStr);
11377
 
11378
								#跳過
11379
								continue;
11380
 
66 liveuser 11381
								}#if end
323 liveuser 11382
 
66 liveuser 11383
							#反之
11384
							else{
323 liveuser 11385
 
11386
								#取得解密後的內容
11387
								$sess_id_str=$enCodeStr["content"];
11388
 
66 liveuser 11389
								}#else end
323 liveuser 11390
 
11391
							#取得 session id
11392
							#函式說明:
11393
							#將字串特定關鍵字與其前面的內容剔除
11394
							#回傳結果:
11395
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11396
							#$result["error"],錯誤訊息陣列.
11397
							#$result["warning"],警告訊息鎮列.
11398
							#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
3 liveuser 11399
							#$result["function"],當前執行的函數名稱.
323 liveuser 11400
							#$result["argu"],使用的參數.
11401
							#$result["oriStr"],要處理的原始字串內容.
11402
							#$result["content"],處理好的的字串內容.
11403
							#$result["deleted"],被移除的內容.
3 liveuser 11404
							#必填參數:
323 liveuser 11405
							#$conf["stringIn"],字串,要處理的字串.
11406
							$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$sess_id_str;
11407
							#$conf["keyWord"],字串,特定字串.
11408
							$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="=";
3 liveuser 11409
							#可省略參數:
323 liveuser 11410
							#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
11411
							#$conf["recursive"]="true";
11412
							#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
11413
							#$conf["lastResult"]=$delStrBeforeKeyWord;
3 liveuser 11414
							#參考資料:
323 liveuser 11415
							#無.
11416
							#備註:
11417
							#無.
11418
							$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
11419
							unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 11420
 
323 liveuser 11421
							#如果執行失敗
11422
							if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 11423
 
323 liveuser 11424
								#提示格式錯誤
11425
								echo "Received format of sess is not right".PHP_EOL;
11426
 
11427
								#debug
11428
								var_dump($delStrBeforeKeyWord);
226 liveuser 11429
 
323 liveuser 11430
								#跳過
11431
								continue;
226 liveuser 11432
 
3 liveuser 11433
								}#if end
226 liveuser 11434
 
323 liveuser 11435
							#如果沒有應該存在的關鍵字 "="
11436
							if($delStrBeforeKeyWord["founded"]==="false"){
226 liveuser 11437
 
323 liveuser 11438
								#debug
11439
								var_dump($delStrBeforeKeyWord);
226 liveuser 11440
 
323 liveuser 11441
								#跳過
11442
								continue;
11443
 
3 liveuser 11444
								}#if end
226 liveuser 11445
 
323 liveuser 11446
							#取得收到的sid
11447
							$sess_id=$delStrBeforeKeyWord["content"];
316 liveuser 11448
 
323 liveuser 11449
							#代表要更換自己的 id 為 session 名稱
11450
							$connections[$conIndex]["id"]=$sess_id;
11451
 
11452
							#如果要debug
11453
							if($conf["debug"]==="true"){
11454
 
11455
								#提示用戶已經認證成什麼身份
11456
								echo "new client id saved:".$sess_id.PHP_EOL;
11457
 
11458
								}#if end
11459
 
316 liveuser 11460
							}#if end
11461
 
323 liveuser 11462
						#如果有收到 email 資訊,設置該連線已經通過email認證.
11463
						if(isset($buf->email)){
316 liveuser 11464
 
323 liveuser 11465
							#gpg decret
316 liveuser 11466
							#函式說明:
11467
							#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,gpg,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
11468
							#回傳結果:
11469
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11470
							#$result["function"],當前執行的函數名稱.
11471
							#$result["content"],加密後的結果.
11472
							#$result["error"],錯誤訊息陣列.
11473
							#$result["argu"],使用的參數.
11474
							#必填參數:
11475
							#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
323 liveuser 11476
							$conf["authenticate::enCodeStr"]["enCodeStr"]=base64_decode($buf->email);
11477
							#$conf["enCodeType"],"字串",加密或編碼的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin"與"gpg",8種,"sha1"較耗時;"md5"較快;"p_hash"適用於密碼加密;"aes256"是對稱式加解密;"qbpwcf"是透過先json_encdoe後再urlencode最後再base64_encode後bin2hex的結果;"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin";"gpg"是應用gpg進行加解密,需要先有ID對應的key.
316 liveuser 11478
							$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
11479
							#可省略參數:
11480
							#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
11481
							#$conf["sha1Raw"]="false";
11482
							#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
11483
							#$conf["p_hash"]="";
11484
							#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
11485
							#$conf["keyForAes256"]="";
11486
							#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
11487
							#$conf["aes256Encode"]="";
11488
							#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
11489
							#$conf["qbpwcfDecode"]="false";
11490
							#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
11491
							$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
11492
							#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,要使用的gpg id,預設為gnupgId.
11493
							#$conf["gpgId"]="";
11494
							#參考資料:
11495
							#sha1=>http://php.net/manual/en/function.sha1.php
11496
							#md5=>http://php.net/manual/en/function.md5.php
11497
							#password_hash=>http://php.net/manual/en/function.password-hash.php
11498
							#password_verify=>http://php.net/manual/en/function.password-verify.php
11499
							#json_decode=>https://www.php.net/manual/en/function.json-decode.php
11500
							#備註:
11501
							#無.
11502
							$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
11503
							unset($conf["authenticate::enCodeStr"]);
11504
 
323 liveuser 11505
							#如果執行異常
316 liveuser 11506
							if($enCodeStr["status"]==="false"){
323 liveuser 11507
 
11508
								#提示格式錯誤
11509
								echo "Received format of EMAIL is not right".PHP_EOL;
11510
 
316 liveuser 11511
								#debug
11512
								var_dump($enCodeStr);
323 liveuser 11513
 
316 liveuser 11514
								#跳過
11515
								continue;
323 liveuser 11516
 
316 liveuser 11517
								}#if end
323 liveuser 11518
 
11519
							#反之
11520
							else{
11521
 
11522
								#取得解密後的內容
11523
								$validatedEmail=$enCodeStr["content"];
11524
 
11525
								}#else end
11526
 
11527
							#取得 email
316 liveuser 11528
							#函式說明:
11529
							#將字串特定關鍵字與其前面的內容剔除
11530
							#回傳結果:
11531
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11532
							#$result["error"],錯誤訊息陣列.
11533
							#$result["warning"],警告訊息鎮列.
11534
							#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
11535
							#$result["function"],當前執行的函數名稱.
11536
							#$result["argu"],使用的參數.
11537
							#$result["oriStr"],要處理的原始字串內容.
11538
							#$result["content"],處理好的的字串內容.
11539
							#$result["deleted"],被移除的內容.
11540
							#必填參數:
11541
							#$conf["stringIn"],字串,要處理的字串.
323 liveuser 11542
							$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$validatedEmail;
316 liveuser 11543
							#$conf["keyWord"],字串,特定字串.
11544
							$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="=";
11545
							#可省略參數:
11546
							#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
11547
							#$conf["recursive"]="true";
11548
							#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
11549
							#$conf["lastResult"]=$delStrBeforeKeyWord;
11550
							#參考資料:
11551
							#無.
11552
							#備註:
11553
							#無.
11554
							$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
11555
							unset($conf["stringProcess::delStrBeforeKeyWord"]);
11556
 
11557
							#如果執行失敗
11558
							if($delStrBeforeKeyWord["status"]==="false"){
11559
 
11560
								#debug
11561
								var_dump($delStrBeforeKeyWord);
323 liveuser 11562
 
316 liveuser 11563
								#跳過
11564
								continue;
11565
 
11566
								}#if end
11567
 
11568
							#如果沒有應該存在的關鍵字 "="
11569
							if($delStrBeforeKeyWord["founded"]==="false"){
11570
 
323 liveuser 11571
								#提示格式錯誤
11572
								echo "Received format of EMAIL is not right".PHP_EOL;
11573
 
316 liveuser 11574
								#debug
11575
								var_dump($delStrBeforeKeyWord);
323 liveuser 11576
 
316 liveuser 11577
								#跳過
11578
								continue;
323 liveuser 11579
 
316 liveuser 11580
								}#if end
11581
 
323 liveuser 11582
							#取得收到的email
11583
							$validatedEmail=$delStrBeforeKeyWord["content"];
11584
 
11585
							#設置認證後的身份
11586
							$connections[$conIndex]["auth"]=$validatedEmail;
316 liveuser 11587
 
323 liveuser 11588
							#提示用戶已經認證成什麼身份
11589
							echo "new validated user:".$validatedEmail.PHP_EOL;
316 liveuser 11590
 
11591
							}#if end
11592
 
11593
						#如果收到的訊息是 authWithUserAndPrivateKey
11594
						if(isset($buf->authWithUserAndPrivateKay)){
11595
 
11596
							#取得要嘗試登入的賬號與ssh private key content
11597
							$usernameAndSecret=$buf->authWithUserAndPrivateKay;
11598
 
11599
							#解析要嘗試登入的賬號與加密後的ssh private key content
11600
							#函式說明:
11601
							#尋找字串中是否含有符合格式的內容,且回傳解析好的變數數值.
11602
							#回傳結果:
11603
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11604
							#$reuslt["error"],執行不正常結束的錯訊息陣列.
11605
							#$result["function"],當前執行的函式名稱.
11606
							#$result["argu"],所使用的參數.
11607
							#$result["found"],是否有找到符合格式的字串內容,"true"代表有找到,"false"代表沒有找到.
11608
							#$result["content"],陣列,若為n個${*},則當found為"true"時,就會回傳n個元素.
11609
							#$result["parsedVar"][varName],陣列,解析好的變數陣列,varName為${}中的內容,變數的key從0開始.
11610
							#必填參數:
11611
							#$conf["input"],字串,要檢查的字串.
11612
							$conf["search::findSpecifyStrFormat"]["input"]=$usernameAndSecret;
11613
							#$conf["format"],格式字串,要尋找的格式字串.格式為固定的字串("fixedStr format")與變數("${keyWordVarName}")組成.
11614
							$conf["search::findSpecifyStrFormat"]["format"]="\${username} secret:\${secret}";
11615
							#可省略參數:
11616
							#$conf["varEqual"],陣列,變數對應的數值,null代表不指定,其他內容代表該變數解析出來必須要為該內容.
11617
							#$conf["varEqual"]=array(null,"found");
11618
							#$conf["varCon"],陣列,每個varEqual為null者,其是否有其他條件,預設為null代表無其他條件,條件的表示是用陣列的key與value來表達,例如:array("no_tail"=>" not"),就代表變數的結尾不能為" not",可以用的key有"head",代表開頭要有什麼;"no_head",代表不能為什麼開頭;"tail",代表要什麼結尾;"no_tail",代表不能什麼結尾.
11619
							#$conf["varCon"]=array("no_tail"=>" not");
11620
							#參考資料:
11621
							#無.
11622
							#備註:
11623
							#無.
11624
							$findSpecifyStrFormat=search::findSpecifyStrFormat($conf["search::findSpecifyStrFormat"]);
11625
							unset($conf["search::findSpecifyStrFormat"]);
11626
 
11627
							#如果執行失敗
11628
							if($findSpecifyStrFormat["status"]==="false"){
11629
 
11630
								#debug
11631
								var_dump($findSpecifyStrFormat);
11632
 
11633
								#跳過
11634
								continue;
11635
 
11636
								}#if end
11637
 
11638
							#如果沒有需要的內容
11639
							if($findSpecifyStrFormat["found"]==="false"){
11640
 
11641
								#debug
11642
								var_dump($findSpecifyStrFormat);
11643
 
11644
								#跳過
11645
								continue;
11646
 
11647
								}#if end
11648
 
11649
							#儲存要登入的使用者名稱
11650
							$unAuthUser=$findSpecifyStrFormat["parsedVar"]["username"][0];
11651
 
11652
							#儲存欲登入者的ssh private key
11653
							$unAuthUserSshPriKey=$findSpecifyStrFormat["parsedVar"]["secret"][0];
11654
 
11655
							#建立暫存的 ssh privat key
11656
							#函式說明:
11657
							#於本套件位置底下的tmp資料夾下建立與回傳暫存檔案名稱路徑
11658
							#回傳結果:
11659
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11660
							#$result["error"],錯誤訊息.
11661
							#$result["function"],當前執行的函數名稱.
11662
							#$result["content"],暫存檔案的路徑與名稱.
11663
							#$result["fileName"],暫存檔案的名稱.
11664
							#$result["path"],暫存檔案的路徑.
11665
							#必填參數:
11666
							#無.
11667
							#可省略參數:
11668
							#$conf["content"],陣列,每行檔案的內容,預設為空陣列,不寫入任何資料.
11669
							$conf["fileAccess::createTempFile"]["contant"]=array($unAuthUserSshPriKey);
11670
							#參考資料:
11671
							#無.
11672
							#備註:
11673
							#無.
11674
							$createTempFile=fileAccess::createTempFile($conf["fileAccess::createTempFile"]);
11675
							unset($conf["fileAccess::createTempFile"]);
11676
 
11677
							#如果執行異常
11678
							if($createTempFile["status"]==="false"){
11679
 
11680
								#debug
11681
								var_dump($createTempFile);
11682
 
11683
								#跳過
11684
								continue;
11685
 
11686
								}#if end
11687
 
11688
							#儲存 ssh private key 的位置與名稱
11689
							$sshPrivateKey=$createTempFile["content"];
11690
 
11691
							#檢測能否使用 ssh private 登入對應賬號
11692
							$cmd="echo \"env\" | ssh -i ".$sshPrivateKey." ".$unAuthUser."@127.0.0.1";
11693
 
11694
							#函式說明:
11695
							#將指令字串解析成陣列,方便給予 external::callShell 使用
11696
							#回傳結果:
11697
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11698
							#$reuslt["error"],執行不正常結束的錯訊息陣列.
11699
							#$result["function"],當前執行的函式名稱.
11700
							#$result["content"],解析好的指令陣列.
11701
							#$result["cmd"],解析好的指令名稱.
11702
							#$result["argus"],解析好的參數陣列.
11703
							#$result["argu"],所使用的參數.
11704
							#必填參數
11705
							#$conf["cmdStr"],字串,要解析的指令字串
11706
							$conf["cmd::parseCmdString"]["cmdStr"]=$cmd;
11707
							#可省略參數:
11708
							#無.
11709
							#參考資料:
11710
							#無.
11711
							#備註:
11712
							#無.
11713
							$parseCmdString=cmd::parseCmdString($conf["cmd::parseCmdString"]);
11714
							unset($conf["cmd::parseCmdString"]);
11715
 
11716
							#如果執行失敗
11717
							if($parseCmdString["status"]==="false"){
11718
 
11719
								#debug
11720
								var_dump($parseCmdString);
11721
 
11722
								#跳過
11723
								continue;
11724
 
11725
								}#if end
11726
 
11727
							#函式說明:
11728
							#透過proc來多執行序運作.
11729
							#回傳結果:
11730
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11731
							#$reuslt["error"],執行不正常結束的錯訊息陣列.
11732
							#$result["function"],當前執行的函式名稱.
11733
							#$result["argu"],使用的參數.
11734
							#$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"代表程序的資訊.
11735
							#必填參數:
11736
							#$conf["cmds"],字串陣列,每個元素代表單一程序要執行的指令與參數.
11737
							$conf["threads::proc"]["cmds"]=array($parseCmdString["argus"]);
11738
							#可省略參數:
11739
							#$conf["wait"],字串,是否需要等待所有程序結束,預設為"true"要等待;反之為"false"不要等待.
11740
							#$conf["wait"]="false";
11741
							#$conf["timeout"],字串陣列,每個元素代表單一程序執行的最大等待秒數,超過後將會強迫停止執行,僅當wait參數為"true"時生效.
11742
							#$conf["timeout"]=array("10");
11743
							#$conf["workingDir"],字串陣列,個別程式執行時的家目錄,預設不指定.
11744
							#$conf["workingDir"]=array("path");
11745
							#$conf["envs"],2維字串陣列,每個元素代表個別程式執行時的指定環境變數,key變數名稱;value為變數內容.預設為array("QBPWCF" => "Quick Build PHP Website Componment base on Fedora Linux");
11746
							#$conf["envs"]=array(array("key"=>"value"));
11747
							#$conf["executeBy"],字串陣列,每個元素代表個別指令要用什麼程式執行,預設為"bash".
11748
							#$conf["executeBy"]=array("bash");
11749
							#參考資料:
11750
							#https://www.php.net/manual/en/function.proc-open.php
11751
							#https://www.php.net/manual/en/function.proc-get-status.php
11752
							#https://www.php.net/manual/en/function.proc-terminate.php
11753
							#備註:
11754
							#當wait參數為"true"時,會自動解析stdout與stderr,因此不用再透過 self::proc_update 來更新.
11755
							#當wait參數不為"true"時,若需要取得當下的執行狀況,請使用 self::proc_update 來更新.
11756
							$proc=threads::proc($conf["threads::proc"]);
11757
							unset($conf["threads::proc"]);
11758
 
11759
							#如果執行失敗
11760
							if($proc["status"]==="false"){
11761
 
11762
								#debug
11763
								var_dump($proc);
11764
 
11765
								#跳過
11766
								continue;
11767
 
11768
								}#if end
11769
 
11770
							#如果執行失敗
11771
							if($proc["content"][0]["status"]==="false"){
11772
 
11773
								#debug
11774
								var_dump($proc);
11775
 
11776
								#跳過
11777
								continue;
11778
 
11779
								}#if end
11780
 
11781
							#反之
11782
							else{
11783
 
11784
								#代表使用者登入成功
11785
								$connections[$conIndex]["auth"]=$unAuthUser;
11786
 
323 liveuser 11787
								#設置訊息來源
11788
								$talkback["from"]="server";
11789
 
11790
								#設置訊息內容
11791
								$talkback["msg"]="authenticated";
11792
 
11793
								#設置給用戶端識別用的id
11794
								$talkback["id"]=$buf->id;
11795
 
11796
								#設置要回傳的訊息
11797
								$talkback=json_encode($talkback);
316 liveuser 11798
 
11799
								}#else end
11800
 
11801
							#如果是 ws 模式
11802
							if($conf["wsMode"]==="true"){
11803
 
11804
								#如果已經 handshake 過
11805
								if($connections[$conIndex]["handshaked"]==="true"){
11806
 
11807
									#如果要 unmask
11808
									if($connections[$conIndex]["unmask"]==="true"){
11809
 
11810
										#函式說明:
11811
										#加密 handshake 後要傳送的訊息
11812
										#回傳結果:
11813
										#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11814
										#$result["error"],執行不正常結束的錯訊息陣列.
11815
										#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
11816
										#$result["argu"],陣列,使用的參數.
11817
										#必填參數:
11818
										#$conf["text"],字串,要加密的訊息.
11819
										$conf["webSock::encode"]["text"]=$talkback;
11820
										#可省略參數:
11821
										#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
11822
										#$conf["payloadIsBin"]="false";
11823
										#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
11824
										#$conf["ping"]="false";
11825
										#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
11826
										#$conf["pong"]="false";
11827
										#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
11828
										#$conf["frames"]=array();
11829
										#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
11830
										#$conf["mask"]="false";
11831
										#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
11832
										#$conf["debug"]="false";
11833
										#參考資料:
11834
										#無.
11835
										#備註:
11836
										#目前$conf["text"]長度超過125會出錯.
11837
										$talkback=webSock::encode($conf["webSock::encode"]);
11838
										unset($conf["webSock::encode"]);
11839
 
11840
										#如果執行失敗
11841
										if($talkback["status"]==="false"){
11842
 
11843
											#印出結果
11844
											var_dump($talkback);
11845
 
11846
											#結束執行
11847
											exit;
11848
 
11849
											}#if end
11850
 
11851
										#debug
11852
										#var_dump(__LINE__,$talkback);
11853
 
11854
										}#if end
11855
 
11856
									}#if end
11857
 
11858
								}#if end
11859
 
11860
							#反之不為 web socket 訊息
11861
							else{
11862
 
11863
								#儲存成只有一個訊息
11864
								$talkback["content"][]=$talkback;
11865
 
11866
								}#else
11867
 
11868
							#針對每個訊息的分段
11869
							foreach($talkback["content"] as $msg){
11870
 
11871
								#回傳訊息
11872
								$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
11873
 
323 liveuser 11874
								#如果傳遞失敗
11875
								if($socket_write===false){
11876
 
11877
									#debug
11878
									var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
11879
 
11880
									}#if end
316 liveuser 11881
 
11882
								}#foreach end
11883
 
11884
							}#if end
11885
 
11886
						# no authentication required - end
11887
 
323 liveuser 11888
						# When there is only a id attr end here - start
11889
 
11890
						#取得暫存的物件轉陣列結果
11891
						$tmp=(array)$buf;
11892
 
11893
						#如果只有一個屬性,且為id
11894
						if(count($tmp)===1 && isset($tmp["id"])){
11895
 
11896
							#跳過後面的運行
66 liveuser 11897
							continue;
323 liveuser 11898
 
66 liveuser 11899
							}#if end
323 liveuser 11900
 
11901
						# When there is only a id attr end here - end
226 liveuser 11902
 
323 liveuser 11903
						# denied no auth user - start
316 liveuser 11904
 
323 liveuser 11905
						#如果尚未認證
11906
						if($connections[$conIndex]["auth"]===false){
226 liveuser 11907
 
323 liveuser 11908
							#初始化儲存資訊結構的陣列
11909
							$talkback=array();
11910
 
11911
							#設置訊息來源
11912
							$talkback["from"]="server";
11913
 
11914
							#設置訊息內容
11915
							$talkback["msg"]="permission denied";
11916
 
11917
							#設置給用戶端識別用的id
11918
							$talkback["id"]=$buf->id;
11919
 
3 liveuser 11920
							#設置要回傳的訊息
323 liveuser 11921
							$talkback=json_encode($talkback);
226 liveuser 11922
 
3 liveuser 11923
							#如果是 ws 模式
11924
							if($conf["wsMode"]==="true"){
226 liveuser 11925
 
3 liveuser 11926
								#如果已經 handshake 過
11927
								if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 11928
 
11929
									#如果要 unmask
3 liveuser 11930
									if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 11931
 
3 liveuser 11932
										#函式說明:
226 liveuser 11933
										#加密 handshake 後要傳送的訊息
3 liveuser 11934
										#回傳結果:
11935
										#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11936
										#$result["error"],執行不正常結束的錯訊息陣列.
11937
										#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
11938
										#$result["argu"],陣列,使用的參數.
11939
										#必填參數:
11940
										#$conf["text"],字串,要加密的訊息.
226 liveuser 11941
										$conf["webSock::encode"]["text"]=$talkback;
3 liveuser 11942
										#可省略參數:
11943
										#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
11944
										#$conf["payloadIsBin"]="false";
11945
										#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
11946
										#$conf["ping"]="false";
11947
										#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
11948
										#$conf["pong"]="false";
11949
										#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
11950
										#$conf["frames"]=array();
11951
										#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
11952
										#$conf["mask"]="false";
11953
										#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
11954
										#$conf["debug"]="false";
11955
										#參考資料:
11956
										#無.
11957
										#備註:
11958
										#目前$conf["text"]長度超過125會出錯.
11959
										$talkback=webSock::encode($conf["webSock::encode"]);
11960
										unset($conf["webSock::encode"]);
226 liveuser 11961
 
3 liveuser 11962
										#如果執行失敗
11963
										if($talkback["status"]==="false"){
226 liveuser 11964
 
3 liveuser 11965
											#印出結果
11966
											var_dump($talkback);
226 liveuser 11967
 
3 liveuser 11968
											#結束執行
11969
											exit;
226 liveuser 11970
 
3 liveuser 11971
											}#if end
226 liveuser 11972
 
3 liveuser 11973
										#debug
11974
										#var_dump(__LINE__,$talkback);
226 liveuser 11975
 
3 liveuser 11976
										}#if end
226 liveuser 11977
 
3 liveuser 11978
									}#if end
226 liveuser 11979
 
3 liveuser 11980
								}#if end
226 liveuser 11981
 
3 liveuser 11982
							#反之不為 web socket 訊息
11983
							else{
226 liveuser 11984
 
3 liveuser 11985
								#儲存成只有一個訊息
11986
								$talkback["content"][]=$talkback;
226 liveuser 11987
 
3 liveuser 11988
								}#else
226 liveuser 11989
 
3 liveuser 11990
							#針對每個訊息的分段
11991
							foreach($talkback["content"] as $msg){
226 liveuser 11992
 
3 liveuser 11993
								#回傳訊息
323 liveuser 11994
								$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 11995
 
3 liveuser 11996
								#debug
11997
								#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 11998
 
3 liveuser 11999
								}#foreach end
226 liveuser 12000
 
3 liveuser 12001
							#跳到下一輪
12002
							continue;
226 liveuser 12003
 
3 liveuser 12004
							}#if end
226 liveuser 12005
 
323 liveuser 12006
						# denied no auth user - end
226 liveuser 12007
 
323 liveuser 12008
						# authentication required - start
226 liveuser 12009
 
323 liveuser 12010
						#如果有 to 跟 content
12011
						if( isset($buf->to) && isset($buf->content) ){
12012
 
12013
							#解密 $buf->to
12014
							#gpg decret
12015
							#函式說明:
12016
							#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,gpg,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
12017
							#回傳結果:
12018
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12019
							#$result["function"],當前執行的函數名稱.
12020
							#$result["content"],加密後的結果.
12021
							#$result["error"],錯誤訊息陣列.
12022
							#$result["argu"],使用的參數.
12023
							#必填參數:
12024
							#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
12025
							$conf["authenticate::enCodeStr"]["enCodeStr"]=base64_decode($buf->to);
12026
							#$conf["enCodeType"],"字串",加密或編碼的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin"與"gpg",8種,"sha1"較耗時;"md5"較快;"p_hash"適用於密碼加密;"aes256"是對稱式加解密;"qbpwcf"是透過先json_encdoe後再urlencode最後再base64_encode後bin2hex的結果;"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin";"gpg"是應用gpg進行加解密,需要先有ID對應的key.
12027
							$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
12028
							#可省略參數:
12029
							#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
12030
							#$conf["sha1Raw"]="false";
12031
							#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
12032
							#$conf["p_hash"]="";
12033
							#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
12034
							#$conf["keyForAes256"]="";
12035
							#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
12036
							#$conf["aes256Encode"]="";
12037
							#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
12038
							#$conf["qbpwcfDecode"]="false";
12039
							#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
12040
							$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
12041
							#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,要使用的gpg id,預設為gnupgId.
12042
							#$conf["gpgId"]="";
12043
							#參考資料:
12044
							#sha1=>http://php.net/manual/en/function.sha1.php
12045
							#md5=>http://php.net/manual/en/function.md5.php
12046
							#password_hash=>http://php.net/manual/en/function.password-hash.php
12047
							#password_verify=>http://php.net/manual/en/function.password-verify.php
12048
							#json_decode=>https://www.php.net/manual/en/function.json-decode.php
12049
							#備註:
12050
							#無.
12051
							$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
12052
							unset($conf["authenticate::enCodeStr"]);
226 liveuser 12053
 
323 liveuser 12054
							#如果執行異常
12055
							if($enCodeStr["status"]==="false"){
12056
 
12057
								#提示格式錯誤
12058
								echo "Received format of EMAIL is not right".PHP_EOL;
12059
 
12060
								#debug
12061
								var_dump($enCodeStr);
12062
 
12063
								#跳過
12064
								continue;
12065
 
12066
								}#if end
12067
 
12068
							#反之
12069
							else{
12070
 
12071
								#取得解密後的內容
12072
								$to=$enCodeStr["content"];
12073
 
12074
								}#else end
12075
 
12076
							#取得收訊息者的id
12077
							#函式說明:
12078
							#將字串特定關鍵字與其前面的內容剔除
12079
							#回傳結果:
12080
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12081
							#$result["error"],錯誤訊息陣列.
12082
							#$result["warning"],警告訊息鎮列.
12083
							#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
12084
							#$result["function"],當前執行的函數名稱.
12085
							#$result["argu"],使用的參數.
12086
							#$result["oriStr"],要處理的原始字串內容.
12087
							#$result["content"],處理好的的字串內容.
12088
							#$result["deleted"],被移除的內容.
12089
							#必填參數:
12090
							#$conf["stringIn"],字串,要處理的字串.
12091
							$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$to;
12092
							#$conf["keyWord"],字串,特定字串.
12093
							$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="=";
12094
							#可省略參數:
12095
							#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
12096
							#$conf["recursive"]="true";
12097
							#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
12098
							#$conf["lastResult"]=$delStrBeforeKeyWord;
12099
							#參考資料:
12100
							#無.
12101
							#備註:
12102
							#無.
12103
							$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
12104
							unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 12105
 
323 liveuser 12106
							#如果執行失敗
12107
							if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 12108
 
323 liveuser 12109
								#debug
12110
								var_dump($delStrBeforeKeyWord);
226 liveuser 12111
 
323 liveuser 12112
								#跳過
12113
								continue;
226 liveuser 12114
 
323 liveuser 12115
								}#if end
226 liveuser 12116
 
323 liveuser 12117
							#如果沒有應該存在的關鍵字 "="
12118
							if($delStrBeforeKeyWord["founded"]==="false"){
226 liveuser 12119
 
323 liveuser 12120
								#提示格式錯誤
12121
								echo "Received format of EMAIL is not right".PHP_EOL;
12122
 
12123
								#debug
12124
								var_dump($delStrBeforeKeyWord);
226 liveuser 12125
 
323 liveuser 12126
								#跳過
12127
								continue;
12128
 
12129
								}#if end
226 liveuser 12130
 
323 liveuser 12131
							#取得收到的id
12132
							$to=$delStrBeforeKeyWord["content"];
12133
 
12134
							#解密 $buf->content
12135
							#gpg decret
12136
							#函式說明:
12137
							#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,gpg,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
12138
							#回傳結果:
12139
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12140
							#$result["function"],當前執行的函數名稱.
12141
							#$result["content"],加密後的結果.
12142
							#$result["error"],錯誤訊息陣列.
12143
							#$result["argu"],使用的參數.
12144
							#必填參數:
12145
							#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
12146
							$conf["authenticate::enCodeStr"]["enCodeStr"]=base64_decode($buf->content);
12147
							#$conf["enCodeType"],"字串",加密或編碼的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin"與"gpg",8種,"sha1"較耗時;"md5"較快;"p_hash"適用於密碼加密;"aes256"是對稱式加解密;"qbpwcf"是透過先json_encdoe後再urlencode最後再base64_encode後bin2hex的結果;"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin";"gpg"是應用gpg進行加解密,需要先有ID對應的key.
12148
							$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
12149
							#可省略參數:
12150
							#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
12151
							#$conf["sha1Raw"]="false";
12152
							#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
12153
							#$conf["p_hash"]="";
12154
							#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
12155
							#$conf["keyForAes256"]="";
12156
							#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
12157
							#$conf["aes256Encode"]="";
12158
							#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
12159
							#$conf["qbpwcfDecode"]="false";
12160
							#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
12161
							$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
12162
							#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,要使用的gpg id,預設為gnupgId.
12163
							#$conf["gpgId"]="";
12164
							#參考資料:
12165
							#sha1=>http://php.net/manual/en/function.sha1.php
12166
							#md5=>http://php.net/manual/en/function.md5.php
12167
							#password_hash=>http://php.net/manual/en/function.password-hash.php
12168
							#password_verify=>http://php.net/manual/en/function.password-verify.php
12169
							#json_decode=>https://www.php.net/manual/en/function.json-decode.php
12170
							#備註:
12171
							#無.
12172
							$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
12173
							unset($conf["authenticate::enCodeStr"]);
226 liveuser 12174
 
323 liveuser 12175
							#如果執行異常
12176
							if($enCodeStr["status"]==="false"){
12177
 
12178
								#提示格式錯誤
12179
								echo "Received format of EMAIL is not right".PHP_EOL;
12180
 
12181
								#debug
12182
								var_dump($enCodeStr);
12183
 
12184
								#跳過
12185
								continue;
12186
 
12187
								}#if end
12188
 
12189
							#反之
12190
							else{
12191
 
12192
								#取得解密後的內容
12193
								$msg=$enCodeStr["content"];
12194
 
12195
								}#else end
12196
 
12197
							#取得要傳送的訊息
12198
							#函式說明:
12199
							#將字串特定關鍵字與其前面的內容剔除
12200
							#回傳結果:
12201
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12202
							#$result["error"],錯誤訊息陣列.
12203
							#$result["warning"],警告訊息鎮列.
12204
							#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
12205
							#$result["function"],當前執行的函數名稱.
12206
							#$result["argu"],使用的參數.
12207
							#$result["oriStr"],要處理的原始字串內容.
12208
							#$result["content"],處理好的的字串內容.
12209
							#$result["deleted"],被移除的內容.
12210
							#必填參數:
12211
							#$conf["stringIn"],字串,要處理的字串.
12212
							$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$msg;
12213
							#$conf["keyWord"],字串,特定字串.
12214
							$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="=";
12215
							#可省略參數:
12216
							#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
12217
							#$conf["recursive"]="true";
12218
							#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
12219
							#$conf["lastResult"]=$delStrBeforeKeyWord;
12220
							#參考資料:
12221
							#無.
12222
							#備註:
12223
							#無.
12224
							$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
12225
							unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 12226
 
323 liveuser 12227
							#如果執行失敗
12228
							if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 12229
 
323 liveuser 12230
								#debug
12231
								var_dump($delStrBeforeKeyWord);
226 liveuser 12232
 
323 liveuser 12233
								#跳過
66 liveuser 12234
								continue;
226 liveuser 12235
 
66 liveuser 12236
								}#if end
226 liveuser 12237
 
323 liveuser 12238
							#如果沒有應該存在的關鍵字 "="
12239
							if($delStrBeforeKeyWord["founded"]==="false"){
226 liveuser 12240
 
323 liveuser 12241
								#提示格式錯誤
324 liveuser 12242
								echo "Received format of msg is not right".PHP_EOL;
323 liveuser 12243
 
12244
								#debug
12245
								var_dump($delStrBeforeKeyWord);
226 liveuser 12246
 
323 liveuser 12247
								#跳過
12248
								continue;
12249
 
3 liveuser 12250
								}#if end
226 liveuser 12251
 
323 liveuser 12252
							#取得要傳送的訊息
12253
							$msg=$delStrBeforeKeyWord["content"];
12254
 
12255
							#另存新訊息的資訊
12256
							$newMsg=array("to"=>$to,"msg"=>$msg,"id"=>$buf->id);
12257
 
324 liveuser 12258
							#如果有 $buf->from
12259
							if(isset($buf->from)){
12260
 
12261
								#解密 $buf->from
12262
								#gpg decret
12263
								#函式說明:
12264
								#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,gpg,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
12265
								#回傳結果:
12266
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12267
								#$result["function"],當前執行的函數名稱.
12268
								#$result["content"],加密後的結果.
12269
								#$result["error"],錯誤訊息陣列.
12270
								#$result["argu"],使用的參數.
12271
								#必填參數:
12272
								#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
12273
								$conf["authenticate::enCodeStr"]["enCodeStr"]=base64_decode($buf->from);
12274
								#$conf["enCodeType"],"字串",加密或編碼的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin"與"gpg",8種,"sha1"較耗時;"md5"較快;"p_hash"適用於密碼加密;"aes256"是對稱式加解密;"qbpwcf"是透過先json_encdoe後再urlencode最後再base64_encode後bin2hex的結果;"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin";"gpg"是應用gpg進行加解密,需要先有ID對應的key.
12275
								$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
12276
								#可省略參數:
12277
								#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
12278
								#$conf["sha1Raw"]="false";
12279
								#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
12280
								#$conf["p_hash"]="";
12281
								#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
12282
								#$conf["keyForAes256"]="";
12283
								#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
12284
								#$conf["aes256Encode"]="";
12285
								#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
12286
								#$conf["qbpwcfDecode"]="false";
12287
								#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
12288
								$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
12289
								#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,要使用的gpg id,預設為gnupgId.
12290
								#$conf["gpgId"]="";
12291
								#參考資料:
12292
								#sha1=>http://php.net/manual/en/function.sha1.php
12293
								#md5=>http://php.net/manual/en/function.md5.php
12294
								#password_hash=>http://php.net/manual/en/function.password-hash.php
12295
								#password_verify=>http://php.net/manual/en/function.password-verify.php
12296
								#json_decode=>https://www.php.net/manual/en/function.json-decode.php
12297
								#備註:
12298
								#無.
12299
								$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
12300
								unset($conf["authenticate::enCodeStr"]);
12301
 
12302
								#如果執行異常
12303
								if($enCodeStr["status"]==="false"){
12304
 
12305
									#提示格式錯誤
12306
									echo "Received format of EMAIL is not right".PHP_EOL;
12307
 
12308
									#debug
12309
									var_dump($enCodeStr);
12310
 
12311
									#跳過
12312
									continue;
12313
 
12314
									}#if end
12315
 
12316
								#反之
12317
								else{
12318
 
12319
									#取得解密後的內容
12320
									$from=$enCodeStr["content"];
12321
 
12322
									}#else end
12323
 
12324
								#取得from
12325
								#函式說明:
12326
								#將字串特定關鍵字與其前面的內容剔除
12327
								#回傳結果:
12328
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12329
								#$result["error"],錯誤訊息陣列.
12330
								#$result["warning"],警告訊息鎮列.
12331
								#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
12332
								#$result["function"],當前執行的函數名稱.
12333
								#$result["argu"],使用的參數.
12334
								#$result["oriStr"],要處理的原始字串內容.
12335
								#$result["content"],處理好的的字串內容.
12336
								#$result["deleted"],被移除的內容.
12337
								#必填參數:
12338
								#$conf["stringIn"],字串,要處理的字串.
12339
								$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$from;
12340
								#$conf["keyWord"],字串,特定字串.
12341
								$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="=";
12342
								#可省略參數:
12343
								#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
12344
								#$conf["recursive"]="true";
12345
								#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
12346
								#$conf["lastResult"]=$delStrBeforeKeyWord;
12347
								#參考資料:
12348
								#無.
12349
								#備註:
12350
								#無.
12351
								$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
12352
								unset($conf["stringProcess::delStrBeforeKeyWord"]);
12353
 
12354
								#如果執行失敗
12355
								if($delStrBeforeKeyWord["status"]==="false"){
12356
 
12357
									#debug
12358
									var_dump($delStrBeforeKeyWord);
12359
 
12360
									#跳過
12361
									continue;
12362
 
12363
									}#if end
12364
 
12365
								#如果沒有應該存在的關鍵字 "="
12366
								if($delStrBeforeKeyWord["founded"]==="false"){
12367
 
12368
									#提示格式錯誤
12369
									echo "Received format of from is not right".PHP_EOL;
12370
 
12371
									#debug
12372
									var_dump($delStrBeforeKeyWord);
12373
 
12374
									#跳過
12375
									continue;
12376
 
12377
									}#if end
12378
 
12379
								#取得from
12380
								$from=$delStrBeforeKeyWord["content"];
12381
 
12382
								#設置訊息來源
12383
								$newMsg["from"]=$from;
12384
 
12385
								}#ff end
12386
 
323 liveuser 12387
							#設置尚未傳遞的對話內容
12388
							$connections[$conIndex]["msg"][]=$newMsg;
12389
 
12390
							#如果要 debug
12391
							if($conf["debug"]==="true"){
12392
 
3 liveuser 12393
								#debug
323 liveuser 12394
								echo "new message(".$msg.") which resource id is ".$buf->id." from ".$connections[$conIndex]["id"]." to ".$to." queued".PHP_EOL;
12395
 
12396
								}#if end
12397
 
3 liveuser 12398
							}#if end
226 liveuser 12399
 
323 liveuser 12400
						#如果有 toAll,亦即要廣播的內容.
12401
						if( isset($buf->toAll) ){
12402
 
12403
							#解密 $buf->toAll
12404
							#gpg decret
12405
							#函式說明:
12406
							#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,gpg,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
12407
							#回傳結果:
12408
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12409
							#$result["function"],當前執行的函數名稱.
12410
							#$result["content"],加密後的結果.
12411
							#$result["error"],錯誤訊息陣列.
12412
							#$result["argu"],使用的參數.
12413
							#必填參數:
12414
							#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
12415
							$conf["authenticate::enCodeStr"]["enCodeStr"]=base64_decode($buf->toAll);
12416
							#$conf["enCodeType"],"字串",加密或編碼的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin"與"gpg",8種,"sha1"較耗時;"md5"較快;"p_hash"適用於密碼加密;"aes256"是對稱式加解密;"qbpwcf"是透過先json_encdoe後再urlencode最後再base64_encode後bin2hex的結果;"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin";"gpg"是應用gpg進行加解密,需要先有ID對應的key.
12417
							$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
12418
							#可省略參數:
12419
							#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
12420
							#$conf["sha1Raw"]="false";
12421
							#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
12422
							#$conf["p_hash"]="";
12423
							#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
12424
							#$conf["keyForAes256"]="";
12425
							#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
12426
							#$conf["aes256Encode"]="";
12427
							#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
12428
							#$conf["qbpwcfDecode"]="false";
12429
							#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
12430
							$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
12431
							#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,要使用的gpg id,預設為gnupgId.
12432
							#$conf["gpgId"]="";
12433
							#參考資料:
12434
							#sha1=>http://php.net/manual/en/function.sha1.php
12435
							#md5=>http://php.net/manual/en/function.md5.php
12436
							#password_hash=>http://php.net/manual/en/function.password-hash.php
12437
							#password_verify=>http://php.net/manual/en/function.password-verify.php
12438
							#json_decode=>https://www.php.net/manual/en/function.json-decode.php
12439
							#備註:
12440
							#無.
12441
							$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
12442
							unset($conf["authenticate::enCodeStr"]);
226 liveuser 12443
 
323 liveuser 12444
							#如果執行異常
12445
							if($enCodeStr["status"]==="false"){
12446
 
12447
								#提示格式錯誤
12448
								echo "Received format of EMAIL is not right".PHP_EOL;
12449
 
12450
								#debug
12451
								var_dump($enCodeStr);
12452
 
12453
								#跳過
12454
								continue;
12455
 
12456
								}#if end
12457
 
12458
							#反之
12459
							else{
12460
 
12461
								#取得解密後的內容
12462
								$toAll=$enCodeStr["content"];
12463
 
12464
								}#else end
12465
 
12466
							#取得要廣播的訊息 $toAll
66 liveuser 12467
							#函式說明:
12468
							#將字串特定關鍵字與其前面的內容剔除
12469
							#回傳結果:
12470
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12471
							#$result["error"],錯誤訊息陣列.
12472
							#$result["warning"],警告訊息鎮列.
12473
							#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
12474
							#$result["function"],當前執行的函數名稱.
12475
							#$result["argu"],使用的參數.
12476
							#$result["oriStr"],要處理的原始字串內容.
12477
							#$result["content"],處理好的的字串內容.
12478
							#$result["deleted"],被移除的內容.
12479
							#必填參數:
12480
							#$conf["stringIn"],字串,要處理的字串.
323 liveuser 12481
							$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$toAll;
66 liveuser 12482
							#$conf["keyWord"],字串,特定字串.
323 liveuser 12483
							$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="=";
66 liveuser 12484
							#可省略參數:
12485
							#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
12486
							#$conf["recursive"]="true";
12487
							#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
12488
							#$conf["lastResult"]=$delStrBeforeKeyWord;
12489
							#參考資料:
12490
							#無.
12491
							#備註:
12492
							#無.
12493
							$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
12494
							unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 12495
 
66 liveuser 12496
							#如果執行失敗
12497
							if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 12498
 
323 liveuser 12499
								#debug
66 liveuser 12500
								var_dump($delStrBeforeKeyWord);
226 liveuser 12501
 
323 liveuser 12502
								#跳過
12503
								continue;
226 liveuser 12504
 
66 liveuser 12505
								}#if end
226 liveuser 12506
 
323 liveuser 12507
							#如果沒有應該存在的關鍵字 "="
12508
							if($delStrBeforeKeyWord["founded"]==="false"){
226 liveuser 12509
 
323 liveuser 12510
								#提示格式錯誤
12511
								echo "Received format of EMAIL is not right".PHP_EOL;
12512
 
12513
								#debug
12514
								var_dump($delStrBeforeKeyWord);
226 liveuser 12515
 
323 liveuser 12516
								#跳過
12517
								continue;
12518
 
12519
								}#if end
226 liveuser 12520
 
323 liveuser 12521
							#取得要廣播的訊息
12522
							$toAll=$delStrBeforeKeyWord["content"];
12523
 
12524
							#設置尚未傳遞的廣播訊息
12525
							$connections[$conIndex]["broadMsg"][]=$toAll;
12526
 
66 liveuser 12527
							}#if end
226 liveuser 12528
 
323 liveuser 12529
						# authentication required - end
226 liveuser 12530
 
326 liveuser 12531
						#透過 processFuncs 參數處理訊息的部分 - start
226 liveuser 12532
 
323 liveuser 12533
						#如果收到的內容已經為物件
12534
						if(gettype($buf)==="object"){
12535
 
12536
							#轉回json字串
12537
							$buf=json_encode($buf);
12538
 
66 liveuser 12539
							}#if end
226 liveuser 12540
 
3 liveuser 12541
						#如果有指定的外掛函式
12542
						if(isset($conf["processFuncs"])){
226 liveuser 12543
 
3 liveuser 12544
							#針對每個用來處理輸入字串的函式
12545
							foreach($conf["processFuncs"] as $proFunc){
226 liveuser 12546
 
3 liveuser 12547
								#debug
12548
								#var_dump(__LINE__,$proFunc);
323 liveuser 12549
 
12550
								if($conf["debug"]==="true"){
12551
 
12552
									#debug
12553
									echo "running processFuncs ".$proFunc."...".PHP_EOL;
12554
 
12555
									}#if end
226 liveuser 12556
 
66 liveuser 12557
								#函式說明:
12558
								#提供webSock::nativeSocketTcpIpServer用於接受檢查權限的功能.
12559
								#回傳結果:
12560
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12561
								#$result["error"],執行不正常結束的錯訊息陣列.
12562
								#$result["argu"],陣列,使用的參數.
12563
								#必填參數:
12564
								#$conf["data"],字串,收到的bin2hex編碼後果gpg加密過後的json格式資料,必填的key有"randomStr","username","password".
12565
								$conf["webSocket::checkAuth"]["data"]=&$buf;
12566
								#$conf["serverSock"],resource,web socket server socket
12567
								$conf["webSocket::checkAuth"]["serverSock"]=&$sock;
12568
								#$conf["clientSock"],$resource,web socket client socket
12569
								$conf["webSocket::checkAuth"]["clientSock"]=&$con["connect"];
12570
								#$conf["clientInfo"],陣列,web socket client info.
12571
								$conf["webSocket::checkAuth"]["clientInfo"]=&$connections[$conIndex];
12572
								#$conf["clientIndex"],整數.web socket client index.
12573
								$conf["webSocket::checkAuth"]["clientIndex"]=&$conIndex;
12574
								#$conf["allConn"],陣列,all web socket client info.
12575
								$conf["webSocket::checkAuth"]["allConn"]=&$connections;
12576
								#$conf["func"],字串,要檢查的是否具備權限的函式.
12577
								$conf["webSocket::checkAuth"]["func"]=$proFunc;
12578
								#可省略參數:
12579
								#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
12580
								#$conf["wsMode"]="true";
12581
								#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
12582
								#$conf["gpgId"]=gnupgId;
12583
								#$conf["falseAllowFuncPlus"],陣列,額外的未認證時可以執行的函式清單.
12584
								#$conf["falseAllowFuncPlus"]=array();
12585
								#$conf["publicAllowFuncPlus"],陣列,額外的認證為public時可以執行的函式清單.
12586
								#$conf["publicAllowFuncPlus"]=array();
12587
								#參考資料:
12588
								#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
12589
								#備註:
12590
								#無.
323 liveuser 12591
								$checkAuth=webSock::checkAuth($conf["webSocket::checkAuth"]);
66 liveuser 12592
								unset($conf["webSocket::checkAuth"]);
3 liveuser 12593
 
66 liveuser 12594
								#如果沒有權限
12595
								if($checkAuth["status"]==="false"){
226 liveuser 12596
 
323 liveuser 12597
									#如果要 debug
12598
									if($conf["debug"]==="true"){
12599
 
12600
										#提示訊息
12601
										echo "permission dnied".PHP_EOL;
12602
 
12603
										#debug
12604
										var_dump($checkAuth);
12605
 
12606
										}#if end
12607
 
66 liveuser 12608
									#換看下個 $proFunc
12609
									continue;
226 liveuser 12610
 
66 liveuser 12611
									}#if end
12612
 
3 liveuser 12613
								#呼叫函式,參數為輸入的字串data跟client socket, server socket, 每個 socket
12614
								#https://www.php.net/manual/en/function.call-user-func.php
12615
								$param=array("data"=>&$buf,"serverSock"=>&$sock,"clientSock"=>&$con["connect"],"clientInfo"=>&$connections[$conIndex],"clientIndex"=>&$conIndex,"allConn"=>&$connections);
12616
								$params=array();
66 liveuser 12617
								$params[]=&$param;
323 liveuser 12618
								$call_user_func_array=call_user_func_array($proFunc,$params);
3 liveuser 12619
 
323 liveuser 12620
								#如果要 debug
12621
								if($conf["debug"]==="true"){
12622
 
12623
									#提示訊息
12624
									echo "Return result:".PHP_EOL;
12625
 
12626
									#debug
12627
									var_dump($call_user_func_array);
12628
 
12629
									}#if end
3 liveuser 12630
 
12631
								#如果有回傳結果
323 liveuser 12632
								if($call_user_func_array!==NULL){
226 liveuser 12633
 
3 liveuser 12634
									#如果回傳的形態為陣列
323 liveuser 12635
									if(gettype($call_user_func_array)==="array"){
3 liveuser 12636
 
323 liveuser 12637
										#如果無 status
12638
										if(!isset($call_user_func_array["status"])){
12639
 
12640
											#提示錯誤
12641
											echo "run function ".$proFunc." with params:".print_r($params,true)." , but format of return is incorrect!".PHP_EOL;
12642
 
12643
											#debug
12644
											var_dump($call_user_func_array);
12645
 
12646
											#提示會往後面執行
12647
											echo "go next function.".PHP_EOL;
12648
 
12649
											#換下個 function
12650
											continue;
12651
 
12652
											}#if end
12653
 
3 liveuser 12654
										#如果執行出錯
323 liveuser 12655
										if($call_user_func_array["status"]==="false"){
3 liveuser 12656
 
12657
											#提示錯誤
12658
											echo "run function ".$proFunc." with params:".print_r($params,true)." failed!".PHP_EOL;
226 liveuser 12659
 
3 liveuser 12660
											#提示會往後面執行
12661
											echo "go next function.".PHP_EOL;
226 liveuser 12662
 
3 liveuser 12663
											#跳到下一輪
12664
											#continue;
12665
 
12666
											}#if end
226 liveuser 12667
 
3 liveuser 12668
										#如果結果為跳下一輪
323 liveuser 12669
										else if($call_user_func_array["status"]==="continue"){
226 liveuser 12670
 
323 liveuser 12671
											#如果要debug
12672
											if($conf["debug"]==="true"){
12673
 
12674
												#提示成功
12675
												echo "run function ".$proFunc." with params:".print_r($params,true)." success.".PHP_EOL;
226 liveuser 12676
 
323 liveuser 12677
												#提示會往後面執行
12678
												echo "go next function.".PHP_EOL;
12679
 
12680
												}#if end
12681
 
3 liveuser 12682
											}#if end
226 liveuser 12683
 
3 liveuser 12684
										#如果已經被處理好了且不准移交給後面的處理
323 liveuser 12685
										else if($call_user_func_array["status"]==="true"){
226 liveuser 12686
 
323 liveuser 12687
											#如果要debug
12688
											if($conf["debug"]==="true"){
226 liveuser 12689
 
323 liveuser 12690
												#提示成功
12691
												echo "run function ".$proFunc." with params:".print_r($params,true)." success.".PHP_EOL;
226 liveuser 12692
 
323 liveuser 12693
												#提示在此打住.
12694
												echo "end process,".PHP_EOL;
12695
 
12696
												}#if end
12697
 
3 liveuser 12698
											#後面就不做了
12699
											break;
226 liveuser 12700
 
3 liveuser 12701
											}#if end
226 liveuser 12702
 
3 liveuser 12703
										}#if end
12704
 
12705
									#反之回傳形態錯誤
12706
									else{
226 liveuser 12707
 
3 liveuser 12708
										#提示錯誤
12709
										echo "run function ".$proFunc." with params:".print_r($params,true)." success, but format of return is incorrect!".PHP_EOL;
226 liveuser 12710
 
3 liveuser 12711
										#提示會往後面執行
12712
										echo "go next function.".PHP_EOL;
226 liveuser 12713
 
3 liveuser 12714
										}#else end
12715
 
12716
									}#if end
226 liveuser 12717
 
3 liveuser 12718
								#如果沒有回傳結果
12719
								else{
226 liveuser 12720
 
3 liveuser 12721
									#提示錯誤
12722
									echo "run function ".$proFunc." with params:".print_r($params,true)." success, but there is no return!".PHP_EOL;
226 liveuser 12723
 
3 liveuser 12724
									#跳下一輪
12725
									#continue;
226 liveuser 12726
 
3 liveuser 12727
									}#else end
12728
 
12729
								}#foreach end
226 liveuser 12730
 
3 liveuser 12731
							}#if end
326 liveuser 12732
 
12733
						#透過 processFuncs 參數處理訊息的部分 - end
226 liveuser 12734
 
3 liveuser 12735
						}#if end
226 liveuser 12736
 
3 liveuser 12737
					}#foreach end
226 liveuser 12738
 
12739
				#do end
3 liveuser 12740
				}while(true);
12741
 
12742
			#提示關閉 server socket
12743
			echo "關閉 server socket".PHP_EOL;
12744
 
12745
			#關閉 socket
12746
			socket_close($sock);
226 liveuser 12747
 
3 liveuser 12748
			#do end
12749
			}while(true);
226 liveuser 12750
 
3 liveuser 12751
		#設置執行正常
12752
		$result["status"]="true";
226 liveuser 12753
 
3 liveuser 12754
		#回傳結果
12755
		return $result;
226 liveuser 12756
 
3 liveuser 12757
		}#function nativeSocketTcpIpServer end
226 liveuser 12758
 
12759
	/*
3 liveuser 12760
	#函式說明:
12761
	#連線到webSocket,會印出建立好的unixDomainSocket位置與名稱.
12762
	#回傳結果:
12763
	#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
12764
	#$result["error"],錯誤訊息陣列.
12765
	#$resutl["function"],當前執行的涵式名稱.
12766
	#$result["content"],取得的回應.
12767
	#$result["argu"],所使用的參數.
12768
	#$result["Sec-WebSocket-Accept"],所得到的Sec-WebSocket-Accept.
12769
	#必填參數:
12770
	#無.
12771
	#可省略參數:
12772
	#$conf["targetServr"],字串,要連線的目標,預設為"localhost".
12773
	#$conf["targetServr"]="";
12774
	#$conf["targetPort"],字串,要連線的目標port.
12775
	#$conf["targetPort"]="";
12776
	#$conf["ssl"],字串,是否要走wss,預設為"false",不走wss;反之為"true".
12777
	#$conf["ssl"]="false";
12778
	#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
12779
	#$conf["debug"]="false";
12780
	#參考資料:
12781
	#https://www.php.net/manual/en/function.stream-socket-client.php
12782
	#https://www.php.net/manual/en/function.stream-context-create.php
12783
	#https://www.php.net/manual/en/context.ssl.php
12784
	#備註:
12785
	#建構中...
12786
	*/
12787
	public static function clientDaemon(&$conf){
226 liveuser 12788
 
3 liveuser 12789
		#初始化要回傳的結果
12790
		$result=array();
12791
 
12792
		#取得當前執行的函數名稱
12793
		$result["function"]=__FUNCTION__;
12794
 
12795
		#涵式說明:
12796
		#判斷當前環境為web還是cmd
12797
		#回傳結果:
12798
		#$result,"web"或"cmd"
12799
		if(csInformation::getEnv()==="web"){
226 liveuser 12800
 
3 liveuser 12801
			#設置執行失敗
12802
			$result["status"]="false";
226 liveuser 12803
 
3 liveuser 12804
			#設置執行錯誤訊息
12805
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 12806
 
3 liveuser 12807
			#回傳結果
12808
			return $result;
226 liveuser 12809
 
3 liveuser 12810
			}#if end
12811
 
12812
		#取得參數
12813
		$result["argu"]=$conf;
12814
 
12815
		#如果 $conf 不為陣列
12816
		if(gettype($conf)!="array"){
226 liveuser 12817
 
3 liveuser 12818
			#設置執行失敗
12819
			$result["status"]="false";
226 liveuser 12820
 
3 liveuser 12821
			#設置執行錯誤訊息
12822
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 12823
 
3 liveuser 12824
			#如果傳入的參數為 null
12825
			if($conf==null){
226 liveuser 12826
 
3 liveuser 12827
				#設置執行錯誤訊息
12828
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 12829
 
3 liveuser 12830
				}#if end
12831
 
12832
			#回傳結果
12833
			return $result;
226 liveuser 12834
 
3 liveuser 12835
			}#if end
226 liveuser 12836
 
3 liveuser 12837
		#檢查參數
12838
		#函式說明:
12839
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
12840
		#回傳結果:
12841
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12842
		#$result["error"],執行不正常結束的錯訊息陣列.
12843
		#$result["simpleError"],簡單表示的錯誤訊息.
12844
		#$result["function"],當前執行的函式名稱.
12845
		#$result["argu"],設置給予的參數.
12846
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
12847
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
12848
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
12849
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
12850
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
12851
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
12852
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
12853
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
12854
		#必填參數:
12855
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
12856
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
12857
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
12858
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
12859
		#可省略參數:
12860
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
12861
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array();
12862
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
12863
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array();
12864
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
12865
		#$conf["canBeEmptyString"]="false";
12866
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
12867
		#$conf["canNotBeEmpty"]=array();
12868
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
12869
		#$conf["canBeEmpty"]=array();
12870
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
12871
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("targetServr","targetPort","ssl","debug");
12872
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
12873
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("targetServr","targetPort","ssl","debug");
12874
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
12875
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","string");
12876
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
12877
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("localhost",null,"false","false");
12878
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
12879
		#$conf["disallowAllSkipableVarIsEmpty"]="";
12880
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
12881
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
12882
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
12883
		#$conf["disallowAllSkipableVarNotExist"]="";
12884
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
12885
		#$conf["arrayCountEqualCheck"][]=array();
12886
		#參考資料:
12887
		#array_keys=>http://php.net/manual/en/function.array-keys.php
12888
		#備註:
12889
		#無.
12890
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
12891
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 12892
 
3 liveuser 12893
		#如果檢查參數失敗
12894
		if($checkArguments["status"]==="false"){
226 liveuser 12895
 
3 liveuser 12896
			#設置執行失敗
12897
			$result["status"]="false";
226 liveuser 12898
 
3 liveuser 12899
			#設置執行錯誤訊息
12900
			$result["error"]=$checkArguments;
226 liveuser 12901
 
3 liveuser 12902
			#回傳結果
12903
			return $result;
226 liveuser 12904
 
3 liveuser 12905
			}#if end
226 liveuser 12906
 
3 liveuser 12907
		#如果檢查參數不通過
12908
		if($checkArguments["passed"]==="false"){
226 liveuser 12909
 
3 liveuser 12910
			#設置執行失敗
12911
			$result["status"]="false";
226 liveuser 12912
 
3 liveuser 12913
			#設置執行錯誤訊息
12914
			$result["error"]=$checkArguments;
226 liveuser 12915
 
3 liveuser 12916
			#回傳結果
12917
			return $result;
226 liveuser 12918
 
3 liveuser 12919
			}#if end
226 liveuser 12920
 
3 liveuser 12921
		#如果targetPort沒有設置
12922
		if(!isset($conf["targetPort"])){
226 liveuser 12923
 
3 liveuser 12924
			#port預設為80
12925
			$conf["targetPort"]="80";
226 liveuser 12926
 
3 liveuser 12927
			#如果有啟用 ssl
12928
			if($conf["ssl"]==="true"){
226 liveuser 12929
 
3 liveuser 12930
				#port預設為443
12931
				$conf["targetPort"]="443";
226 liveuser 12932
 
3 liveuser 12933
				}#if end
226 liveuser 12934
 
3 liveuser 12935
			}#if end
226 liveuser 12936
 
3 liveuser 12937
		#回報任何錯誤
12938
		#error_reporting(E_ALL);
226 liveuser 12939
 
3 liveuser 12940
		#如果要使用 ssl
12941
		if($conf["ssl"]==="true"){
226 liveuser 12942
 
3 liveuser 12943
			#預設的path
12944
			$path="/";
226 liveuser 12945
 
3 liveuser 12946
			#分割出server位置與對應GET的path
12947
			#函式說明:
12948
			#將固定格式的字串分開,並回傳分開的結果.
12949
			#回傳結果:
12950
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12951
			#$result["error"],錯誤訊息陣列
12952
			#$result["function"],當前執行的函數名稱.
12953
			#$result["argu"],使用的參數.
12954
			#$result["oriStr"],要分割的原始字串內容
12955
			#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
12956
			#$result["dataCounts"],爲總共分成幾段
12957
			#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
12958
			#必填參數:
12959
			#$conf["stringIn"],字串,要處理的字串.
12960
			$conf["stringProcess::spiltString"]["stringIn"]=$conf["targetServr"];
12961
			#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
12962
			$conf["stringProcess::spiltString"]["spiltSymbol"]="/";
12963
			#可省略參數:
12964
			#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
12965
			$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
12966
			#參考資料:
12967
			#無.
12968
			#備註:
12969
			#無.
12970
			$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
12971
			unset($conf["stringProcess::spiltString"]);
226 liveuser 12972
 
3 liveuser 12973
			#如果檢查執行失敗
12974
			if($spiltString["status"]==="false"){
226 liveuser 12975
 
3 liveuser 12976
				#設置執行失敗
12977
				$result["status"]="false";
226 liveuser 12978
 
3 liveuser 12979
				#設置執行錯誤訊息
12980
				$result["error"]=$spiltString;
226 liveuser 12981
 
3 liveuser 12982
				#回傳結果
12983
				return $result;
226 liveuser 12984
 
3 liveuser 12985
				}#if end
226 liveuser 12986
 
3 liveuser 12987
			#如果含有 /
12988
			if($spiltString["found"]==="true"){
226 liveuser 12989
 
3 liveuser 12990
				#函式說明:
12991
				#將字串特定關鍵字與其前面的內容剔除
12992
				#回傳結果:
12993
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12994
				#$result["error"],錯誤訊息陣列.
12995
				#$result["warning"],警告訊息鎮列.
12996
				#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
12997
				#$result["function"],當前執行的函數名稱.
12998
				#$result["argu"],使用的參數.
12999
				#$result["oriStr"],要處理的原始字串內容.
226 liveuser 13000
				#$result["content"],處理好的的字串內容.
3 liveuser 13001
				#必填參數:
13002
				#$conf["stringIn"],字串,要處理的字串.
13003
				$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$conf["targetServr"];
13004
				#$conf["keyWord"],字串,特定字串.
13005
				$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="/";
13006
				#可省略參數:
13007
				#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
13008
				#$conf["recursive"]="true";
13009
				#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
13010
				#$conf["lastResult"]=$delStrBeforeKeyWord;
13011
				#參考資料:
13012
				#無.
13013
				#備註:
13014
				#無.
13015
				$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
13016
				unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 13017
 
3 liveuser 13018
				#如果檢查執行失敗
13019
				if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 13020
 
3 liveuser 13021
					#設置執行失敗
13022
					$result["status"]="false";
226 liveuser 13023
 
3 liveuser 13024
					#設置執行錯誤訊息
13025
					$result["error"]=$delStrBeforeKeyWord;
226 liveuser 13026
 
3 liveuser 13027
					#回傳結果
13028
					return $result;
226 liveuser 13029
 
3 liveuser 13030
					}#if end
226 liveuser 13031
 
3 liveuser 13032
				#如果該存在的 / 不存在
13033
				if($delStrBeforeKeyWord["founded"]==="false"){
226 liveuser 13034
 
3 liveuser 13035
					#設置執行失敗
13036
					$result["status"]="false";
226 liveuser 13037
 
3 liveuser 13038
					#設置執行錯誤訊息
13039
					$result["error"]=$delStrBeforeKeyWord;
226 liveuser 13040
 
3 liveuser 13041
					#回傳結果
13042
					return $result;
226 liveuser 13043
 
3 liveuser 13044
					}#if end
226 liveuser 13045
 
3 liveuser 13046
				#設置 path
13047
				$path="/".$delStrBeforeKeyWord["content"];
226 liveuser 13048
 
3 liveuser 13049
				#如果有切出 path
13050
				if($spiltString["dataCounts"]>=2){
226 liveuser 13051
 
3 liveuser 13052
					#另存peer host name
13053
					$peerHostName=$spiltString["dataArray"][0];
226 liveuser 13054
 
3 liveuser 13055
					#更新 targetServr
13056
					$conf["targetServr"]=$peerHostName;
226 liveuser 13057
 
3 liveuser 13058
					}#if end
226 liveuser 13059
 
3 liveuser 13060
				}#if end
226 liveuser 13061
 
3 liveuser 13062
			#初始化給 stream_context_create 用的參數
13063
			$paramsForStream_context_create=array();
226 liveuser 13064
 
3 liveuser 13065
			#設置為http相關的參數
13066
			#$paramsForStream_context_create["http"]=array();
226 liveuser 13067
 
3 liveuser 13068
			#method為HEAD
13069
			#$paramsForStream_context_create["http"]["method"]="HEAD ".$path;
226 liveuser 13070
 
3 liveuser 13071
			#HTTP/1.1
13072
			#$paramsForStream_context_create["http"]["protocol_version"]="1.1";
226 liveuser 13073
 
3 liveuser 13074
			#初始化header
13075
			#$paramsForStream_context_create["http"]["header"]=array();
226 liveuser 13076
 
3 liveuser 13077
			#設置header Host
13078
			#$paramsForStream_context_create["http"]["header"][]="Host: ".$conf["targetServr"];
226 liveuser 13079
 
3 liveuser 13080
			#設置header Upgrade
13081
			#$paramsForStream_context_create["http"]["header"][]="Upgrade: websocket";
226 liveuser 13082
 
3 liveuser 13083
			#設置header Connection
13084
			#$paramsForStream_context_create["http"]["header"][]="Connection: Upgrade";
226 liveuser 13085
 
3 liveuser 13086
			#設置header Sec-WebSocket-Version
13087
			#$paramsForStream_context_create["http"]["header"][]="Sec-WebSocket-Version: 13";
226 liveuser 13088
 
3 liveuser 13089
			#設置header Sec-WebSocket-Key
13090
			#$paramsForStream_context_create["http"]["header"][]="Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==";
226 liveuser 13091
 
3 liveuser 13092
			#body content
13093
			#$paramsForStream_context_create["http"]["content"]="";
226 liveuser 13094
 
3 liveuser 13095
			#設置為ssl相關的參數
13096
			$paramsForStream_context_create["ssl"]=array();
226 liveuser 13097
 
3 liveuser 13098
			#被連線端的網域名稱
13099
			#$paramsForStream_context_create["ssl"]["peer_name"]=$conf["targetServr"];
226 liveuser 13100
 
3 liveuser 13101
			#verify_peer
13102
			#$paramsForStream_context_create["ssl"]["verify_peer"]=true;
13103
			#$paramsForStream_context_create["ssl"]["verify_peer"]=false;
226 liveuser 13104
 
3 liveuser 13105
			#verify_peer_name
13106
			#$paramsForStream_context_create["ssl"]["verify_peer_name"]=true;
13107
			#$paramsForStream_context_create["ssl"]["verify_peer_name"]=false;
226 liveuser 13108
 
3 liveuser 13109
			#allow_self_signed,允許沒有受到認可的憑證
226 liveuser 13110
			#$paramsForStream_context_create["ssl"]["allow_self_signed"]=false;
13111
 
3 liveuser 13112
			#cafile
13113
			$paramsForStream_context_create["ssl"]["cafile"]="/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem";
226 liveuser 13114
 
3 liveuser 13115
			#capath
13116
			#$paramsForStream_context_create["ssl"]["capath"]="/etc/pki/ca-trust/extracted/pem/directory-hash/";
226 liveuser 13117
 
3 liveuser 13118
			#local_cert
13119
			#$paramsForStream_context_create["ssl"]["local_cert"]="/etc/pki/tls/certs/php-selfsigned-and-key.crt";
226 liveuser 13120
 
3 liveuser 13121
			#local_pk
13122
			#$paramsForStream_context_create["ssl"]["local_pk"]="/etc/pki/tls/private/php-selfsigned.key";
226 liveuser 13123
 
3 liveuser 13124
			#capture_peer_cert
13125
			$paramsForStream_context_create["ssl"]["capture_peer_cert"]=true;
226 liveuser 13126
 
3 liveuser 13127
			#capture_peer_cert_chain
13128
			$paramsForStream_context_create["ssl"]["capture_peer_cert_chain"]=true;
226 liveuser 13129
 
3 liveuser 13130
			#security_level
13131
			#$paramsForStream_context_create["ssl"]["security_level"]=5;
226 liveuser 13132
 
3 liveuser 13133
			#如果要 debug
13134
			if($conf["debug"]==="true"){
226 liveuser 13135
 
3 liveuser 13136
				#debug
13137
				var_dump(__LINE__,$paramsForStream_context_create);
226 liveuser 13138
 
3 liveuser 13139
				}#if end
226 liveuser 13140
 
3 liveuser 13141
			#建立ssl設定
13142
			$stream_context_create=stream_context_create($paramsForStream_context_create);
226 liveuser 13143
 
3 liveuser 13144
			#如果要 debug
13145
			if($conf["debug"]==="true"){
226 liveuser 13146
 
3 liveuser 13147
				#debug
13148
				var_dump(__LINE__,$stream_context_create);
226 liveuser 13149
 
3 liveuser 13150
				}#if end
226 liveuser 13151
 
3 liveuser 13152
			#連線到 $conf["targetServr"].":".$conf["targetPort"] ,若有 error 可從 $error_code,$error_message 取得資訊, timeout 為 30 秒, connection flags 為 STREAM_CLIENT_CONNECT, 連線的屬性記載在 $stream_context_create.
13153
			$stream_socket_client=stream_socket_client("ssl://".$conf["targetServr"].":".$conf["targetPort"],$error_code,$error_message,0,STREAM_CLIENT_CONNECT,$stream_context_create);
13154
 
13155
			#如果連線到 peer 失敗
13156
			if($stream_socket_client===false){
226 liveuser 13157
 
3 liveuser 13158
				#設置執行失敗
13159
				$result["status"]="false";
226 liveuser 13160
 
3 liveuser 13161
				#設置執行錯誤訊息
13162
				$result["error"][]="stream_socket_client() failed.".PHP_EOL."Reason: ".$error_message."(".$error_code.")".PHP_EOL;
226 liveuser 13163
 
3 liveuser 13164
				#回傳結果
13165
				return $result;
226 liveuser 13166
 
3 liveuser 13167
				}#if end
226 liveuser 13168
 
3 liveuser 13169
			#取得連線的資訊
13170
			$result["info"]=stream_get_meta_data($stream_socket_client);
226 liveuser 13171
 
3 liveuser 13172
			#write header - start
226 liveuser 13173
 
3 liveuser 13174
			#initial header
13175
			$header="";
226 liveuser 13176
 
3 liveuser 13177
			#method、path、protocol
13178
			$header=$header."HEAD ".$path." HTTP/1.1"."\r\n";
226 liveuser 13179
 
3 liveuser 13180
			#Host
13181
			$header=$header."Host: ".$conf["targetServr"]."\r\n";
226 liveuser 13182
 
3 liveuser 13183
			#Upgrade
13184
			$header=$header."Upgrade: websocket"."\r\n";
226 liveuser 13185
 
3 liveuser 13186
			#Connection
13187
			$header=$header."Connection: Upgrade"."\r\n";
226 liveuser 13188
 
3 liveuser 13189
			#Sec-WebSocket-Version
13190
			$header=$header."Sec-WebSocket-Version: 13"."\r\n";
226 liveuser 13191
 
3 liveuser 13192
			#Sec-WebSocket-Key
13193
			$header=$header."Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ=="."\r\n";
226 liveuser 13194
 
13195
			#send header
3 liveuser 13196
			fwrite($stream_socket_client,$header."\r\n");
226 liveuser 13197
 
3 liveuser 13198
			#write header - close
226 liveuser 13199
 
3 liveuser 13200
			#GET server reponse
13201
			while(!feof($stream_socket_client)){
226 liveuser 13202
 
3 liveuser 13203
				#讀取內容
13204
				$fgets=fgets($stream_socket_client, 1024);
226 liveuser 13205
 
3 liveuser 13206
				#如果要 debug
13207
				if($conf["debug"]==="true"){
226 liveuser 13208
 
3 liveuser 13209
					#debug
13210
					var_dump(__LINE__,$fgets);
226 liveuser 13211
 
3 liveuser 13212
					}#if end
226 liveuser 13213
 
3 liveuser 13214
				#如果 server 已經回應要用 websocket 協定了
13215
				if(trim($fgets)==="Upgrade: websocket"){
226 liveuser 13216
 
3 liveuser 13217
					#跳出while
13218
					break;
226 liveuser 13219
 
3 liveuser 13220
					}#if end
226 liveuser 13221
 
3 liveuser 13222
				}#if end
226 liveuser 13223
 
3 liveuser 13224
			#將建立的 sock 放到 $master 陣列
13225
			$master[] = $stream_socket_client;
226 liveuser 13226
 
3 liveuser 13227
			#函式說明:
13228
			#取得目前瀏覽的頁面的路徑或執行的php程式路徑.
13229
			#回傳結果:
13230
			#$result["status"],執行是否正常,"true"代表執行成功,"false"代表執行失敗.
13231
			#$result["error"],錯誤訊息.
13232
			#$result["function"],檔前執行的函數名稱.
13233
			#$result["content"],目前瀏覽的頁面的路徑或執行的php程式路徑.
13234
			#$result["serverIp"],取得伺服器ip.
13235
			#$result["scheme"],取得與伺服器連線所使用的通訊協定.
13236
			#必填參數:
13237
			$conf["csInformation::getPathOfThisPhpFile"]["type"]="pathOnly";#想要取得的路徑類型,"full"代表完整路徑,"pathOnly"代表只要路徑,"lastLayer"代表上一層目錄的名稱
13238
			#必填參數:
13239
			#無.
13240
			#可省略參數:
13241
			#無.
13242
			#參考資料:
13243
			#http://blog.longwin.com.tw/2009/01/php-get-directory-file-path-dirname-2008/
13244
			#備註:
13245
			#無.
13246
			$getPathOfThisPhpFile=csInformation::getPathOfThisPhpFile($conf["csInformation::getPathOfThisPhpFile"]);
13247
			unset($conf["csInformation::getPathOfThisPhpFile"]);
226 liveuser 13248
 
3 liveuser 13249
			#如果執行失敗
13250
			if($getPathOfThisPhpFile["status"]=="false"){
226 liveuser 13251
 
3 liveuser 13252
				#設置錯誤識別
13253
				$result["status"]="false";
226 liveuser 13254
 
3 liveuser 13255
				#設置錯誤訊息
13256
				$result["error"]=$getPathOfThisPhpFile;
226 liveuser 13257
 
3 liveuser 13258
				#回傳結果
13259
				return $result;
226 liveuser 13260
 
3 liveuser 13261
				}#if end
226 liveuser 13262
 
3 liveuser 13263
			#函式說明:
13264
			#使用 linux 的 uuid 指令來產生 uuid 字串
13265
			#回傳結果:
13266
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
13267
			#$result["error"],錯誤訊息.
13268
			#$result["function"],當前執行的函式名稱.
13269
			#$result["content"],uuid.
13270
			#必填參數:
13271
			#無.
13272
			#可省略參數:
13273
			#無.
13274
			#參考資料:
13275
			#無.
13276
			#備註:
13277
			#無.
13278
			$uuid=cmd::uuid();
226 liveuser 13279
 
3 liveuser 13280
			#如果執行失敗
13281
			if($uuid["status"]=="false"){
226 liveuser 13282
 
3 liveuser 13283
				#設置錯誤識別
13284
				$result["status"]="false";
226 liveuser 13285
 
3 liveuser 13286
				#設置錯誤訊息
13287
				$result["error"]=$uuid;
226 liveuser 13288
 
3 liveuser 13289
				#回傳結果
13290
				return $result;
226 liveuser 13291
 
3 liveuser 13292
				}#if end
226 liveuser 13293
 
3 liveuser 13294
			#設置存放socket的path
13295
			$socketPath=$getPathOfThisPhpFile["content"]."var/webSock::clientDaemon";
226 liveuser 13296
 
3 liveuser 13297
			#讓存放unix domain socket的路徑存在
13298
			#函式說明:
13299
			#確保路徑存在.
13300
			#回傳結果:
13301
			#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
13302
			#$result["error"],錯誤訊息陣列.
13303
			#$resutl["function"],當前執行的涵式名稱.
13304
			#$result["path"],建立好的路徑字串.
13305
			#$result["fileName"],檔案名稱,若 $conf["haveFileName"] 為 "true" 則會回傳.
13306
			#$result["argu"],使用的參數.
13307
			#必填參數:
13308
			#$conf["path"],要檢查的路徑
13309
			$conf["fileAccess::validatePath"]["path"]=$socketPath;
13310
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
13311
			$conf["fileAccess::validatePath"]["fileArgu"]=__FILE__;
13312
			#可省略參數:
13313
			#$conf["haveFileName"],字串,"true"代表有$conf["path"]檔案名稱,"false"代表$conf["path"]為純路徑,預設為"false".
13314
			$conf["fileAccess::validatePath"]["haveFileName"]="false";
13315
			#$conf["dirPermission"],字串,新建資料夾的權限設定,預設爲0770,亦即擁有者,同群組者可以讀,寫,存取,其他人無法使用.
13316
			#$conf["dirPermission"]="";
13317
			#$conf["web"],是否為檔案系統,"true"為網頁路徑,"false"為網頁系統,預設為"false".
13318
			$conf["fileAccess::validatePath"]["web"]="false";
13319
			#參考資料:
13320
			#無.
13321
			#備註:
13322
			#無.
13323
			$validatePath=fileAccess::validatePath($conf["fileAccess::validatePath"]);
13324
			unset($conf["fileAccess::validatePath"]);
226 liveuser 13325
 
3 liveuser 13326
			#如果執行失敗
13327
			if($validatePath["status"]==="false"){
226 liveuser 13328
 
3 liveuser 13329
				#設置錯誤識別
13330
				$result["status"]="false";
226 liveuser 13331
 
3 liveuser 13332
				#設置錯誤訊息
13333
				$result["error"]=$validatePath;
226 liveuser 13334
 
3 liveuser 13335
				#回傳結果
13336
				return $result;
226 liveuser 13337
 
3 liveuser 13338
				}#if end
226 liveuser 13339
 
3 liveuser 13340
			#變更 working dir
13341
			$chdir=chdir($socketPath);
226 liveuser 13342
 
3 liveuser 13343
			#設置sock檔案名稱
13344
			$socketName=$uuid["content"].".sock";
226 liveuser 13345
 
3 liveuser 13346
			#設置sock檔案位置與名稱
13347
			$socketAddr=$socketPath."/".$socketName;
226 liveuser 13348
 
3 liveuser 13349
			#如果要 debug
13350
			if($conf["debug"]==="true"){
226 liveuser 13351
 
3 liveuser 13352
				#debug
13353
				var_dump(__LINE__,$socketAddr);
226 liveuser 13354
 
3 liveuser 13355
				}#if end
226 liveuser 13356
 
3 liveuser 13357
			#建立 unix domain socket
13358
			$usock=stream_socket_server("unix://".$socketName, $errno, $errstr);
226 liveuser 13359
 
3 liveuser 13360
			#如果建立 unix domain socket 失敗
13361
			if(!$usock){
226 liveuser 13362
 
3 liveuser 13363
				#設置執行失敗
13364
				$result["status"]="false";
226 liveuser 13365
 
3 liveuser 13366
				#設置錯誤訊息
13367
				$result["error"][]=$errstr." (".$errno.")";
226 liveuser 13368
 
3 liveuser 13369
				#設置錯誤訊息
13370
				$result["error"][]="建立 unix domain socket(".$socketAddr.") 失敗";
226 liveuser 13371
 
3 liveuser 13372
				#回傳結果
13373
				return $result;
226 liveuser 13374
 
3 liveuser 13375
				}#if end
226 liveuser 13376
 
3 liveuser 13377
			#印出socket addr
13378
			echo "unixDomainSocket:".$socketAddr;
226 liveuser 13379
 
3 liveuser 13380
			#將建立的 unix domain socket 放到 $master 陣列
13381
			$master[] = $usock;
226 liveuser 13382
 
3 liveuser 13383
			#永久監聽, 不 timeout
13384
			while(true){
226 liveuser 13385
 
3 liveuser 13386
				#設置給 stream_select 監控的 sock 變數
13387
				$read = $write = $except = $master;
226 liveuser 13388
 
3 liveuser 13389
				#等待1秒,看有沒有連線進來讀寫資料
13390
				$mod_fd = stream_select($read, $write, $except, 1);
226 liveuser 13391
 
3 liveuser 13392
				#如果沒有偵測到讀寫動作失敗
13393
				if($mod_fd===FALSE){
226 liveuser 13394
 
3 liveuser 13395
					#關閉 web socket 連線
13396
					@fclose($stream_socket_client);
226 liveuser 13397
 
3 liveuser 13398
					#關閉unix domain socket
13399
					@fclose($usock);
226 liveuser 13400
 
3 liveuser 13401
					#移除unix domain socket
13402
					@unlink($socketAddr);
226 liveuser 13403
 
3 liveuser 13404
					#設置執行失敗
13405
					$result["status"]="false";
226 liveuser 13406
 
3 liveuser 13407
					#設置錯誤訊息
13408
					$result["error"][]="監聽資源異動失敗";
226 liveuser 13409
 
3 liveuser 13410
					#回傳結果
13411
					return $result;
226 liveuser 13412
 
3 liveuser 13413
					}#if end
226 liveuser 13414
 
3 liveuser 13415
				#如果沒有訊息,代表閒置時可以做的事情
13416
				else if($mod_fd===0){
226 liveuser 13417
 
3 liveuser 13418
					#代表沒收到訊息
13419
					echo ".";
226 liveuser 13420
 
3 liveuser 13421
					}#if end
226 liveuser 13422
 
3 liveuser 13423
				#反之有收到來自 web socket server 或 unix socket 的訊息
13424
				else{
226 liveuser 13425
 
3 liveuser 13426
					#針對每個 sock 陣列
13427
					foreach($read as $readStream){
226 liveuser 13428
 
3 liveuser 13429
						#如果是來自 web socket server 的訊息
13430
						if($readStream===$stream_socket_client){
226 liveuser 13431
 
3 liveuser 13432
							#當等待別人連線時,若有人連線進來.
13433
							#$webConn = stream_socket_accept($stream_socket_client);
226 liveuser 13434
 
3 liveuser 13435
							#如果要 debug
13436
							if($conf["debug"]==="true"){
226 liveuser 13437
 
3 liveuser 13438
								#debug
13439
								var_dump(__LINE__,"有收到來自 web socket server 的訊息");
226 liveuser 13440
 
3 liveuser 13441
								}#if end
226 liveuser 13442
 
3 liveuser 13443
							#讀取內容
13444
							$fread=fread($stream_socket_client,1024);
226 liveuser 13445
 
3 liveuser 13446
							#如果要 debug
13447
							if($conf["debug"]==="true"){
226 liveuser 13448
 
3 liveuser 13449
								#debug
13450
								var_dump(__LINE__,strlen($fread),$fread);
226 liveuser 13451
 
3 liveuser 13452
								}#if end
226 liveuser 13453
 
3 liveuser 13454
							#函式說明:
13455
							#將 handshake 後含有 mask bit 的 web socket 訊息進行  mask/unmask.
13456
							#回傳結果:
13457
							#$result["function"],當前函式的名稱.
13458
							#$result["argu"],使用的參數.
13459
							#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
13460
							#$result["content"],unmask後的內容.
13461
							#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame.
13462
							#$result["error"],錯誤訊息陣列.
13463
							#必填參數:
13464
							#$conf["payload"],字串,要解密的訊息.
226 liveuser 13465
							$conf["webSock::unmask"]["payload"]=$fread;
3 liveuser 13466
							#可省略參數:
13467
							#$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
13468
							$conf["webSock::unmask"]["allowUnmask"]="true";
13469
							#$conf["webSock::unmask"]["debug"]="true";
13470
							#參考資料
13471
							#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
13472
							#https://tools.ietf.org/html/rfc6455
13473
							#https://tools.ietf.org/html/rfc5234
13474
							#備註:
13475
							#無.
13476
							$unmask=webSock::unmask($conf["webSock::unmask"]);
13477
							unset($conf["webSock::unmask"]);
226 liveuser 13478
 
3 liveuser 13479
							#debug
13480
							#var_dump(__LINE__,$unmask);
226 liveuser 13481
 
3 liveuser 13482
							#如果出錯
13483
							if($unmask["status"]==="false"){
226 liveuser 13484
 
3 liveuser 13485
								#關閉 web socket 連線
13486
								@fclose($stream_socket_client);
226 liveuser 13487
 
3 liveuser 13488
								#關閉unix domain socket
13489
								@fclose($usock);
226 liveuser 13490
 
3 liveuser 13491
								#移除unix domain socket
13492
								@unlink($socketAddr);
226 liveuser 13493
 
3 liveuser 13494
								#設置執行失敗
13495
								$result["status"]="false";
226 liveuser 13496
 
3 liveuser 13497
								#設置執行錯誤訊息
13498
								$result["error"]=$unmask;
226 liveuser 13499
 
3 liveuser 13500
								#回傳結果
13501
								return $result;
226 liveuser 13502
 
3 liveuser 13503
								}#if end
226 liveuser 13504
 
3 liveuser 13505
							#如果收到文字訊息
13506
							if($unmask["type"]==="text"){
226 liveuser 13507
 
3 liveuser 13508
								#如果有解析出內容
13509
								if(isset($unmask["content"])){
226 liveuser 13510
 
3 liveuser 13511
									#提示收到的訊息
13512
									echo $unmask["content"];
226 liveuser 13513
 
3 liveuser 13514
									#傳遞給unix domain client
13515
									$fwrite=fwrite($unixConn,$unmask["content"]);
226 liveuser 13516
 
3 liveuser 13517
									#如果要 debug
13518
									if($conf["debug"]==="true"){
226 liveuser 13519
 
3 liveuser 13520
										#debug
13521
										var_dump(__LINE__,$fwrite);
226 liveuser 13522
 
3 liveuser 13523
										}#if end
226 liveuser 13524
 
3 liveuser 13525
									#關閉連線
13526
									fclose($unixConn);
226 liveuser 13527
 
3 liveuser 13528
									}#if end
226 liveuser 13529
 
3 liveuser 13530
								}#if end
226 liveuser 13531
 
3 liveuser 13532
							#如果收到ping
13533
							if($unmask["type"]==="ping"){
226 liveuser 13534
 
3 liveuser 13535
								#函式說明:
226 liveuser 13536
								#加密 handshake 後要傳送的 webSocket 訊息
3 liveuser 13537
								#回傳結果:
13538
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
13539
								#$result["error"],執行不正常結束的錯訊息陣列.
13540
								#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
13541
								#$result["argu"],陣列,使用的參數.
13542
								#必填參數:
13543
								#$conf["text"],字串,要加密的訊息.
226 liveuser 13544
								$conf["webSock::encode"]["text"]="";
3 liveuser 13545
								#可省略參數:
13546
								#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
13547
								#$conf["ping"]="true";
13548
								#$conf["pong"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
13549
								$conf["webSock::encode"]["pong"]="true";
13550
								#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
13551
								#$conf["frames"]=array();
13552
								#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
13553
								$conf["webSock::encode"]["mask"]="true";
13554
								#參考資料:
13555
								#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
13556
								#備註:
13557
								#無.
13558
								$encode=webSock::encode($conf["webSock::encode"]);
13559
								unset($conf["webSock::encode"]);
226 liveuser 13560
 
3 liveuser 13561
								#如果要 debug
13562
								if($conf["debug"]==="true"){
226 liveuser 13563
 
3 liveuser 13564
									#debug
13565
									var_dump(__LINE__,$encode);
226 liveuser 13566
 
3 liveuser 13567
									}#if end
226 liveuser 13568
 
3 liveuser 13569
								#如果出錯
13570
								if($encode["status"]==="false"){
226 liveuser 13571
 
3 liveuser 13572
									#設置執行失敗
13573
									$result["status"]="false";
226 liveuser 13574
 
3 liveuser 13575
									#設置執行錯誤訊息
13576
									$result["error"]=$encode;
226 liveuser 13577
 
3 liveuser 13578
									#回傳結果
13579
									return $result;
226 liveuser 13580
 
3 liveuser 13581
									}#if end
226 liveuser 13582
 
3 liveuser 13583
								#如果要 debug
13584
								if($conf["debug"]==="true"){
226 liveuser 13585
 
3 liveuser 13586
									#debug
13587
									var_dump(__LINE__,$encode);
226 liveuser 13588
 
3 liveuser 13589
									}#if end
226 liveuser 13590
 
3 liveuser 13591
								#針對每個 frame
13592
								foreach($encode["content"] as $fNo => $frame){
226 liveuser 13593
 
3 liveuser 13594
									#傳遞給 web socket server
13595
									$fwrite=fwrite($stream_socket_client,$frame);
226 liveuser 13596
 
3 liveuser 13597
									#如果傳遞失敗
13598
									if($fwrite===false){
226 liveuser 13599
 
3 liveuser 13600
										#關閉 web socket 連線
13601
										@fclose($stream_socket_client);
226 liveuser 13602
 
3 liveuser 13603
										#關閉unix domain socket
13604
										@fclose($usock);
226 liveuser 13605
 
3 liveuser 13606
										#移除unix domain socket
13607
										@unlink($socketAddr);
226 liveuser 13608
 
3 liveuser 13609
										#設置執行失敗
13610
										$result["status"]="false";
226 liveuser 13611
 
3 liveuser 13612
										#設置執行錯誤訊息
13613
										$result["error"][]="傳遞第 ".($fNo+1)." 個 frame 時出錯(總共有".count($encode["content"])."個frame)";
226 liveuser 13614
 
3 liveuser 13615
										#回傳結果
13616
										return $result;
226 liveuser 13617
 
3 liveuser 13618
										}#if end
226 liveuser 13619
 
3 liveuser 13620
									}#foreach end
226 liveuser 13621
 
3 liveuser 13622
								}#if end
226 liveuser 13623
 
3 liveuser 13624
							}#if end
226 liveuser 13625
 
3 liveuser 13626
						#反之若為來自 unix domain socket 的訊息
13627
						else if($readStream===$usock){
226 liveuser 13628
 
3 liveuser 13629
							#當等待別人連線時,若有人連線進來.
13630
							$unixConn = stream_socket_accept($usock);
226 liveuser 13631
 
3 liveuser 13632
							#如果要 debug
13633
							if($conf["debug"]==="true"){
226 liveuser 13634
 
3 liveuser 13635
								#debug
13636
								var_dump(__LINE__,"有收到來自 unix domain socket 的訊息");
226 liveuser 13637
 
3 liveuser 13638
								}#if end
226 liveuser 13639
 
3 liveuser 13640
							#讀取內容
13641
							$fgets=trim(fgets($unixConn,1024));
226 liveuser 13642
 
3 liveuser 13643
							#如果要 debug
13644
							if($conf["debug"]==="true"){
226 liveuser 13645
 
3 liveuser 13646
								#debug
13647
								var_dump(__LINE__,strlen($fgets),$fgets);
226 liveuser 13648
 
3 liveuser 13649
								}#if end
226 liveuser 13650
 
3 liveuser 13651
							#轉換成 web socket 的格式
13652
							#函式說明:
226 liveuser 13653
							#加密 handshake 後要傳送的 webSocket 訊息
3 liveuser 13654
							#回傳結果:
13655
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
13656
							#$result["error"],執行不正常結束的錯訊息陣列.
13657
							#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
13658
							#$result["argu"],陣列,使用的參數.
13659
							#必填參數:
13660
							#$conf["text"],字串,要加密的訊息.
226 liveuser 13661
							$conf["webSock::encode"]["text"]=$fgets;
3 liveuser 13662
							#可省略參數:
13663
							#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
13664
							#$conf["ping"]="true";
13665
							#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
13666
							#$conf["frames"]=array();
13667
							#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
13668
							$conf["webSock::encode"]["mask"]="true";
13669
							#參考資料:
13670
							#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
13671
							#備註:
13672
							#無.
13673
							$encode=webSock::encode($conf["webSock::encode"]);
13674
							unset($conf["webSock::encode"]);
226 liveuser 13675
 
3 liveuser 13676
							#如果要 debug
13677
							if($conf["debug"]==="true"){
226 liveuser 13678
 
3 liveuser 13679
								#debug
13680
								var_dump(__LINE__,$encode);
226 liveuser 13681
 
3 liveuser 13682
								}#if end
226 liveuser 13683
 
3 liveuser 13684
							#如果出錯
13685
							if($encode["status"]==="false"){
226 liveuser 13686
 
3 liveuser 13687
								#設置執行失敗
13688
								$result["status"]="false";
226 liveuser 13689
 
3 liveuser 13690
								#設置執行錯誤訊息
13691
								$result["error"]=$encode;
226 liveuser 13692
 
3 liveuser 13693
								#回傳結果
13694
								return $result;
226 liveuser 13695
 
3 liveuser 13696
								}#if end
226 liveuser 13697
 
3 liveuser 13698
							#針對每個frame
13699
							foreach($encode["content"] as $fNo => $frame){
226 liveuser 13700
 
3 liveuser 13701
								#傳遞給 web socket server
13702
								$fwrite=fwrite($stream_socket_client,$frame);
226 liveuser 13703
 
3 liveuser 13704
								#如果要 debug
13705
								if($conf["debug"]==="true"){
226 liveuser 13706
 
3 liveuser 13707
									#debug
13708
									var_dump(__LINE__,$fwrite,"傳遞".strlen($frame)."bytes給webSocketServer",$frame);
226 liveuser 13709
 
3 liveuser 13710
									}#if end
226 liveuser 13711
 
3 liveuser 13712
								#如果傳遞失敗
13713
								if($fwrite===false){
226 liveuser 13714
 
3 liveuser 13715
									#關閉 web socket 連線
13716
									@fclose($stream_socket_client);
226 liveuser 13717
 
3 liveuser 13718
									#關閉unix domain socket
13719
									@fclose($usock);
226 liveuser 13720
 
3 liveuser 13721
									#移除unix domain socket
13722
									@unlink($socketAddr);
226 liveuser 13723
 
3 liveuser 13724
									#設置執行失敗
13725
									$result["status"]="false";
226 liveuser 13726
 
3 liveuser 13727
									#設置執行錯誤訊息
13728
									$result["error"][]="傳遞第 ".($fNo+1)." 個 frame 時出錯(總共有".count($encode["content"])."個frame)";
226 liveuser 13729
 
3 liveuser 13730
									#回傳結果
13731
									return $result;
226 liveuser 13732
 
3 liveuser 13733
									}#if end
226 liveuser 13734
 
3 liveuser 13735
								}#foreach end
226 liveuser 13736
 
3 liveuser 13737
							}#if end
226 liveuser 13738
 
3 liveuser 13739
						#例外狀況
13740
						else{
226 liveuser 13741
 
3 liveuser 13742
							#如果要 debug
13743
							if($conf["debug"]==="true"){
226 liveuser 13744
 
3 liveuser 13745
								#debug
13746
								var_dump(__LINE__,$readStream);
226 liveuser 13747
 
3 liveuser 13748
								}#if end
226 liveuser 13749
 
3 liveuser 13750
							#關閉 web socket 連線
13751
							@fclose($stream_socket_client);
226 liveuser 13752
 
3 liveuser 13753
							#關閉unix domain socket
13754
							@fclose($usock);
226 liveuser 13755
 
3 liveuser 13756
							#移除unix domain socket
13757
							@unlink($socketAddr);
226 liveuser 13758
 
3 liveuser 13759
							#顯示 socket 的狀態
13760
							echo "非預期的錯誤,偵測到不應存在資源有異動".PHP_EOL;
226 liveuser 13761
 
3 liveuser 13762
							#結束執行並回傳1,代表異常結束
13763
							exit(1);
226 liveuser 13764
 
3 liveuser 13765
							}#else end
226 liveuser 13766
 
3 liveuser 13767
						}#foreach end
226 liveuser 13768
 
3 liveuser 13769
					}#else
226 liveuser 13770
 
3 liveuser 13771
				#等待1秒
13772
				sleep(1);
226 liveuser 13773
 
3 liveuser 13774
				}#while end
226 liveuser 13775
 
3 liveuser 13776
			#設置執行正常
13777
			$result["status"]="true";
226 liveuser 13778
 
3 liveuser 13779
			#回傳結果
13780
			return $result;
226 liveuser 13781
 
3 liveuser 13782
			}#if end
226 liveuser 13783
 
3 liveuser 13784
		#反之不用
13785
		else{
226 liveuser 13786
 
3 liveuser 13787
			#如果要 debug
13788
			if($conf["debug"]==="true"){
226 liveuser 13789
 
3 liveuser 13790
				#提示用戶端的文字
13791
				echo "TCP/IP Connection".PHP_EOL;
13792
 
13793
				}#if end
13794
 
13795
			/* Get the port for the WWW service. */
13796
			#http://php.net/manual/en/function.getservbyname.php
13797
			#$service_port = getservbyname('www', 'tcp');
226 liveuser 13798
 
3 liveuser 13799
			/* Get the IP address for the target host. */
13800
			#http://php.net/manual/en/function.gethostbyname.php
13801
			$ServerAddress = gethostbyname($conf["targetServr"]);
13802
 
13803
			/* Create a TCP/IP socket. */
13804
			$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
226 liveuser 13805
 
3 liveuser 13806
			#如果建立 socket 失敗
13807
			if ($socket === false) {
226 liveuser 13808
 
3 liveuser 13809
				#設置執行失敗
13810
				$result["status"]="false";
226 liveuser 13811
 
3 liveuser 13812
				#設置執行錯誤訊息
13813
				$result["error"][]="socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
226 liveuser 13814
 
3 liveuser 13815
				#回傳結果
13816
				return $result;
226 liveuser 13817
 
3 liveuser 13818
				}#if end
226 liveuser 13819
 
3 liveuser 13820
			#反之
13821
			else {
226 liveuser 13822
 
3 liveuser 13823
				#如果要 debug
13824
				if($conf["debug"]==="true"){
226 liveuser 13825
 
3 liveuser 13826
					#印出建立成功訊息
13827
					echo "OK.".PHP_EOL;
226 liveuser 13828
 
3 liveuser 13829
					}#if end
226 liveuser 13830
 
3 liveuser 13831
				}#else end
226 liveuser 13832
 
3 liveuser 13833
			#如果要 debug
13834
			if($conf["debug"]==="true"){
226 liveuser 13835
 
3 liveuser 13836
				#提示要連線到哪個位址的哪個port
13837
				echo "Attempting to connect to ".$ServerAddress." on port ".$conf["targetPort"]."...";
226 liveuser 13838
 
3 liveuser 13839
				}#if end
226 liveuser 13840
 
3 liveuser 13841
			#連線到目標 socket
13842
			$socket_connect=socket_connect($socket, $ServerAddress, $conf["targetPort"]);
226 liveuser 13843
 
3 liveuser 13844
			#如果連線到 socket 失敗
13845
			if($socket_connect===false){
226 liveuser 13846
 
3 liveuser 13847
				#設置執行失敗
13848
				$result["status"]="false";
226 liveuser 13849
 
3 liveuser 13850
				#設置執行錯誤訊息
13851
				$result["error"][]="socket_connect() failed.".PHP_EOL."Reason: ($socket_connect) " . socket_strerror(socket_last_error($socket)) . PHP_EOL;
226 liveuser 13852
 
3 liveuser 13853
				#回傳結果
13854
				return $result;
226 liveuser 13855
 
3 liveuser 13856
				}#if end
226 liveuser 13857
 
3 liveuser 13858
			#反之
13859
			else {
226 liveuser 13860
 
3 liveuser 13861
				#如果要 debug
13862
				if($conf["debug"]==="true"){
226 liveuser 13863
 
3 liveuser 13864
					#印出連線成功訊息
13865
					echo "OK.".PHP_EOL;
226 liveuser 13866
 
3 liveuser 13867
					}#if end
226 liveuser 13868
 
3 liveuser 13869
				}#else end
226 liveuser 13870
 
3 liveuser 13871
			}#else end
226 liveuser 13872
 
3 liveuser 13873
		#初始化要傳送的HEAD資訊
13874
		$in="HEAD / HTTP/1.1"."\r\n";
13875
		$in=$in."Host: ".$ServerAddress.":".$conf["targetPort"]."\r\n";
13876
		$in=$in."Upgrade: websocket"."\r\n";
13877
		$in=$in."Connection: Upgrade"."\r\n";
13878
		$in=$in."Sec-WebSocket-Version: 13"."\r\n";
13879
		$in=$in."Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ=="."\r\n";
13880
		$in=$in."\r\n";
226 liveuser 13881
 
3 liveuser 13882
		#初始化回傳的內容
13883
		$out = '';
13884
 
13885
		#如果連線到 socket 失敗
13886
		if($socket_connect===false){
13887
 
13888
			#提示傳送HTTP HEAD中
13889
			echo "Sending HTTP HEAD request...";
226 liveuser 13890
 
3 liveuser 13891
			}#if end
226 liveuser 13892
 
3 liveuser 13893
		#將訊息傳送到socket去
13894
		socket_write($socket, $in, strlen($in));
226 liveuser 13895
 
3 liveuser 13896
		#如果連線到 socket 失敗
13897
		if($socket_connect===false){
226 liveuser 13898
 
3 liveuser 13899
			#提示傳送完畢
13900
			echo "OK.".PHP_EOL;
13901
 
13902
			#提示讀取回應中
13903
			echo "Reading response:".PHP_EOL;
226 liveuser 13904
 
3 liveuser 13905
			}#if end
226 liveuser 13906
 
3 liveuser 13907
		#無窮迴圈
13908
		while(true){
226 liveuser 13909
 
3 liveuser 13910
			#一次讀取2048bytes,判斷有無回應,並取得其內容.
13911
			$out = socket_read($socket, 2048);
226 liveuser 13912
 
3 liveuser 13913
			#如果尚未取得 Sec-WebSocket-Accept
13914
			if(!isset($result["Sec-WebSocket-Accept"])){
226 liveuser 13915
 
3 liveuser 13916
				#如果連線到 socket 失敗
13917
				if($socket_connect===false){
226 liveuser 13918
 
3 liveuser 13919
					#印出收到的內容
13920
					echo $out;
226 liveuser 13921
 
3 liveuser 13922
					}#if end
226 liveuser 13923
 
3 liveuser 13924
				#如果 $out 有資料
13925
				if($out){
226 liveuser 13926
 
3 liveuser 13927
					#如果接收到的是字串,且不為空
13928
					if(gettype($out)==="string" && !empty($out)){
226 liveuser 13929
 
3 liveuser 13930
						#如果有既有的前次回應內容
13931
						if(isset($result["content"])){
226 liveuser 13932
 
3 liveuser 13933
							#儲存回應的內容
13934
							$result["content"]=$result["content"].$out;
226 liveuser 13935
 
3 liveuser 13936
							}#if end
226 liveuser 13937
 
3 liveuser 13938
						#反之
13939
						else{
226 liveuser 13940
 
3 liveuser 13941
							#儲存回應的內容
13942
							$result["content"]=$out;
226 liveuser 13943
 
3 liveuser 13944
							}#else end
226 liveuser 13945
 
3 liveuser 13946
						#涵式說明:
13947
						#將固定格式的字串分開,並回傳分開的結果。
13948
						#回傳結果:
13949
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
13950
						#$result["error"],錯誤訊息陣列
13951
						#$result["function"],當前執行的函數名稱.
13952
						#$result["argu"],使用的參數.
13953
						#$result["oriStr"],要分割的原始字串內容
13954
						#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
13955
						#$result["dataCounts"],爲總共分成幾段
13956
						#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
13957
						#必填的參數:
13958
						#$conf["stringIn"],字串,要處理的字串.
13959
						$conf["stringProcess::spiltString"]["stringIn"]=$out;
13960
						#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
13961
						$conf["stringProcess::spiltString"]["spiltSymbol"]="Sec-WebSocket-Accept: ";
13962
						#可省略參數:
13963
						#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
13964
						$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
13965
						$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
13966
						unset($conf["stringProcess::spiltString"]);
226 liveuser 13967
 
3 liveuser 13968
						#如果執行失敗
13969
						if($spiltString["status"]==="false"){
226 liveuser 13970
 
3 liveuser 13971
							#設置執行失敗
13972
							$result["status"]="false";
226 liveuser 13973
 
3 liveuser 13974
							#設置執行錯誤訊息
13975
							$result["error"]=$spiltString;
226 liveuser 13976
 
3 liveuser 13977
							#回傳結果
13978
							return $result;
226 liveuser 13979
 
3 liveuser 13980
							}#if end
226 liveuser 13981
 
3 liveuser 13982
						#取得Sec-WebSocket-Accept
13983
						$result["Sec-WebSocket-Accept"]=trim($spiltString["dataArray"][1]);
226 liveuser 13984
 
13985
						#初始化要傳遞的內容
3 liveuser 13986
						$in="id?";
226 liveuser 13987
 
3 liveuser 13988
						#初始化傳遞的內容長度
13989
						$len=strlen($in);
226 liveuser 13990
 
3 liveuser 13991
						#設置儲存每個元素為8bit字串的陣列
13992
						$bit8=array();
13993
						$bit8[0]="10000001";
13994
						$bit8[1]="1".sprintf("%07s",base_convert($len,10,2));
226 liveuser 13995
 
3 liveuser 13996
						#mask key
13997
						$bit8[2]="00000000";
13998
						$bit8[3]="00000000";
13999
						$bit8[4]="00000000";
14000
						$bit8[5]="00000000";
226 liveuser 14001
 
3 liveuser 14002
						#mask key
14003
						$mask_key=$bit8[2].$bit8[3].$bit8[4].$bit8[5];
226 liveuser 14004
 
3 liveuser 14005
						#針對每個字,進行mask
14006
						for($i=0;$i<$len;$i++){
226 liveuser 14007
 
3 liveuser 14008
							$j=$i%4;
226 liveuser 14009
 
3 liveuser 14010
							$in[$i]=$in[$i] xor $mask_key[$j];
226 liveuser 14011
 
3 liveuser 14012
							}#for end
226 liveuser 14013
 
3 liveuser 14014
						#如果連線到 socket 失敗
14015
						if($socket_connect===false){
226 liveuser 14016
 
3 liveuser 14017
							#提示傳送資料
14018
							echo "Sending Data...".PHP_EOL;
226 liveuser 14019
 
3 liveuser 14020
							}#if end
226 liveuser 14021
 
3 liveuser 14022
						#data frame
14023
						$in=chr(base_convert($bit8[0],2,10)).chr(base_convert($bit8[1],2,10)).chr(base_convert($bit8[2],2,10)).chr(base_convert($bit8[3],2,10)).chr(base_convert($bit8[4],2,10)).chr(base_convert($bit8[5],2,10)).$in;
226 liveuser 14024
 
3 liveuser 14025
						#將訊息傳送到socket去
14026
						socket_write($socket, $in, strlen($in));
226 liveuser 14027
 
3 liveuser 14028
						}#if end
226 liveuser 14029
 
14030
					}#if end
14031
 
3 liveuser 14032
				}#if end
226 liveuser 14033
 
3 liveuser 14034
			#反之取得了 Sec-WebSocket-Accept 就結束 HTTP/1.1
14035
			else{
226 liveuser 14036
 
3 liveuser 14037
				#如果連線到 socket 失敗
14038
				if($socket_connect===false){
226 liveuser 14039
 
3 liveuser 14040
					echo "解密前的內容:".PHP_EOL;
226 liveuser 14041
 
3 liveuser 14042
					}#if end
226 liveuser 14043
 
3 liveuser 14044
				#函式說明:
14045
				#將字串中的每個字變成bytes陣列
14046
				#回傳結果:
14047
				#$result...
14048
				#必填參數:
14049
				#$conf["input"],字串,要轉換成bytes陣列的字串
14050
				$conf["stringProcess::str2bytesArray"]["input"]=$out;
14051
				#可省略參數:
14052
				#無
14053
				#建構中...
14054
				$str2bytesArray=stringProcess::str2bytesArray($conf["stringProcess::str2bytesArray"]);
14055
				unset($conf["stringProcess::str2bytesArray"]);
226 liveuser 14056
 
14057
				#針對每個bytes
3 liveuser 14058
				foreach($str2bytesArray["content"] as $byte){
226 liveuser 14059
 
3 liveuser 14060
					#函式說明:
14061
					#將bytes數字轉換為bit字串(0跟1來表述)
14062
					#回傳結果:
14063
					#$result...
14064
					#必填參數:
14065
					#$conf["input"],字串,要轉換成byte的字串
14066
					$conf["stringProcess::str2bytesArray"]["bytes"]=$byte;
14067
					#可省略參數:
14068
					#無
14069
					#建構中...
14070
					$bytes2bitString=stringProcess::bytes2bitString($conf["stringProcess::str2bytesArray"]);
14071
					unset($conf["stringProcess::str2bytesArray"]);
226 liveuser 14072
 
3 liveuser 14073
					#如果連線到 socket 失敗
14074
					if($socket_connect===false){
226 liveuser 14075
 
3 liveuser 14076
						#debug
14077
						var_dump($bytes2bitString["content"]);
226 liveuser 14078
 
3 liveuser 14079
						}#if end
226 liveuser 14080
 
3 liveuser 14081
					}#foreach end
226 liveuser 14082
 
3 liveuser 14083
				#如果連線到 socket 失敗
14084
				if($socket_connect===false){
226 liveuser 14085
 
3 liveuser 14086
					echo "解密後接收的內容:".PHP_EOL;
226 liveuser 14087
 
3 liveuser 14088
					}#if end
226 liveuser 14089
 
3 liveuser 14090
				#函式說明:
14091
				#解密 handshake 後要接收的訊息
14092
				#回傳結果:
14093
				#$result["function"],當前函式的名稱.
14094
				#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
14095
				#$result["content"],unmask後的內容.
14096
				#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame.
14097
				#$result["error"],錯誤訊息陣列.
14098
				#必填參數:
14099
				#$conf["payload"],字串,要解密的訊息.
226 liveuser 14100
				$conf["webSock::unmask"]["payload"]=$out;
3 liveuser 14101
				#可省略參數:
14102
				#$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
14103
				$conf["webSock::unmask"]["allowUnmask"]="true";
14104
				#參考資料
14105
				#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
14106
				#https://tools.ietf.org/html/rfc6455
14107
				#https://tools.ietf.org/html/rfc5234
14108
				#備註:
14109
				#無.
14110
				$unmask=webSock::unmask($conf["webSock::unmask"]);
14111
				unset($conf["webSock::unmask"]);
226 liveuser 14112
 
3 liveuser 14113
				#如果執行失敗
14114
				if($unmask["status"]==="false"){
226 liveuser 14115
 
3 liveuser 14116
					#設置執行失敗
14117
					$result["status"]="false";
226 liveuser 14118
 
3 liveuser 14119
					#設置執行錯誤訊息
14120
					$result["error"]=$unmask;
226 liveuser 14121
 
3 liveuser 14122
					#回傳結果
14123
					return $result;
226 liveuser 14124
 
3 liveuser 14125
					}#if end
226 liveuser 14126
 
3 liveuser 14127
				#記錄接收到的內容
14128
				$received=$unmask["content"];
226 liveuser 14129
 
3 liveuser 14130
				#如果連線到 socket 失敗
226 liveuser 14131
				if($socket_connect===false){
14132
 
3 liveuser 14133
					#debug
14134
					var_dump($received);
226 liveuser 14135
 
3 liveuser 14136
					}#if end
226 liveuser 14137
 
3 liveuser 14138
				}#else end
226 liveuser 14139
 
3 liveuser 14140
			#休息1秒
14141
			sleep(1);
226 liveuser 14142
 
3 liveuser 14143
			}#while end
14144
 
14145
		#如果連線到 socket 失敗
14146
		if($socket_connect===false){
14147
 
14148
			#提示關閉與 socket 的連線
14149
			echo "Closing socket...";
226 liveuser 14150
 
3 liveuser 14151
			}#if end
226 liveuser 14152
 
3 liveuser 14153
		#關閉與 socket 的連線
14154
		socket_close($socket);
226 liveuser 14155
 
3 liveuser 14156
		#如果連線到 socket 失敗
14157
		if($socket_connect===false){
226 liveuser 14158
 
3 liveuser 14159
			#提示關閉連線成功
14160
			echo "OK.".PHP_EOL;
226 liveuser 14161
 
3 liveuser 14162
			}#if end
226 liveuser 14163
 
3 liveuser 14164
		#設置執行正常
14165
		$result["status"]="true";
226 liveuser 14166
 
3 liveuser 14167
		#回傳結果
14168
		return $result;
226 liveuser 14169
 
3 liveuser 14170
		}#function clientDaemon end
226 liveuser 14171
 
14172
	/*
3 liveuser 14173
	#函式說明:
316 liveuser 14174
	#用php實作的webSocket用戶端,傳遞一次訊息就結束連線.
14175
	#回傳結果:
14176
	#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
14177
	#$result["error"],錯誤訊息陣列.
14178
	#$resutl["function"],當前執行的涵式名稱.
14179
	#$result["argu"],所使用的參數.
14180
	#必填參數:
14181
	#$conf["url"],字串要拜訪的web socket位置,請省略"ws(s)://".
14182
	$conf["url"]="";
14183
	#可省略參數:
14184
	#$conf["wss"],字串,是否要用加密的wss,預設為"true",代表用wss,若為"false"則為ws.
14185
	#$conf["wss"]="true";
14186
	#參考資料:
14187
	#無.
14188
	#備註:
14189
	#建構中...
14190
	*/
14191
	public static function PHPoneTimeClient(&$conf){
14192
 
14193
 
14194
 
14195
		}#function PHPoneTimeClient end
14196
 
14197
	/*
14198
	#函式說明:
3 liveuser 14199
	#webSocket的javaScript用戶端
14200
	#回傳結果:
14201
	#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
14202
	#$result["error"],錯誤訊息陣列.
14203
	#$resutl["function"],當前執行的涵式名稱.
14204
	#$result["argu"],所使用的參數.
14205
	#$result["content"],語法.
14206
	#必填參數:
14207
	#$conf["url"],字串要拜訪的web socket,請省略"ws://".
14208
	$conf["url"]="";
14209
	#可省略參數:
14210
	#$conf["entry"],字串,是否要用加密的wss,預設為"false",代表用ws,若為"true"則為wss.
14211
	#$conf["entry"]="false";
14212
	#$conf["connVar"],字串,用來儲存webSocket連線的物件名稱,預設為"conn".
14213
	#$conf["connVar"]="conn";
316 liveuser 14214
	#$conf["sendThenClose"],字串,是否要傳遞訊息後關閉連線,預設為"false",代表不要要;反之為"true".
14215
	#$conf["sendThenClose"]="false";
14216
	#$conf["oneTimeMsg"],字串,要傳遞的一次訊息內容,預設不指定.
14217
	#$conf["oneTimeMsg"]="";
3 liveuser 14218
	#參考資料:
14219
	#無.
14220
	#備註:
14221
	#無.
14222
	*/
14223
	public static function client(&$conf){
226 liveuser 14224
 
3 liveuser 14225
		#初始化要回傳的結果
14226
		$result=array();
14227
 
14228
		#取得當前執行的函數名稱
14229
		$result["function"]=__FUNCTION__;
14230
 
14231
		#如果沒有參數
14232
		if(func_num_args()==0){
226 liveuser 14233
 
3 liveuser 14234
			#設置執行失敗
14235
			$result["status"]="false";
226 liveuser 14236
 
3 liveuser 14237
			#設置執行錯誤訊息
14238
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 14239
 
3 liveuser 14240
			#回傳結果
14241
			return $result;
226 liveuser 14242
 
3 liveuser 14243
			}#if end
14244
 
14245
		#取得參數
14246
		$result["argu"]=$conf;
14247
 
14248
		#如果 $conf 不為陣列
14249
		if(gettype($conf)!=="array"){
226 liveuser 14250
 
3 liveuser 14251
			#設置執行失敗
14252
			$result["status"]="false";
226 liveuser 14253
 
3 liveuser 14254
			#設置執行錯誤訊息
14255
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 14256
 
3 liveuser 14257
			#如果傳入的參數為 null
14258
			if($conf===null){
226 liveuser 14259
 
3 liveuser 14260
				#設置執行錯誤訊息
14261
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 14262
 
3 liveuser 14263
				}#if end
14264
 
14265
			#回傳結果
14266
			return $result;
226 liveuser 14267
 
3 liveuser 14268
			}#if end
226 liveuser 14269
 
3 liveuser 14270
		#檢查參數
14271
		#函式說明:
14272
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
14273
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
14274
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
14275
		#$result["function"],當前執行的函式名稱.
14276
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
14277
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
14278
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
14279
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
14280
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
14281
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
14282
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
14283
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
14284
		#必填寫的參數:
14285
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
14286
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
14287
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
14288
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("url");
14289
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
14290
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
14291
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
14292
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
14293
		#可以省略的參數:
14294
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
14295
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
14296
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
14297
		#$conf["canNotBeEmpty"]=array();
14298
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
14299
		#$conf["canBeEmpty"]=array();
14300
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
14301
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
14302
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
316 liveuser 14303
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("entry","connVar","sendThenClose","oneTimeMsg");
226 liveuser 14304
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
316 liveuser 14305
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","string");
3 liveuser 14306
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
316 liveuser 14307
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("false","conn","false",null);
3 liveuser 14308
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
14309
		#$conf["arrayCountEqualCheck"][]=array();
14310
		#參考資料來源:
14311
		#array_keys=>http://php.net/manual/en/function.array-keys.php
14312
		#建議:
14313
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
14314
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
14315
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 14316
 
3 liveuser 14317
		#如果檢查參數失敗
14318
		if($checkArguments["status"]==="false"){
226 liveuser 14319
 
3 liveuser 14320
			#設置執行失敗
14321
			$result["status"]="false";
226 liveuser 14322
 
3 liveuser 14323
			#設置執行錯誤訊息
14324
			$result["error"]=$checkArguments;
226 liveuser 14325
 
3 liveuser 14326
			#回傳結果
14327
			return $result;
226 liveuser 14328
 
3 liveuser 14329
			}#if end
226 liveuser 14330
 
3 liveuser 14331
		#如果參數檢查不通過
14332
		if($checkArguments["passed"]==="false"){
226 liveuser 14333
 
3 liveuser 14334
			#設置執行失敗
14335
			$result["status"]="false";
226 liveuser 14336
 
3 liveuser 14337
			#設置執行錯誤訊息
14338
			$result["error"]=$checkArguments;
226 liveuser 14339
 
3 liveuser 14340
			#回傳結果
14341
			return $result;
226 liveuser 14342
 
14343
			}#if end
14344
 
3 liveuser 14345
		#初始化 web socket 的協定
14346
		$webSockUrl="ws://";
226 liveuser 14347
 
3 liveuser 14348
		#如果要加密
14349
		if($conf["entry"]==="true"){
226 liveuser 14350
 
3 liveuser 14351
			$webSockUrl="wss://";
226 liveuser 14352
 
3 liveuser 14353
			}#if end
226 liveuser 14354
 
316 liveuser 14355
		#初始化傳遞訊息的語法
14356
		$sendMag="";
14357
 
14358
		#如果要傳送訊息後關閉連線
14359
		if($conf["sendThenClose"]==="true"){
14360
 
14361
			#如果有設置要傳遞的訊息
14362
			if(isset($conf["oneTimeMsg"])){
14363
 
323 liveuser 14364
				#設置 json 物件
14365
				$sendMag=$sendMag."var json=".$conf["oneTimeMsg"].";".PHP_EOL;
14366
 
14367
				#設置 json 物件
14368
				$sendMag=$sendMag."var jsonStr=JSON.stringify(json);".PHP_EOL;
14369
 
316 liveuser 14370
				#設置傳遞訊息的語法
323 liveuser 14371
				$sendMag=$sendMag.$conf["connVar"].".send(jsonStr);".PHP_EOL;
316 liveuser 14372
 
14373
				}#if end
14374
 
14375
			}#if end
14376
 
3 liveuser 14377
		#設置用戶端連線到webSocket的範例
323 liveuser 14378
		$script="
3 liveuser 14379
			//建立 web socket 連線到 ".$webSockUrl.$conf["url"]."
14380
			var ".$conf["connVar"]." = new WebSocket('".$webSockUrl.$conf["url"]."');
226 liveuser 14381
 
3 liveuser 14382
			//當連線成功後
14383
			".$conf["connVar"].".onopen = function(e)
14384
			{
14385
				//印出連線成功訊息到console
14386
				console.log(\"Connection established!\");
316 liveuser 14387
				".$sendMag."
3 liveuser 14388
			};
14389
 
14390
			//當有收到訊息時
14391
			".$conf["connVar"].".onmessage = function(e) {
226 liveuser 14392
 
3 liveuser 14393
				//將訊息顯現在console
14394
				console.log(e.data);
14395
			};
323 liveuser 14396
			";
226 liveuser 14397
 
3 liveuser 14398
		#函式說明:
323 liveuser 14399
		#將要執行的script語法透過該函式執行(會在程式外層用<script></script>包起來).
3 liveuser 14400
		#回傳結果:
323 liveuser 14401
		#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
14402
		#$result["error"],錯誤訊息陣列
14403
		#$result["function"],當前執行的函數名稱
14404
		#$result["content"],要執行的javaScript語法
14405
		#必填參數:
14406
		#$conf["script"],字串,要執行的javaScript語法.
14407
		$conf["javaScript::toScript"]["script"]=$script;
14408
		#可省略參數:
14409
		#$conf["onReady"],字串,是否要在網頁完全載入後再執行,"false"為不等載入完就先執行,預設為"true"要等載入完再執行.
14410
		#$conf["onReady"]="true";
14411
		#$conf["globalJs"],字串陣列,為要放入<script>標籤的js全域變數.
14412
		#$conf["globalJs"]=array();
14413
		#$conf["jsFunciton"],字串陣列,為要放入<script>標籤的js函數.
14414
		#$conf["jsFunciton"]=array();
14415
		#$conf["noScriptTag"],字串,是否不要輸出<script></script>,預設為"false",代表要輸出;反之為"true",代表不要輸出.
14416
		#$conf["noScriptTag"]="false";
14417
		#參考資料:
14418
		#http://stackoverflow.com/questions/9899372/pure-javascript-equivalent-to-jquerys-ready-how-to-call-a-function-when-the
14419
		#備註:
14420
		#無.
14421
		$toScript=javaScript::toScript($conf["javaScript::toScript"]);
14422
		unset($conf["javaScript::toScript"]);
226 liveuser 14423
 
323 liveuser 14424
		#如果檢查參數失敗
14425
		if($toScript["status"]==="false"){
226 liveuser 14426
 
3 liveuser 14427
			#設置執行失敗
14428
			$result["status"]="false";
226 liveuser 14429
 
3 liveuser 14430
			#設置執行錯誤訊息
323 liveuser 14431
			$result["error"]=$toScript;
226 liveuser 14432
 
3 liveuser 14433
			#回傳結果
14434
			return $result;
226 liveuser 14435
 
14436
			}#if end
14437
 
3 liveuser 14438
		#設置用戶端的html與js語法
323 liveuser 14439
		$result["content"]=$toScript["content"];
226 liveuser 14440
 
3 liveuser 14441
		#設置執行正常
14442
		$result["status"]="true";
226 liveuser 14443
 
3 liveuser 14444
		#回傳結果
14445
		return $result;
226 liveuser 14446
 
3 liveuser 14447
		}#function client end
226 liveuser 14448
 
3 liveuser 14449
	/*
14450
	#函式說明:
14451
	#將 handshake 後含有 mask bit 的 web socket 訊息進行  mask/unmask.
14452
	#回傳結果:
14453
	#$result["function"],當前函式的名稱.
14454
	#$result["argu"],使用的參數.
14455
	#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
14456
	#$result["content"],unmask後的內容.
14457
	#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame.
14458
	#$result["error"],錯誤訊息陣列.
14459
	#必填參數:
14460
	#$conf["payload"],字串,要解密的訊息.
226 liveuser 14461
	$conf["payload"]="";
3 liveuser 14462
	#可省略參數:
14463
	$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
14464
	$conf["allowUnmask"]="false";
14465
	#參考資料
14466
	#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
14467
	#https://tools.ietf.org/html/rfc6455
14468
	#https://tools.ietf.org/html/rfc5234
14469
	#備註:
14470
	#無.
14471
	*/
14472
	public static function mask(&$conf){
226 liveuser 14473
 
3 liveuser 14474
		#改呼叫 webSock::umask
14475
		return webSock::unmask($conf);
226 liveuser 14476
 
3 liveuser 14477
		}#function mask end
226 liveuser 14478
 
3 liveuser 14479
	/*
14480
	#函式說明:
14481
	#將 handshake 後含有 mask bit 的 web socket 訊息進行  mask/unmask.
14482
	#回傳結果:
14483
	#$result["function"],當前函式的名稱.
14484
	#$result["argu"],使用的參數.
14485
	#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
14486
	#$result["content"],unmask後的內容.
324 liveuser 14487
	#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame;"waitPayloadContinue":代表尚未收到全部的payload,回傳的content為未mask處理的payload與head.
3 liveuser 14488
	#$result["error"],錯誤訊息陣列.
14489
	#必填參數:
14490
	#$conf["payload"],字串,要解密的訊息.
226 liveuser 14491
	$conf["payload"]="";
3 liveuser 14492
	#可省略參數:
14493
	#$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
14494
	#$conf["allowUnmask"]="false";
14495
	#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
14496
	#$conf["debug"]="false";
14497
	#參考資料
14498
	#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
14499
	#https://tools.ietf.org/html/rfc6455
14500
	#https://tools.ietf.org/html/rfc5234
14501
	#備註:
14502
	#無.
14503
	*/
14504
	public static function unmask(&$conf) {
226 liveuser 14505
 
3 liveuser 14506
		#初始化要回傳的結果
14507
		$result=array();
14508
 
14509
		#取得當前執行的函數名稱
14510
		$result["function"]=__FUNCTION__;
226 liveuser 14511
 
3 liveuser 14512
		#取得參數內容
14513
		$result["argu"]=$conf;
226 liveuser 14514
 
3 liveuser 14515
		#檢查參數
14516
		#函式說明:
14517
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
14518
		#回傳結果:
14519
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
14520
		#$result["error"],執行不正常結束的錯訊息陣列.
14521
		#$result["simpleError"],簡單表示的錯誤訊息.
14522
		#$result["function"],當前執行的函式名稱.
14523
		#$result["argu"],設置給予的參數.
14524
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
14525
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
14526
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
14527
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
14528
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
14529
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
14530
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
14531
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
14532
		#必填參數:
14533
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
14534
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
14535
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
14536
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
14537
		#可省略參數:
14538
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
14539
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("payload");
14540
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
14541
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
14542
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
14543
		#$conf["canBeEmptyString"]="false";
14544
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
14545
		#$conf["canNotBeEmpty"]=array();
14546
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
14547
		#$conf["canBeEmpty"]=array();
14548
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
14549
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("allowUnmask","debug");
14550
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
14551
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("allowUnmask","debug");
14552
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
14553
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
14554
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
14555
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("false","false");
14556
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
14557
		#$conf["variableCheck::checkArguments"]["disallowAllSkipableVarIsEmpty"]="";
14558
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
14559
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
14560
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
14561
		#$conf["disallowAllSkipableVarNotExist"]="";
14562
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
14563
		#$conf["arrayCountEqualCheck"][]=array();
14564
		#參考資料:
14565
		#array_keys=>http://php.net/manual/en/function.array-keys.php
14566
		#備註:
14567
		#無.
14568
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
14569
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 14570
 
3 liveuser 14571
		#如果檢查參數失敗
14572
		if($checkArguments["status"]==="false"){
226 liveuser 14573
 
3 liveuser 14574
			#設置執行不正常
14575
			$result["status"]="false";
226 liveuser 14576
 
3 liveuser 14577
			#設置錯誤訊息
14578
			$result["error"]=$checkArguments;
226 liveuser 14579
 
3 liveuser 14580
			#回傳結果
14581
			return $result;
226 liveuser 14582
 
3 liveuser 14583
			}#if end
226 liveuser 14584
 
3 liveuser 14585
		#如果檢查參數不通過
14586
		if($checkArguments["passed"]==="false"){
226 liveuser 14587
 
3 liveuser 14588
			#設置執行不正常
14589
			$result["status"]="false";
226 liveuser 14590
 
3 liveuser 14591
			#設置錯誤訊息
14592
			$result["error"]=$checkArguments;
226 liveuser 14593
 
3 liveuser 14594
			#回傳結果
14595
			return $result;
226 liveuser 14596
 
3 liveuser 14597
			}#if end
226 liveuser 14598
 
3 liveuser 14599
		#取得變數
14600
		$payload=$conf["payload"];
226 liveuser 14601
 
3 liveuser 14602
		#如果要debug
14603
		if($conf["debug"]==="true"){
226 liveuser 14604
 
3 liveuser 14605
			#debug payload length
14606
			echo __LINE__." strlen(\$payload)=".strlen($payload).PHP_EOL;
226 liveuser 14607
 
3 liveuser 14608
			}#if end
226 liveuser 14609
 
3 liveuser 14610
		#web socket frame 最少為 2bytes
14611
		if(strlen($payload)<2){
226 liveuser 14612
 
3 liveuser 14613
			#函式說明:
14614
			#將字串中的每個字變成hex的字串陣列
14615
			#回傳結果:
14616
			#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
14617
			#$result["function"],當前執行的函式內容.
14618
			#$result["error"],錯誤訊息陣列.
14619
			#$result["content"],hex的字串陣列.
14620
			#必填參數:
14621
			#$conf["input"],字串,要轉換成bytes陣列的字串.
14622
			$conf["stringProcess::str2bytesArray"]["input"]=$payload;
14623
			#可省略參數:
14624
			#無.
14625
			#參考資料:
14626
			#無.
14627
			#備註:
14628
			#無.
14629
			$str2bytesArray=stringProcess::str2bytesArray($conf["stringProcess::str2bytesArray"]);
14630
			unset($conf["stringProcess::str2bytesArray"]);
226 liveuser 14631
 
3 liveuser 14632
			#如果檢查參數失敗
14633
			if($str2bytesArray["status"]==="false"){
226 liveuser 14634
 
3 liveuser 14635
				#設置執行不正常
14636
				$result["status"]="false";
226 liveuser 14637
 
3 liveuser 14638
				#設置錯誤訊息
14639
				$result["error"]=$str2bytesArray;
226 liveuser 14640
 
3 liveuser 14641
				#回傳結果
14642
				return $result;
226 liveuser 14643
 
3 liveuser 14644
				}#if end
226 liveuser 14645
 
3 liveuser 14646
			#設置警告訊息
14647
			$result["warning"][]="web socket frame 最少為 2 bytes,目前收到得為 ".strlen($payload)." bytes";
226 liveuser 14648
 
3 liveuser 14649
			#設置警告訊息
14650
			$result["warning"][]="接收到的 web socket frame 內容";
226 liveuser 14651
 
3 liveuser 14652
			#設置警告訊息
14653
			$result["warning"][]="(ASCII):".$payload;
226 liveuser 14654
 
3 liveuser 14655
			#開始截取輸出
14656
			ob_start();
226 liveuser 14657
 
3 liveuser 14658
			#針對每個bytes
14659
			for($i=0;$i<count($str2bytesArray["content"]);$i++){
226 liveuser 14660
 
3 liveuser 14661
				#印出其內容
14662
				echo "[".$str2bytesArray["content"][$i]."]";
226 liveuser 14663
 
3 liveuser 14664
				#若不是最後一個byte
14665
				if($i===count($str2bytesArray["content"])-1){
226 liveuser 14666
 
3 liveuser 14667
					#空一格
14668
					echo " ";
226 liveuser 14669
 
3 liveuser 14670
					}#if end
226 liveuser 14671
 
3 liveuser 14672
				}#if end
226 liveuser 14673
 
3 liveuser 14674
			#取得用HEX表示的內容
14675
			$hexStr=ob_get_contents();
226 liveuser 14676
 
3 liveuser 14677
			#結束截取輸出
14678
			ob_end_clean();
226 liveuser 14679
 
3 liveuser 14680
			#設置警告訊息
14681
			$result["warning"][]="(HEX):".$hexStr;
226 liveuser 14682
 
3 liveuser 14683
			#設置為非 web socket frame
14684
			$result["type"]="invalid";
226 liveuser 14685
 
3 liveuser 14686
			#設置執行正常
14687
			$result["status"]="true";
226 liveuser 14688
 
3 liveuser 14689
			#回傳結果
14690
			return $result;
226 liveuser 14691
 
3 liveuser 14692
			}#if end
226 liveuser 14693
 
3 liveuser 14694
		#如果要debug
14695
		if($conf["debug"]==="true"){
226 liveuser 14696
 
3 liveuser 14697
			#debug data length
14698
			echo __LINE__." \$length=".(ord($payload[1]) & 127).PHP_EOL;
226 liveuser 14699
 
3 liveuser 14700
			}#if end
226 liveuser 14701
 
3 liveuser 14702
		#取得字串長度
14703
		$psl=strlen($payload);
226 liveuser 14704
 
3 liveuser 14705
		#初始化儲存每個bytes
14706
		$bytes=array();
226 liveuser 14707
 
3 liveuser 14708
		#函式說明:
14709
		#將字串中的每個字變成bytes陣列
14710
		#回傳結果:
14711
		#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
14712
		#$result["function"],當前執行的函式內容.
14713
		#$result["error"],錯誤訊息陣列.
14714
		#$result["content"],hex的字串陣列.
14715
		#必填參數:
14716
		#$conf["input"],字串,要轉換成bytes陣列的字串
14717
		$conf["stringProcess::str2bytesArray"]["input"]=$payload;
14718
		#可省略參數:
14719
		#無
14720
		$str2bytesArray=stringProcess::str2bytesArray($conf["stringProcess::str2bytesArray"]);
14721
		unset($conf["stringProcess::str2bytesArray"]);
226 liveuser 14722
 
3 liveuser 14723
		#如果執行失敗
14724
		if($str2bytesArray["status"]==="false"){
226 liveuser 14725
 
3 liveuser 14726
			#設置執行不正常
14727
			$result["status"]="false";
226 liveuser 14728
 
3 liveuser 14729
			#設置錯誤訊息
14730
			$result["error"]=$str2bytesArray;
226 liveuser 14731
 
3 liveuser 14732
			#回傳結果
14733
			return $result;
226 liveuser 14734
 
3 liveuser 14735
			}#if end
226 liveuser 14736
 
3 liveuser 14737
		#針對每個bytes
14738
		foreach($str2bytesArray["content"] as $bytesNum => $oneByte){
226 liveuser 14739
 
3 liveuser 14740
			#函式說明:
14741
			#將bytes數字轉換為bit陣列(0跟1來表述)
14742
			#回傳結果:
14743
			#$result...
14744
			#必填參數:
14745
			#$conf["input"],字串,要轉換成byte的字串
14746
			$conf["stringProcess::bytes2byte"]["bytes"]=$oneByte;
14747
			#可省略參數:
14748
			#無
14749
			$bytes2byte=stringProcess::bytes2bitString($conf["stringProcess::bytes2byte"]);
14750
			unset($conf["stringProcess::bytes2byte"]);
226 liveuser 14751
 
3 liveuser 14752
			#儲存bytes與其bit
14753
			$bytes[$bytesNum]["content"]=$bytes2byte["content"];
226 liveuser 14754
 
3 liveuser 14755
			}#foreach end
226 liveuser 14756
 
3 liveuser 14757
		#frame-fin 1 bit
14758
		#%x0 ; more frames of this message follow
14759
		#%x1 ; final frame of this message
14760
		$frameFin=$bytes[0]["content"][0];
14761
 
14762
		#如果不是最後一個 frame
14763
		if($frameFin==="0"){
226 liveuser 14764
 
3 liveuser 14765
			#如果要debug
14766
			if($conf["debug"]==="true"){
226 liveuser 14767
 
3 liveuser 14768
				#debug
14769
				echo __LINE__." frame-fin = 0, not supported".PHP_EOL;
226 liveuser 14770
 
3 liveuser 14771
				}#if end
226 liveuser 14772
 
3 liveuser 14773
			#設置警告訊息
14774
			$result["warning"][]="目前不支援大於一個frame的mask/unmask功能";
226 liveuser 14775
 
3 liveuser 14776
			#設置警告訊息
14777
			$result["warning"][]=$bytes;
226 liveuser 14778
 
3 liveuser 14779
			#設置為非 web socket frame
14780
			$result["type"]="invalid";
226 liveuser 14781
 
3 liveuser 14782
			#設置執行正常
14783
			$result["status"]="true";
226 liveuser 14784
 
3 liveuser 14785
			#回傳結果
14786
			return $result;
226 liveuser 14787
 
3 liveuser 14788
			}#if end
226 liveuser 14789
 
3 liveuser 14790
		#反之是最後一個 data frame
14791
		else{
226 liveuser 14792
 
3 liveuser 14793
			#如果要debug
14794
			if($conf["debug"]==="true"){
226 liveuser 14795
 
3 liveuser 14796
				#debug
14797
				echo __LINE__." frame-fin = 1, means this is a last data frame".PHP_EOL;
226 liveuser 14798
 
3 liveuser 14799
				}#if end
226 liveuser 14800
 
3 liveuser 14801
			}#else end
226 liveuser 14802
 
3 liveuser 14803
		#frame-rsv1 1 bit
14804
		#MUST be 0 unless negotiated otherwise
14805
		$frameRsv1=$bytes[0]["content"][1];
226 liveuser 14806
 
3 liveuser 14807
		#frame-rsv2 1 bit
14808
		#MUST be 0 unless negotiated otherwise
14809
		$frameRsv2=$bytes[0]["content"][2];
226 liveuser 14810
 
3 liveuser 14811
		#frame-rsv3 1 bit
14812
		#MUST be 0 unless negotiated otherwise
14813
		$frameRsv3=$bytes[0]["content"][3];
226 liveuser 14814
 
3 liveuser 14815
		#如果bit[1~3]都為0
14816
		if($frameRsv1===$frameRsv2 && $frameRsv2===$frameRsv3 && $frameRsv3==="0"){
226 liveuser 14817
 
3 liveuser 14818
			#如果要debug
14819
			if($conf["debug"]==="true"){
226 liveuser 14820
 
3 liveuser 14821
				#debug
14822
				echo __LINE__." frame-rsv1~3 = 0".PHP_EOL;
226 liveuser 14823
 
3 liveuser 14824
				}#if end
226 liveuser 14825
 
3 liveuser 14826
			}#if end
226 liveuser 14827
 
3 liveuser 14828
		#如果不存在第5個bit
14829
		if(!isset($bytes[0]["content"][4])){
226 liveuser 14830
 
3 liveuser 14831
			#如果要debug
14832
			if($conf["debug"]==="true"){
226 liveuser 14833
 
3 liveuser 14834
				#debug
14835
				echo __LINE__." $bytes[0]['content'][4] not set!".PHP_EOL;
226 liveuser 14836
 
3 liveuser 14837
				}#if end
226 liveuser 14838
 
3 liveuser 14839
			}#if end
226 liveuser 14840
 
3 liveuser 14841
		/*
14842
		frame-opcode 4 bit
14843
		frame-opcode-cont       = %x0 ; frame continuation
14844
 
14845
		frame-opcode-non-control= %x1 ; text frame
14846
					/ %x2 ; binary frame
14847
					/ %x3-7
14848
					; 4 bits in length,
14849
					; reserved for further non-control frames
14850
 
14851
		frame-opcode-control    = %x8 ; connection close
14852
					/ %x9 ; ping
14853
					/ %xA ; pong
14854
					/ %xB-F ; reserved for further control
14855
					; frames
14856
					; 4 bits in length
14857
		*/
14858
		#如果 bytes[0] 長度不足 8
14859
		if(gettype($bytes[0]["content"])==="array"){
226 liveuser 14860
 
3 liveuser 14861
			if(count($bytes[0]["content"])!==8){
226 liveuser 14862
 
3 liveuser 14863
				#$i為4~7
14864
				for($i=4;$i<8;$i++){
226 liveuser 14865
 
3 liveuser 14866
					#如果未設置
14867
					if(!isset($bytes[0]["content"][$i])){
226 liveuser 14868
 
3 liveuser 14869
						#用 "0" 去補
14870
						$bytes[0]["content"][$i]="0";
226 liveuser 14871
 
3 liveuser 14872
						}#if end
226 liveuser 14873
 
3 liveuser 14874
					}#for end
226 liveuser 14875
 
3 liveuser 14876
				}#if end
226 liveuser 14877
 
3 liveuser 14878
			}#if end
226 liveuser 14879
 
3 liveuser 14880
		$frameOpcode=$bytes[0]["content"][4].$bytes[0]["content"][5].$bytes[0]["content"][6].$bytes[0]["content"][7];
226 liveuser 14881
 
3 liveuser 14882
		#如果要debug
14883
		if($conf["debug"]==="true"){
226 liveuser 14884
 
3 liveuser 14885
			#debug
14886
			echo __LINE__." frame-opcode = ".$frameOpcode.PHP_EOL;
226 liveuser 14887
 
3 liveuser 14888
			}#if end
226 liveuser 14889
 
14890
		$frameOpcodeIntX=$bytes[0]["content"][4]*pow(2,3)+$bytes[0]["content"][5]*pow(2,2)+$bytes[0]["content"][6]*pow(2,1)+$bytes[0]["content"][7]*pow(2,0);
14891
 
3 liveuser 14892
		#設置預設訊息類型為 unknow
14893
		$result["type"]="unknow";
226 liveuser 14894
 
3 liveuser 14895
		#如果 Opcode 等於 1
14896
		if($frameOpcodeIntX===1){
226 liveuser 14897
 
3 liveuser 14898
			#如果要debug
14899
			if($conf["debug"]==="true"){
226 liveuser 14900
 
3 liveuser 14901
				#debug
14902
				echo "It is a text frame".PHP_EOL;
226 liveuser 14903
 
3 liveuser 14904
				}#if end
226 liveuser 14905
 
3 liveuser 14906
			#設置該訊息類型為 text
14907
			$result["type"]="text";
226 liveuser 14908
 
3 liveuser 14909
			}#if end
226 liveuser 14910
 
3 liveuser 14911
		#如果 Opcode 等於 9
14912
		else if($frameOpcodeIntX===9){
226 liveuser 14913
 
3 liveuser 14914
			#如果要debug
14915
			if($conf["debug"]==="true"){
226 liveuser 14916
 
3 liveuser 14917
				#debug
14918
				echo "It is a ping frame".PHP_EOL;
226 liveuser 14919
 
3 liveuser 14920
				}#if end
226 liveuser 14921
 
3 liveuser 14922
			#設置該訊息類型為 text
14923
			$result["type"]="ping";
226 liveuser 14924
 
3 liveuser 14925
			}#if end
226 liveuser 14926
 
3 liveuser 14927
		#如果是 pong
14928
		else if($frameOpcodeIntX===10){
226 liveuser 14929
 
3 liveuser 14930
			#如果要debug
14931
			if($conf["debug"]==="true"){
226 liveuser 14932
 
3 liveuser 14933
				#debug
14934
				echo "It is a pong frame".PHP_EOL;
14935
 
14936
				}#if end
14937
 
14938
			#設置該訊息類型為 pong
14939
			$result["type"]="pong";
226 liveuser 14940
 
3 liveuser 14941
			}#if end
226 liveuser 14942
 
3 liveuser 14943
		#frame-masked 1 bit
14944
		#%x0 ;frame is not masked, no frame-masking-key
14945
		#%x1 ;frame is masked, frame-masking-key present 1 bit in lengt
226 liveuser 14946
		$frameMasked=$bytes[1]["content"][0];
14947
 
3 liveuser 14948
		#預設收到的訊息有mask過.
226 liveuser 14949
		$masked=true;
14950
 
14951
		#如果沒有 masked
3 liveuser 14952
		if($frameMasked!=='1'){
226 liveuser 14953
 
14954
			#如果不允許沒有設置 masked bit
3 liveuser 14955
			if($conf["allowUnmask"]!=="true"){
226 liveuser 14956
 
3 liveuser 14957
				#如果要debug
14958
				if($conf["debug"]==="true"){
226 liveuser 14959
 
3 liveuser 14960
					#debug
14961
					echo __LINE__." frame-masked !== 1, differ with https://tools.ietf.org/html/rfc6455#section-5.3".PHP_EOL;
226 liveuser 14962
 
3 liveuser 14963
					}#if end
226 liveuser 14964
 
3 liveuser 14965
				#設置為非 web socket frame
14966
				$result["type"]="invalid";
226 liveuser 14967
 
3 liveuser 14968
				#設置執行正常
14969
				$result["status"]="true";
226 liveuser 14970
 
3 liveuser 14971
				#回傳結果
14972
				return $result;
226 liveuser 14973
 
3 liveuser 14974
				}#if end
226 liveuser 14975
 
3 liveuser 14976
			#設置收到的訊息沒有mask過.
14977
			$masked=false;
226 liveuser 14978
 
3 liveuser 14979
			}#if end
226 liveuser 14980
 
3 liveuser 14981
		#debug
14982
		#echo __LINE__." frame-masked = ".$frameMasked.PHP_EOL;
226 liveuser 14983
 
3 liveuser 14984
		#frame-payload-length 7 bit, 7+16 bits, or 7+64 bits
14985
		/*
14986
		The length of the "Payload data", in bytes: if 0-125, that is the
14987
		payload length.  If 126, the following 2 bytes interpreted as a
14988
		16-bit unsigned integer are the payload length.  If 127, the
14989
		following 8 bytes interpreted as a 64-bit unsigned integer (the
14990
		most significant bit MUST be 0) are the payload length.  Multibyte
14991
		length quantities are expressed in network byte order.  Note that
14992
		in all cases, the minimal number of bytes MUST be used to encode
14993
		the length, for example, the length of a 124-byte-long string
14994
		can't be encoded as the sequence 126, 0, 124.  The payload length
14995
		is the length of the "Extension data" + the length of the
14996
		"Application data".  The length of the "Extension data" may be
14997
		zero, in which case the payload length is the length of the
14998
		"Application data".
14999
		*/
15000
		if(gettype($bytes[1]["content"])==="array"){
226 liveuser 15001
 
15002
			if(count($bytes[1]["content"])!==8){
15003
 
3 liveuser 15004
				#如果要debug
15005
				if($conf["debug"]==="true"){
226 liveuser 15006
 
3 liveuser 15007
					#debug
15008
					echo __LINE__." payloadLengthBit length !== 8".PHP_EOL;
226 liveuser 15009
 
3 liveuser 15010
					}#if end
226 liveuser 15011
 
3 liveuser 15012
				#如果 bit 不存在,用 0 補上
15013
				for($i=1;$i<8;$i++){
226 liveuser 15014
 
3 liveuser 15015
					#如果未設置
15016
					if(!isset($bytes[1]["content"][$i])){
226 liveuser 15017
 
3 liveuser 15018
						#用"0"替代
15019
						$bytes[1]["content"][$i]="0";
226 liveuser 15020
 
3 liveuser 15021
						}#if end
226 liveuser 15022
 
3 liveuser 15023
					}#for end
226 liveuser 15024
 
3 liveuser 15025
				#代表是用戶在連線.
15026
				#return "client connected!";
226 liveuser 15027
 
3 liveuser 15028
				}#if end
226 liveuser 15029
 
3 liveuser 15030
			}#if end
226 liveuser 15031
 
3 liveuser 15032
		$payloadLengthBit=$bytes[1]["content"][1].$bytes[1]["content"][2].$bytes[1]["content"][3].$bytes[1]["content"][4].$bytes[1]["content"][5].$bytes[1]["content"][6].$bytes[1]["content"][7];
226 liveuser 15033
 
3 liveuser 15034
		#length from 0~127(0~125)
15035
		$payloadLength=$bytes[1]["content"][7]*pow(2,0)+$bytes[1]["content"][6]*pow(2,1)+$bytes[1]["content"][5]*pow(2,2)+$bytes[1]["content"][4]*pow(2,3)+$bytes[1]["content"][3]*pow(2,4)+$bytes[1]["content"][2]*pow(2,5)+$bytes[1]["content"][1]*pow(2,6);
226 liveuser 15036
 
3 liveuser 15037
		#如果長度小於 126
15038
		if($payloadLength<126){
226 liveuser 15039
 
15040
			#mask bit start bytes index
3 liveuser 15041
			$maskBitStartBytesIndex=2;
226 liveuser 15042
 
3 liveuser 15043
			#如果要debug
15044
			if($conf["debug"]==="true"){
226 liveuser 15045
 
3 liveuser 15046
				#debug
15047
				echo __LINE__." mask bit start bytes index = ".$maskBitStartBytesIndex.PHP_EOL;
226 liveuser 15048
 
3 liveuser 15049
				}#if end
226 liveuser 15050
 
3 liveuser 15051
			}#if end
226 liveuser 15052
 
3 liveuser 15053
		#如果長度是 126
15054
		if($payloadLength===126){
226 liveuser 15055
 
3 liveuser 15056
			$payloadLengthBit=$bytes[2]["content"][0].$bytes[2]["content"][1].$bytes[2]["content"][2].$bytes[2]["content"][3].$bytes[2]["content"][4].$bytes[2]["content"][5].$bytes[2]["content"][6].$bytes[2]["content"][7].$bytes[3]["content"][0].$bytes[3]["content"][1].$bytes[3]["content"][2].$bytes[3]["content"][3].$bytes[3]["content"][4].$bytes[3]["content"][5].$bytes[3]["content"][6].$bytes[3]["content"][7];
226 liveuser 15057
 
3 liveuser 15058
			#初始化 payload 長度
15059
			$payloadLength=0;
226 liveuser 15060
 
3 liveuser 15061
			#2次迴圈,兩個bytes
15062
			for($i=0;$i<2;$i++){
226 liveuser 15063
 
3 liveuser 15064
				#8次迴圈,1個byte等於8個bit
15065
				for($j=0;$j<8;$j++){
226 liveuser 15066
 
3 liveuser 15067
					#次方數
15068
					$k=$j+8*$i;
226 liveuser 15069
 
3 liveuser 15070
					#加總 payload 長度
15071
					$payloadLength=$payloadLength+$bytes[3-$i]["content"][7-$j]*pow(2,$k);
226 liveuser 15072
 
3 liveuser 15073
					}#for end
226 liveuser 15074
 
3 liveuser 15075
				}#for end
226 liveuser 15076
 
15077
			#mask bit start bytes index
3 liveuser 15078
			$maskBitStartBytesIndex=4;
226 liveuser 15079
 
3 liveuser 15080
			#如果要debug
15081
			if($conf["debug"]==="true"){
226 liveuser 15082
 
3 liveuser 15083
				#debug
15084
				echo __LINE__." mask bit start bytes index = ".$maskBitStartBytesIndex.PHP_EOL;
226 liveuser 15085
 
3 liveuser 15086
				}#if end
226 liveuser 15087
 
3 liveuser 15088
			}#if end
226 liveuser 15089
 
15090
		#如果長度是 127
3 liveuser 15091
		else if($payloadLength===127){
226 liveuser 15092
 
3 liveuser 15093
			$payloadLengthBit="";
226 liveuser 15094
 
3 liveuser 15095
			#四次迴圈(4個bytes)
15096
			for($i=0;$i<4;$i++){
226 liveuser 15097
 
3 liveuser 15098
				#8次迴圈,1個byte等於8個bit
15099
				for($j=0;$j<8;$j++){
226 liveuser 15100
 
3 liveuser 15101
					$payloadLengthBit=$payloadLengthBit.$bytes[4+$i]["content"][0+$j];
226 liveuser 15102
 
3 liveuser 15103
					}#for end
226 liveuser 15104
 
3 liveuser 15105
				}#for end
226 liveuser 15106
 
3 liveuser 15107
			#初始化 payload 長度
15108
			$payloadLength=0;
226 liveuser 15109
 
3 liveuser 15110
			#四次迴圈(4個bytes)
15111
			for($i=0;$i<4;$i++){
226 liveuser 15112
 
3 liveuser 15113
				#8次迴圈,1個byte等於8個bit
15114
				for($j=0;$j<8;$j++){
226 liveuser 15115
 
3 liveuser 15116
					#次方數
15117
					$k=$j+8*$i;
226 liveuser 15118
 
3 liveuser 15119
					$payloadLength=$payloadLength+$bytes[7-$i]["content"][7-$j]*pow(2,$k);
226 liveuser 15120
 
3 liveuser 15121
					}#for end
226 liveuser 15122
 
3 liveuser 15123
				}#for end
324 liveuser 15124
 
226 liveuser 15125
			#mask bit start bytes index
3 liveuser 15126
			$maskBitStartBytesIndex=8;
226 liveuser 15127
 
3 liveuser 15128
			#如果要debug
15129
			if($conf["debug"]==="true"){
226 liveuser 15130
 
3 liveuser 15131
				#debug
15132
				echo __LINE__." mask bit start bytes index = ".$maskBitStartBytesIndex.PHP_EOL;
226 liveuser 15133
 
3 liveuser 15134
				}#if end
226 liveuser 15135
 
15136
			}#if end
15137
 
3 liveuser 15138
		#如果要debug
15139
		if($conf["debug"]==="true"){
226 liveuser 15140
 
3 liveuser 15141
			#debug
15142
			var_dump(__LINE__,$bytes);
226 liveuser 15143
 
3 liveuser 15144
			#debug 提示payload的長度的2進位表示法
226 liveuser 15145
			echo __LINE__." payload data payloadLengthBit is ".$payloadLengthBit.PHP_EOL;
15146
 
3 liveuser 15147
			#debug 提示payload的長度
15148
			echo __LINE__." payload data length is ".$payloadLength." bytes".PHP_EOL;
226 liveuser 15149
 
3 liveuser 15150
			}#if end
226 liveuser 15151
 
3 liveuser 15152
		#如果有mask
15153
		if($masked){
226 liveuser 15154
 
3 liveuser 15155
			#組合 maskBit 字串
15156
			$maskBitStr=
15157
				chr(base_convert($bytes[$maskBitStartBytesIndex]["content"],2,10)).
15158
				chr(base_convert($bytes[$maskBitStartBytesIndex+1]["content"],2,10)).
15159
				chr(base_convert($bytes[$maskBitStartBytesIndex+2]["content"],2,10)).
15160
				chr(base_convert($bytes[$maskBitStartBytesIndex+3]["content"],2,10));
226 liveuser 15161
 
3 liveuser 15162
			#如果要debug
15163
			if($conf["debug"]==="true"){
226 liveuser 15164
 
3 liveuser 15165
				#debug 提示 mask bit 字串
15166
				echo __LINE__." maskBit str is ".$maskBitStr.PHP_EOL;
226 liveuser 15167
 
3 liveuser 15168
				}#if end
226 liveuser 15169
 
3 liveuser 15170
			}#if end
226 liveuser 15171
 
3 liveuser 15172
		#初始化 payload data 字串
15173
		$payloadDataStr="";
226 liveuser 15174
 
3 liveuser 15175
		#如果有mask
15176
		if($masked){
226 liveuser 15177
 
324 liveuser 15178
 
15179
 
3 liveuser 15180
			#有多長就跑幾次
15181
			for($i=0;$i<$payloadLength;$i++){
324 liveuser 15182
 
15183
				#如果沒有該存在的payload
15184
				if(!isset($bytes[$maskBitStartBytesIndex+4+$i])){
15185
 
15186
					#儲存尚未 mask處理的payload與head.
15187
					$result["content"]=$bytes;
15188
 
15189
					#設置type為還有 payload 未收到 
15190
					$result["type"]="waitPayloadContinue";
15191
 
15192
					#設置執行正常
15193
					$result["status"]="true";
15194
 
15195
					#回傳結果
15196
					return $result;
15197
 
15198
					}#if end
226 liveuser 15199
 
3 liveuser 15200
				#串接 masked 的 payload data.
15201
				$payloadDataStr=$payloadDataStr.chr(base_convert($bytes[$maskBitStartBytesIndex+4+$i]["content"],2,10));
226 liveuser 15202
 
3 liveuser 15203
				}#for end
226 liveuser 15204
 
3 liveuser 15205
			#如果要debug
15206
			if($conf["debug"]==="true"){
226 liveuser 15207
 
3 liveuser 15208
				#debug 提示 mask bit 字串
15209
				echo __LINE__." masked payload data str is ".$payloadDataStr.PHP_EOL;
226 liveuser 15210
 
3 liveuser 15211
				}#if end
226 liveuser 15212
 
3 liveuser 15213
			#unmask payload data
15214
			for($i=0;$i<$payloadLength;$i++){
226 liveuser 15215
 
3 liveuser 15216
				$payloadDataStr[$i]=$payloadDataStr[$i]^$maskBitStr[$i%4];
226 liveuser 15217
 
3 liveuser 15218
				}#for end
226 liveuser 15219
 
3 liveuser 15220
			}#if end
226 liveuser 15221
 
3 liveuser 15222
		#反之
15223
		else{
226 liveuser 15224
 
3 liveuser 15225
			#有多長就跑幾次
15226
			for($i=0;$i<$payloadLength;$i++){
226 liveuser 15227
 
3 liveuser 15228
				#串接 masked 的 payload data.
15229
				$payloadDataStr=$payloadDataStr.chr(base_convert($bytes[$maskBitStartBytesIndex+$i]["content"],2,10));
226 liveuser 15230
 
3 liveuser 15231
				}#for end
226 liveuser 15232
 
3 liveuser 15233
			}#else end
226 liveuser 15234
 
3 liveuser 15235
		#取得 umask 後的內容
15236
		$result["content"]=$payloadDataStr;
226 liveuser 15237
 
3 liveuser 15238
		#設置執行正常
15239
		$result["status"]="true";
226 liveuser 15240
 
15241
		#回傳結果
3 liveuser 15242
		return $result;
226 liveuser 15243
 
3 liveuser 15244
		}#function unmask end
15245
 
15246
	/*
15247
	#函式說明:
226 liveuser 15248
	#加密 handshake 後要傳送的 webSocket 訊息
3 liveuser 15249
	#回傳結果:
15250
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
15251
	#$result["error"],執行不正常結束的錯訊息陣列.
15252
	#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
15253
	#$result["argu"],陣列,使用的參數.
15254
	#必填參數:
15255
	#$conf["text"],字串,要加密的訊息.
226 liveuser 15256
	$conf["text"]="";
3 liveuser 15257
	#可省略參數:
15258
	#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
15259
	#$conf["payloadIsBin"]="false";
15260
	#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
15261
	#$conf["ping"]="false";
15262
	#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
15263
	#$conf["pong"]="false";
15264
	#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
15265
	#$conf["frames"]=array();
15266
	#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
15267
	#$conf["mask"]="false";
15268
	#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
15269
	#$conf["debug"]="false";
15270
	#參考資料:
15271
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
15272
	#備註:
15273
	#無.
15274
	*/
15275
	public static function encode(&$conf){
226 liveuser 15276
 
3 liveuser 15277
		#初始化要回傳的結果
15278
		$result=array();
15279
 
15280
		#設置當其函數名稱
15281
		$result["function"]=__FUNCTION__;
226 liveuser 15282
 
3 liveuser 15283
		#初始化分割好的 web socket 封包
15284
		$result["content"]=array();
15285
 
15286
		#如果 $conf 不為陣列
15287
		if(gettype($conf)!="array"){
15288
 
15289
			#設置執行失敗
15290
			$result["status"]="false";
15291
 
15292
			#設置執行錯誤訊息
15293
			$result["error"][]="\$conf變數須為陣列形態";
15294
 
15295
			#如果傳入的參數為 null
15296
			if($conf==null){
15297
 
15298
				#設置執行錯誤訊息
15299
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
15300
 
15301
				}#if end
226 liveuser 15302
 
3 liveuser 15303
			}#if end
226 liveuser 15304
 
3 liveuser 15305
		#設置放置的參數
15306
		$result["argu"]=$conf;
226 liveuser 15307
 
3 liveuser 15308
		#函式說明:
15309
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
15310
		#回傳結果:
15311
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
15312
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
15313
		#$result["simpleError"],簡單表示的錯誤訊息.
15314
		#$result["function"],當前執行的函式名稱.
15315
		#$result["argu"],設置給予的參數.
15316
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
15317
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
15318
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
15319
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
15320
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
15321
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
15322
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
15323
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
15324
		#必填參數:
15325
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
15326
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
15327
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
15328
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
15329
		#可省略參數:
15330
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
15331
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("text");
15332
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
15333
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
15334
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
15335
		#$conf["canBeEmptyString"]="false";
15336
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
15337
		#$conf["canNotBeEmpty"]=array();
15338
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
15339
		#$conf["canBeEmpty"]=array();
15340
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
15341
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("payloadIsBin","ping","pong","mask","debug");
15342
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
15343
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("payloadIsBin","ping","pong","frames","mask","debug");
15344
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
15345
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","array","string","string");
15346
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
15347
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("false","false","false",array(),"false","false");
15348
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
15349
		$conf["variableCheck::checkArguments"]["disallowAllSkipableVarIsEmpty"]="false";
15350
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
15351
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
15352
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
15353
		#$conf["arrayCountEqualCheck"][]=array();
15354
		#參考資料:
15355
		#array_keys=>http://php.net/manual/en/function.array-keys.php
15356
		#備註:
15357
		#無.
15358
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
15359
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 15360
 
3 liveuser 15361
		#如果執行失敗
15362
		if($checkArguments["status"]==="false"){
226 liveuser 15363
 
3 liveuser 15364
			#設置執行失敗
15365
			$result["status"]="false";
15366
 
15367
			#設置執行錯誤訊息
15368
			$result["error"]=$checkArguments;
226 liveuser 15369
 
3 liveuser 15370
			#回傳結果
15371
			return $result;
226 liveuser 15372
 
3 liveuser 15373
			}#if end
226 liveuser 15374
 
3 liveuser 15375
		#如果參數檢查不通過
15376
		if($checkArguments["passed"]==="false"){
226 liveuser 15377
 
3 liveuser 15378
			#設置執行失敗
15379
			$result["status"]="false";
15380
 
15381
			#設置執行錯誤訊息
15382
			$result["error"]=$checkArguments;
226 liveuser 15383
 
3 liveuser 15384
			#回傳結果
15385
			return $result;
226 liveuser 15386
 
3 liveuser 15387
			}#if end
226 liveuser 15388
 
3 liveuser 15389
		#如果是要產生 ping/pong 的訊息
15390
		if($conf["ping"]==="true" || $conf["pong"]==="true"){
226 liveuser 15391
 
3 liveuser 15392
			#強制將payload設置為空
15393
			$conf["text"]="";
226 liveuser 15394
 
3 liveuser 15395
			}#if end
226 liveuser 15396
 
3 liveuser 15397
		#取得payload
15398
		$text=$conf["text"];
226 liveuser 15399
 
3 liveuser 15400
		#取得 payload length
15401
		$length=strlen($text);
226 liveuser 15402
 
3 liveuser 15403
		#如果沒有payload
15404
		if($length===0){
226 liveuser 15405
 
3 liveuser 15406
			#初始化第一個 frame 為 最後一個 frame.
15407
			$header="1000";
226 liveuser 15408
 
3 liveuser 15409
			#如果是ping
15410
			if($conf["ping"]==="true"){
226 liveuser 15411
 
3 liveuser 15412
				#其訊息類別為 ping
15413
				$header=$header."1001";
226 liveuser 15414
 
3 liveuser 15415
				}#if end
226 liveuser 15416
 
3 liveuser 15417
			#如果是pong
15418
			else if($conf["pong"]==="true"){
226 liveuser 15419
 
3 liveuser 15420
				#其訊息類別為 pong
15421
				$header=$header."1010";
226 liveuser 15422
 
3 liveuser 15423
				}#if end
226 liveuser 15424
 
3 liveuser 15425
			#例外狀況
15426
			else{
226 liveuser 15427
 
3 liveuser 15428
				#設置執行失敗
15429
				$result["status"]="false";
15430
 
15431
				#設置執行錯誤訊息
15432
				$result["error"][]="參數 text 為空時,需要 ping or pong 參數擇一";
15433
 
15434
				#設置執行錯誤訊息
15435
				$result["error"][]=$checkArguments;
226 liveuser 15436
 
3 liveuser 15437
				#回傳結果
15438
				return $result;
226 liveuser 15439
 
3 liveuser 15440
				}#else end
226 liveuser 15441
 
3 liveuser 15442
			}#if end
226 liveuser 15443
 
3 liveuser 15444
		#反之有payload
15445
		else{
226 liveuser 15446
 
3 liveuser 15447
			#初始化第一個 frame 為 最後一個 frame.
15448
			$header="1000";
226 liveuser 15449
 
3 liveuser 15450
			#如果 payload 是 2元碼
15451
			if($conf["payloadIsBin"]==="true"){
226 liveuser 15452
 
3 liveuser 15453
				#設置 opecode 為 0010
15454
				$header=$header."0010";
226 liveuser 15455
 
3 liveuser 15456
				}#if end
226 liveuser 15457
 
3 liveuser 15458
			#反之為 text
15459
			else{
226 liveuser 15460
 
3 liveuser 15461
				#設置 opecode 為 0001
15462
				$header=$header."0001";
226 liveuser 15463
 
3 liveuser 15464
				}#else end
226 liveuser 15465
 
3 liveuser 15466
			}#else end
226 liveuser 15467
 
3 liveuser 15468
		#如果 payload 長度大於 125
15469
		while($length > 125){
226 liveuser 15470
 
15471
			#初始化第一個 frame 為 不為最後一個 frame,
3 liveuser 15472
			$header="0000";
226 liveuser 15473
 
3 liveuser 15474
			#如果 payload 是 2元碼
15475
			if($conf["payloadIsBin"]==="true"){
226 liveuser 15476
 
3 liveuser 15477
				#設置 opecode 為 0010
15478
				$header=$header."0010";
226 liveuser 15479
 
3 liveuser 15480
				}#if end
226 liveuser 15481
 
3 liveuser 15482
			#反之為 text
15483
			else{
226 liveuser 15484
 
3 liveuser 15485
				#設置 opecode 為 0001
15486
				$header=$header."0001";
226 liveuser 15487
 
3 liveuser 15488
				}#else end
226 liveuser 15489
 
3 liveuser 15490
			#如果已經有前面的內容了
15491
			if(count($result["content"])>0){
226 liveuser 15492
 
3 liveuser 15493
				#設置為中間的 frame, 其 opcode 為 continue data.
15494
				$header="00000000";
226 liveuser 15495
 
3 liveuser 15496
				}#if end
226 liveuser 15497
 
3 liveuser 15498
			#取得125bytes
15499
			$body=substr($text,0,125);
226 liveuser 15500
 
3 liveuser 15501
			#函式說明:
15502
			#將2進位的8位數字字串,變成bytes字串.
15503
			#回傳結果:
15504
			#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15505
			#$result["function"],當前執行的函式內容.
15506
			#$result["error"],錯誤訊息陣列.
15507
			#$result["content"],bytes字串,亦即其代表的一個字.
15508
			#必填參數:
15509
			#$conf["8bits"],字串,要轉換成byte字串的bit數字字串,小於8位會於前頭補0,若非2進位的bit數字字串,則會報錯.
15510
			$conf["stringProcess::bit2byteStr"]["8bits"]=$header;
15511
			#可省略參數:
15512
			#無.
15513
			#參考資料:
15514
			#無.
15515
			#備註:
15516
			#無.
15517
			$bit2byteStr=stringProcess::bit2byteStr($conf["stringProcess::bit2byteStr"]);
15518
			unset($conf["stringProcess::bit2byteStr"]);
226 liveuser 15519
 
3 liveuser 15520
			#如果執行失敗
15521
			if($bit2byteStr["status"]==="false"){
226 liveuser 15522
 
3 liveuser 15523
				#設置執行失敗
15524
				$result["status"]="false";
15525
 
15526
				#設置執行錯誤訊息
15527
				$result["error"]=$bit2byteStr;
226 liveuser 15528
 
3 liveuser 15529
				#回傳結果
15530
				return $result;
226 liveuser 15531
 
3 liveuser 15532
				}#if end
226 liveuser 15533
 
3 liveuser 15534
			#取得該 byte 字串
15535
			$headerInByte=$bit2byteStr["content"];
226 liveuser 15536
 
3 liveuser 15537
			#預設不用mask
15538
			$maskBitAndLengthIntString=(string)(125);
226 liveuser 15539
 
3 liveuser 15540
			#如果需要mask
15541
			if($conf["mask"]==="true"){
226 liveuser 15542
 
3 liveuser 15543
				$maskBitAndLengthIntString=(string)(125+128);
226 liveuser 15544
 
3 liveuser 15545
				}#if end
226 liveuser 15546
 
3 liveuser 15547
			#函式說明:
15548
			#將2進位的8位數字字串,變成bytes字串.
15549
			#回傳結果:
15550
			#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15551
			#$result["function"],當前執行的函式內容.
15552
			#$result["error"],錯誤訊息陣列.
15553
			#$result["content"],bytes字串,亦即其代表的一個字.
15554
			#必填參數:
15555
			#$conf["8bits"],字串,要轉換成byte字串的bit數字字串,小於8位會於前頭補0,若非2進位的bit數字字串,則會報錯.
15556
			$conf["stringProcess::bit2byteStr"]["8bits"]=base_convert($maskBitAndLengthIntString,10,2);
15557
			#可省略參數:
15558
			#無.
15559
			#參考資料:
15560
			#無.
15561
			#備註:
15562
			#無.
15563
			$bit2byteStr=stringProcess::bit2byteStr($conf["stringProcess::bit2byteStr"]);
15564
			unset($conf["stringProcess::bit2byteStr"]);
226 liveuser 15565
 
3 liveuser 15566
			#如果要 debug
15567
			if($conf["debug"]==="true"){
226 liveuser 15568
 
3 liveuser 15569
				#debug
15570
				var_dump(__LINE__,$bit2byteStr);
226 liveuser 15571
 
3 liveuser 15572
				}#if end
226 liveuser 15573
 
3 liveuser 15574
			#如果執行失敗
15575
			if($bit2byteStr["status"]==="false"){
226 liveuser 15576
 
3 liveuser 15577
				#設置執行失敗
15578
				$result["status"]="false";
15579
 
15580
				#設置執行錯誤訊息
15581
				$result["error"]=$bit2byteStr;
226 liveuser 15582
 
3 liveuser 15583
				#回傳結果
15584
				return $result;
226 liveuser 15585
 
3 liveuser 15586
				}#if end
226 liveuser 15587
 
3 liveuser 15588
			#取得該 byte 字串
15589
			$lengthInByte=$bit2byteStr["content"];
226 liveuser 15590
 
3 liveuser 15591
			#初始化 4 bytes mask key.
15592
			$maskKey4bytes="";
226 liveuser 15593
 
3 liveuser 15594
			#如果需要mask
15595
			if($conf["mask"]==="true"){
226 liveuser 15596
 
3 liveuser 15597
				#函式說明:
15598
				#隨機產生任意byte(s)組成的字串.
15599
				#回傳結果:
15600
				#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15601
				#$result["function"],當前執行的函式內容.
15602
				#$result["error"],錯誤訊息陣列.
15603
				#$result["content"],用字串來表示的byte(s).
15604
				#必填參數:
15605
				#無.
15606
				#可省略參數:
15607
				#$conf["length"],字串,要產生多少bytes的字串,預設為1.
15608
				$conf["stringProcess::randomByte"]["length"]="4";
15609
				#參考資料:
15610
				#無.
15611
				#備註:
15612
				#無.
15613
				$randomByte=stringProcess::randomByte($conf["stringProcess::randomByte"]);
15614
				unset($conf["stringProcess::randomByte"]);
226 liveuser 15615
 
3 liveuser 15616
				#如果執行失敗
15617
				if($randomByte["status"]==="false"){
226 liveuser 15618
 
3 liveuser 15619
					#設置執行失敗
15620
					$result["status"]="false";
15621
 
15622
					#設置執行錯誤訊息
15623
					$result["error"]=$randomByte;
226 liveuser 15624
 
3 liveuser 15625
					#回傳結果
15626
					return $result;
226 liveuser 15627
 
3 liveuser 15628
					}#if end
226 liveuser 15629
 
3 liveuser 15630
				#取得隨機產生的 mask key
15631
				$maskKey4bytes=$randomByte["content"];
226 liveuser 15632
 
3 liveuser 15633
				#函式說明:
15634
				#將 handshake 後含有 mask bit 的 web socket 訊息進行  mask/unmask.
15635
				#回傳結果:
15636
				#$result["function"],當前函式的名稱.
15637
				#$result["argu"],使用的參數.
15638
				#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
15639
				#$result["content"],unmask後的內容.
15640
				#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame.
15641
				#$result["error"],錯誤訊息陣列.
15642
				#必填參數:
15643
				#$conf["payload"],字串,要解密的訊息.
226 liveuser 15644
				$conf["webSock::unmask"]["payload"]=$headerInByte.$lengthInByte.$maskKey4bytes.$body;
3 liveuser 15645
				#可省略參數:
15646
				#$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
15647
				$conf["webSock::unmask"]["allowUnmask"]="true";
15648
				#參考資料
15649
				#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
15650
				#https://tools.ietf.org/html/rfc6455
15651
				#https://tools.ietf.org/html/rfc5234
15652
				#備註:
15653
				#無.
15654
				$unmask=webSock::unmask($conf["webSock::unmask"]);
15655
				unset($conf["webSock::unmask"]);
226 liveuser 15656
 
3 liveuser 15657
				#debug
15658
				#var_dump(__LINE__,$unmask);
226 liveuser 15659
 
3 liveuser 15660
				#如果執行失敗
15661
				if($unmask["status"]==="false"){
226 liveuser 15662
 
3 liveuser 15663
					#設置執行失敗
15664
					$result["status"]="false";
15665
 
15666
					#設置執行錯誤訊息
15667
					$result["error"]=$unmask;
226 liveuser 15668
 
3 liveuser 15669
					#回傳結果
15670
					return $result;
226 liveuser 15671
 
3 liveuser 15672
					}#if end
226 liveuser 15673
 
3 liveuser 15674
				#取得該段的結果
15675
				$result["content"][]=$headerInByte.$lengthInByte.$maskKey4bytes.$unmask["content"];
226 liveuser 15676
 
3 liveuser 15677
				}#if end
226 liveuser 15678
 
3 liveuser 15679
			#反之
15680
			else{
226 liveuser 15681
 
3 liveuser 15682
				#取得該段的結果
15683
				$result["content"][]=$headerInByte.$lengthInByte.$maskKey4bytes.$body;
226 liveuser 15684
 
3 liveuser 15685
				}#else end
226 liveuser 15686
 
3 liveuser 15687
			#取得剩下的內容
15688
			$text=substr($text,125);
226 liveuser 15689
 
3 liveuser 15690
			#取得 payload length
15691
			$length=strlen($text);
226 liveuser 15692
 
3 liveuser 15693
			}#while end
226 liveuser 15694
 
3 liveuser 15695
		#執行到這邊代表剩下的長度用一個 frame 即可表達
226 liveuser 15696
 
3 liveuser 15697
		#如果已經有內容了
15698
		if(count($result["content"])>0){
226 liveuser 15699
 
3 liveuser 15700
			#代表不用表示為 text frame 但要表示為最後一個 frame.
15701
			$header="10000000";
226 liveuser 15702
 
3 liveuser 15703
			}#if end
226 liveuser 15704
 
3 liveuser 15705
		#函式說明:
15706
		#將2進位的8位數字字串,變成bytes字串.
15707
		#回傳結果:
15708
		#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15709
		#$result["function"],當前執行的函式內容.
15710
		#$result["error"],錯誤訊息陣列.
15711
		#$result["content"],bytes字串,亦即其代表的一個字.
15712
		#必填參數:
15713
		#$conf["8bits"],字串,要轉換成byte字串的bit數字字串,小於8位會於前頭補0,若非2進位的bit數字字串,則會報錯.
15714
		$conf["stringProcess::bit2byteStr"]["8bits"]=$header;
15715
		#可省略參數:
15716
		#無.
15717
		#參考資料:
15718
		#無.
15719
		#備註:
15720
		#無.
15721
		$bit2byteStr=stringProcess::bit2byteStr($conf["stringProcess::bit2byteStr"]);
15722
		unset($conf["stringProcess::bit2byteStr"]);
226 liveuser 15723
 
3 liveuser 15724
		#如果執行失敗
15725
		if($bit2byteStr["status"]==="false"){
226 liveuser 15726
 
3 liveuser 15727
			#設置執行失敗
15728
			$result["status"]="false";
15729
 
15730
			#設置執行錯誤訊息
15731
			$result["error"]=$bit2byteStr;
226 liveuser 15732
 
3 liveuser 15733
			#回傳結果
15734
			return $result;
226 liveuser 15735
 
3 liveuser 15736
			}#if end
226 liveuser 15737
 
3 liveuser 15738
		#取得該 byte 字串
15739
		$headerInByte=$bit2byteStr["content"];
226 liveuser 15740
 
3 liveuser 15741
		#如果要 debug
15742
		if($conf["debug"]==="true"){
226 liveuser 15743
 
3 liveuser 15744
			#debug
15745
			var_dump(__LINE__,$length,base_convert($length,10,2));
226 liveuser 15746
 
3 liveuser 15747
			}#if end
226 liveuser 15748
 
3 liveuser 15749
		#如果需要mask
15750
		if($conf["mask"]==="true"){
226 liveuser 15751
 
3 liveuser 15752
			#增加maskbit
15753
			$length=$length+128;
226 liveuser 15754
 
3 liveuser 15755
			}#if end
226 liveuser 15756
 
3 liveuser 15757
		#函式說明:
15758
		#將2進位的8位數字字串,變成bytes字串.
15759
		#回傳結果:
15760
		#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15761
		#$result["function"],當前執行的函式內容.
15762
		#$result["error"],錯誤訊息陣列.
15763
		#$result["content"],bytes字串,亦即其代表的一個字.
15764
		#必填參數:
15765
		#$conf["8bits"],字串,要轉換成byte字串的bit數字字串,小於8位會於前頭補0,若非2進位的bit數字字串,則會報錯.
15766
		$conf["stringProcess::bit2byteStr"]["8bits"]=base_convert($length,10,2);
15767
		#可省略參數:
15768
		#無.
15769
		#參考資料:
15770
		#無.
15771
		#備註:
15772
		#無.
15773
		$bit2byteStr=stringProcess::bit2byteStr($conf["stringProcess::bit2byteStr"]);
15774
		unset($conf["stringProcess::bit2byteStr"]);
226 liveuser 15775
 
3 liveuser 15776
		#如果要 debug
15777
		if($conf["debug"]==="true"){
226 liveuser 15778
 
3 liveuser 15779
			#debug
15780
			var_dump(__LINE__,$bit2byteStr);
226 liveuser 15781
 
3 liveuser 15782
			}#if end
226 liveuser 15783
 
3 liveuser 15784
		#如果執行失敗
15785
		if($bit2byteStr["status"]==="false"){
226 liveuser 15786
 
3 liveuser 15787
			#設置執行失敗
15788
			$result["status"]="false";
15789
 
15790
			#設置執行錯誤訊息
15791
			$result["error"]=$bit2byteStr;
226 liveuser 15792
 
3 liveuser 15793
			#回傳結果
15794
			return $result;
226 liveuser 15795
 
3 liveuser 15796
			}#if end
226 liveuser 15797
 
3 liveuser 15798
		#取得該 byte 字串
15799
		$lengthInByte=$bit2byteStr["content"];
226 liveuser 15800
 
3 liveuser 15801
		#初始化 4 bytes mask key.
15802
		$maskKey4bytes="";
226 liveuser 15803
 
3 liveuser 15804
		#如果需要mask
15805
		if($conf["mask"]==="true"){
226 liveuser 15806
 
3 liveuser 15807
			#函式說明:
15808
			#隨機產生任意byte(s)組成的字串.
15809
			#回傳結果:
15810
			#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15811
			#$result["function"],當前執行的函式內容.
15812
			#$result["error"],錯誤訊息陣列.
15813
			#$result["content"],用字串來表示的byte(s).
15814
			#必填參數:
15815
			#無.
15816
			#可省略參數:
15817
			#$conf["length"],字串,要產生多少bytes的字串,預設為1.
15818
			$conf["stringProcess::randomByte"]["length"]="4";
15819
			#參考資料:
15820
			#無.
15821
			#備註:
15822
			#無.
15823
			$randomByte=stringProcess::randomByte($conf["stringProcess::randomByte"]);
15824
			unset($conf["stringProcess::randomByte"]);
226 liveuser 15825
 
3 liveuser 15826
			#如果執行失敗
15827
			if($randomByte["status"]==="false"){
226 liveuser 15828
 
3 liveuser 15829
				#設置執行失敗
15830
				$result["status"]="false";
15831
 
15832
				#設置執行錯誤訊息
15833
				$result["error"]=$randomByte;
226 liveuser 15834
 
3 liveuser 15835
				#回傳結果
15836
				return $result;
226 liveuser 15837
 
3 liveuser 15838
				}#if end
226 liveuser 15839
 
3 liveuser 15840
			#取得隨機產生的 mask key
15841
			$maskKey4bytes=$randomByte["content"];
226 liveuser 15842
 
3 liveuser 15843
			}#if end
226 liveuser 15844
 
3 liveuser 15845
		#函式說明:
15846
		#將 handshake 後含有 mask bit 的 web socket 訊息進行  mask/unmask.
15847
		#回傳結果:
15848
		#$result["function"],當前函式的名稱.
15849
		#$result["argu"],使用的參數.
15850
		#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
15851
		#$result["content"],unmask後的內容.
15852
		#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame.
15853
		#$result["error"],錯誤訊息陣列.
15854
		#必填參數:
15855
		#$conf["payload"],字串,要解密的訊息.
226 liveuser 15856
		$conf["webSock::unmask"]["payload"]=$headerInByte.$lengthInByte.$maskKey4bytes.$text;
3 liveuser 15857
		#可省略參數:
15858
		#$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
15859
		$conf["webSock::unmask"]["allowUnmask"]="true";
15860
		#參考資料
15861
		#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
15862
		#https://tools.ietf.org/html/rfc6455
15863
		#https://tools.ietf.org/html/rfc5234
15864
		#備註:
15865
		#無.
15866
		$unmask=webSock::unmask($conf["webSock::unmask"]);
15867
		unset($conf["webSock::unmask"]);
226 liveuser 15868
 
3 liveuser 15869
		#如果要 debug
15870
		if($conf["debug"]==="true"){
226 liveuser 15871
 
3 liveuser 15872
			#debug
15873
			var_dump(__LINE__,$unmask);
226 liveuser 15874
 
3 liveuser 15875
			}#if end
226 liveuser 15876
 
3 liveuser 15877
		#如果執行失敗
15878
		if($unmask["status"]==="false"){
226 liveuser 15879
 
3 liveuser 15880
			#設置執行失敗
15881
			$result["status"]="false";
15882
 
15883
			#設置執行錯誤訊息
15884
			$result["error"]=$unmask;
226 liveuser 15885
 
3 liveuser 15886
			#回傳結果
15887
			return $result;
226 liveuser 15888
 
3 liveuser 15889
			}#if end
226 liveuser 15890
 
3 liveuser 15891
		#儲存訊息
15892
		$result["content"][]=$headerInByte.$lengthInByte.$maskKey4bytes.$unmask["content"];
226 liveuser 15893
 
3 liveuser 15894
		#設置執行正常
15895
		$result["status"]="true";
226 liveuser 15896
 
3 liveuser 15897
		#回傳結果
15898
		return $result;
226 liveuser 15899
 
3 liveuser 15900
		}#function encode end
226 liveuser 15901
 
3 liveuser 15902
	/*
15903
	函式說明:
15904
	提供webSock::nativeSocketTcpIpServer的processFuncs參數所用的函式,可以接受要求傳遞檔案的內容給用戶.
15905
	#回傳結果:
15906
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
15907
	#$result["error"],執行不正常結束的錯訊息陣列.
15908
	#$result["argu"],陣列,使用的參數.
15909
	#必填參數:
15910
	#$conf["data"],字串,收到的json格式資料,必填的key有"Method","Host","File",Method的value目前只支援"GET",Host的value為ServerName亦即網站的網域,File為要求的檔案路徑與名稱;可省略的key有"Range"跟"partSize"跟id,Range的value為需要的檔案內容範圍,目前只支援"bytes=n1-n2"的格式,partSize的value為取得檔案的分段大小,預設為1024000(bytes),亦即1MB,id為用於給用戶端識別的id.
15911
	$conf["data"]="";
15912
	#$conf["serverSock"],resource,web socket server socket
15913
	$conf["serverSock"]=$resource;
15914
	#$conf["clientSock"],$resource,web socket client socket
15915
	$conf["clientSock"]=$resource;
15916
	#$conf["clientInfo"],陣列,web socket client info.
15917
	$conf["clientInfo"]=array();
15918
	#$conf["clientIndex"],整數.web socket client index.
15919
	$conf["clientIndex"];
15920
	#$conf["allConn"],陣列,all web socket client info.
15921
	$conf["allConn"]=array();
15922
	#可省略參數:
15923
	#無.
15924
	#參考資料:
15925
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
15926
	#備註:
15927
	#無.
15928
	*/
15929
	public static function getFileContent(&$conf){
226 liveuser 15930
 
3 liveuser 15931
		#初始化要回傳的結果
15932
		$result=array();
15933
 
15934
		#取得當前執行的函數名稱
15935
		$result["function"]=__FUNCTION__;
15936
 
15937
		#如果沒有參數
15938
		if(func_num_args()==0){
15939
 
15940
			#設置執行失敗
15941
			$result["status"]="false";
15942
 
15943
			#設置執行錯誤訊息
15944
			$result["error"]="函數".$result["function"]."需要參數";
15945
 
15946
			#回傳結果
15947
			return $result;
15948
 
15949
			}#if end
15950
 
15951
		#涵式說明:
15952
		#判斷當前環境為web還是cmd
15953
		#回傳結果:
15954
		#$result,"web"或"cmd"
15955
		if(csInformation::getEnv()==="web"){
15956
 
15957
			#設置執行失敗
15958
			$result["status"]="false";
15959
 
15960
			#設置執行錯誤訊息
15961
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
15962
 
15963
			#回傳結果
15964
			return $result;
15965
 
15966
			}#if end
226 liveuser 15967
 
3 liveuser 15968
		#取得參數
15969
		$result["argu"]=$conf;
15970
 
15971
		#如果 $conf 不為陣列
15972
		if(gettype($conf)!=="array"){
15973
 
15974
			#設置執行失敗
15975
			$result["status"]="false";
15976
 
15977
			#設置執行錯誤訊息
15978
			$result["error"][]="\$conf變數須為陣列形態";
15979
 
15980
			#如果傳入的參數為 null
15981
			if(is_null($conf)){
15982
 
15983
				#設置執行錯誤訊息
15984
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
15985
 
15986
				}#if end
15987
 
15988
			#回傳結果
15989
			return $result;
15990
 
15991
			}#if end
226 liveuser 15992
 
3 liveuser 15993
		#debug
15994
		#var_dump(__FUNCTION__,__LINE__,$conf);
226 liveuser 15995
 
3 liveuser 15996
		#檢查參數
15997
		#函式說明:
15998
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
15999
		#回傳結果:
16000
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16001
		#$result["error"],執行不正常結束的錯訊息陣列.
16002
		#$result["simpleError"],簡單表示的錯誤訊息.
16003
		#$result["function"],當前執行的函式名稱.
16004
		#$result["argu"],設置給予的參數.
16005
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
16006
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
16007
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
16008
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
16009
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
16010
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
16011
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
16012
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
16013
		#必填參數:
16014
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
16015
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
16016
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
16017
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
16018
		#可省略參數:
16019
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
16020
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientSock","clientInfo","clientIndex","allConn");
16021
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
326 liveuser 16022
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","object","object","array","integer","array");
3 liveuser 16023
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
16024
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
16025
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
16026
		#$conf["canNotBeEmpty"]=array();
16027
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
16028
		#$conf["canBeEmpty"]=array();
16029
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
16030
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("Range","partSize");
16031
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
16032
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("Range","partSize");
16033
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
16034
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","partSize");
16035
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
16036
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null,"1024000");
16037
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
16038
		#$conf["disallowAllSkipableVarIsEmpty"]="";
16039
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
16040
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
16041
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
16042
		#$conf["disallowAllSkipableVarNotExist"]="";
16043
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
16044
		#$conf["arrayCountEqualCheck"][]=array();
16045
		#參考資料:
16046
		#array_keys=>http://php.net/manual/en/function.array-keys.php
16047
		#備註:
16048
		#無.
16049
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
16050
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 16051
 
3 liveuser 16052
		#debug
16053
		#var_dump(__FUNCTION__,__LINE__,$checkArguments);
226 liveuser 16054
 
3 liveuser 16055
		#如果執行失敗
16056
		if($checkArguments["status"]==="false"){
226 liveuser 16057
 
3 liveuser 16058
			#設置錯誤訊息
16059
			$result["error"]=$checkArguments;
226 liveuser 16060
 
3 liveuser 16061
			#var_dump,交給下個 processFuncs 處理
16062
			$result["status"]="false";
226 liveuser 16063
 
3 liveuser 16064
			#回傳結果
16065
			return $result;
226 liveuser 16066
 
3 liveuser 16067
			}#if end
226 liveuser 16068
 
3 liveuser 16069
		#如果檢查不通過
16070
		if($checkArguments["passed"]==="false"){
226 liveuser 16071
 
3 liveuser 16072
			#不處理,略過,交給下個 processFuncs 處理
16073
			$result["status"]="continue";
226 liveuser 16074
 
3 liveuser 16075
			#回傳結果
16076
			return $result;
226 liveuser 16077
 
3 liveuser 16078
			}#if end
226 liveuser 16079
 
3 liveuser 16080
		#檢查收到的訊息是否為json格式
16081
		$revJson=@json_decode($conf["data"]);
16082
 
16083
		#如果不是 json
16084
		if($revJson===null){
226 liveuser 16085
 
3 liveuser 16086
			#不處理,略過,交給下個 processFuncs 處理
16087
			$result["status"]="continue";
226 liveuser 16088
 
3 liveuser 16089
			#回傳結果
16090
			return $result;
226 liveuser 16091
 
3 liveuser 16092
			}#if enf
226 liveuser 16093
 
3 liveuser 16094
		#轉換為陣列
16095
		$revJson=(array)($revJson);
226 liveuser 16096
 
3 liveuser 16097
		#檢查參數
16098
		#函式說明:
16099
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
16100
		#回傳結果:
16101
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16102
		#$result["error"],執行不正常結束的錯訊息陣列.
16103
		#$result["simpleError"],簡單表示的錯誤訊息.
16104
		#$result["function"],當前執行的函式名稱.
16105
		#$result["argu"],設置給予的參數.
16106
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
16107
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
16108
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
16109
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
16110
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
16111
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
16112
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
16113
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
16114
		#必填參數:
16115
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
16116
		$conf["variableCheck::checkArguments"]["varInput"]=&$revJson;
16117
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
16118
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
16119
		#可省略參數:
16120
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
16121
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("Method","Host","File");
16122
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
16123
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string","string");
16124
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
16125
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
16126
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
16127
		#$conf["canNotBeEmpty"]=array();
16128
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
16129
		#$conf["canBeEmpty"]=array();
16130
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
16131
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("id","Range","partSize");
16132
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
16133
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("id","Range","partSize");
16134
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
16135
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string");
16136
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
16137
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null,null,"1024000");
16138
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
16139
		#$conf["disallowAllSkipableVarIsEmpty"]="";
16140
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
16141
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
16142
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
16143
		#$conf["disallowAllSkipableVarNotExist"]="";
16144
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
16145
		#$conf["arrayCountEqualCheck"][]=array();
16146
		#參考資料:
16147
		#array_keys=>http://php.net/manual/en/function.array-keys.php
16148
		#備註:
16149
		#無.
16150
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
16151
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 16152
 
3 liveuser 16153
		#debug
16154
		#var_dump(__FUNCTION__,__LINE__,$checkArguments);
226 liveuser 16155
 
3 liveuser 16156
		#如果執行失敗
16157
		if($checkArguments["status"]==="false"){
226 liveuser 16158
 
3 liveuser 16159
			#設置錯誤訊息
16160
			$result["error"]=$checkArguments;
226 liveuser 16161
 
3 liveuser 16162
			#var_dump,交給下個 processFuncs 處理
16163
			$result["status"]="false";
226 liveuser 16164
 
3 liveuser 16165
			#回傳結果
16166
			return $result;
226 liveuser 16167
 
3 liveuser 16168
			}#if end
226 liveuser 16169
 
3 liveuser 16170
		#如果檢查不通過
16171
		if($checkArguments["passed"]==="false"){
226 liveuser 16172
 
3 liveuser 16173
			#不處理,略過,交給下個 processFuncs 處理
16174
			$result["status"]="continue";
226 liveuser 16175
 
3 liveuser 16176
			#回傳結果
16177
			return $result;
226 liveuser 16178
 
3 liveuser 16179
			}#if end
226 liveuser 16180
 
3 liveuser 16181
		#如果是 GET Method
16182
		if($revJson["Method"]==="GET"){
226 liveuser 16183
 
3 liveuser 16184
			#解析 apache vhost info
16185
			#函式說明:
16186
			#使用 linux 的 httpd 指令來取得 vhost 資訊.
16187
			#回傳結果:
16188
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16189
			#$result["error"],錯誤訊息.
16190
			#$result["function"],當前執行的函式名稱.
16191
			#$result["content"],得到的結果陣列,每個元素可能會含有的key有ServerName、DocumentRoot、ServerAlias,其中DocumentRoot的數值會是用""包起來的路徑.
16192
			#必填參數:
16193
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
16194
			$conf["cmd::httpdGetVhostInfo"]["fileArgu"]=__FILE__;
16195
			#可省略參數:
16196
			#無.
16197
			#參考資料:
16198
			#無
16199
			#備註:
16200
			#無.
16201
			$httpdGetVhostInfo=cmd::httpdGetVhostInfo($conf["cmd::httpdGetVhostInfo"]);
16202
			unset($conf["cmd::httpdGetVhostInfo"]);
226 liveuser 16203
 
3 liveuser 16204
			#debug
16205
			#var_dump(__FUNCTION__,__LINE__,$httpdGetVhostInfo);
226 liveuser 16206
 
3 liveuser 16207
			#如果執行失敗
16208
			if($httpdGetVhostInfo["status"]==="false"){
226 liveuser 16209
 
3 liveuser 16210
				#設置錯誤訊息
16211
				$result["error"]=$httpdGetVhostInfo;
226 liveuser 16212
 
3 liveuser 16213
				#var_dump,交給下個 processFuncs 處理
16214
				$result["status"]="false";
226 liveuser 16215
 
3 liveuser 16216
				#回傳結果
16217
				return $result;
226 liveuser 16218
 
3 liveuser 16219
				}#if end
226 liveuser 16220
 
3 liveuser 16221
			#針對每個結果
16222
			foreach($httpdGetVhostInfo["content"] as $vhost){
226 liveuser 16223
 
3 liveuser 16224
				#如果有 ServerName
16225
				if(isset($vhost["ServerName"])){
226 liveuser 16226
 
3 liveuser 16227
					#如果是要找的 Host
16228
					if($vhost["ServerName"]===$revJson["Host"]){
226 liveuser 16229
 
3 liveuser 16230
						#如果有 DocumentRoot
16231
						if(isset($vhost["DocumentRoot"])){
226 liveuser 16232
 
3 liveuser 16233
							#組合要取得的檔案路徑與名稱
16234
							$file=$vhost["DocumentRoot"]."/".$revJson["File"];
226 liveuser 16235
 
3 liveuser 16236
							#debug
16237
							#var_dump(__LINE__,$file);
226 liveuser 16238
 
3 liveuser 16239
							#如果有 Range 參數
16240
							if(isset($revJson["Range"])){
226 liveuser 16241
 
3 liveuser 16242
								#格式參考
16243
								#bytes=0-499
226 liveuser 16244
 
3 liveuser 16245
								#函式說明:
16246
								#將字串特定關鍵字與其前面的內容剔除
16247
								#回傳結果:
16248
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16249
								#$result["error"],錯誤訊息陣列.
16250
								#$result["warning"],警告訊息鎮列.
16251
								#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
16252
								#$result["function"],當前執行的函數名稱.
16253
								#$result["argu"],使用的參數.
16254
								#$result["oriStr"],要處理的原始字串內容.
226 liveuser 16255
								#$result["content"],處理好的的字串內容.
3 liveuser 16256
								#必填參數:
16257
								#$conf["stringIn"],字串,要處理的字串.
16258
								$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$revJson["Range"];
16259
								#$conf["keyWord"],字串,特定字串.
16260
								$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="bytes=";
16261
								#可省略參數:
16262
								#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
16263
								#$conf["recursive"]="true";
16264
								#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
16265
								#$conf["lastResult"]=$delStrBeforeKeyWord;
16266
								#參考資料:
16267
								#無.
16268
								#備註:
16269
								#無.
16270
								$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
16271
								unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 16272
 
3 liveuser 16273
								#如果執行失敗
16274
								if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 16275
 
3 liveuser 16276
									#設置錯誤訊息
16277
									$result["error"]=$delStrBeforeKeyWord;
226 liveuser 16278
 
3 liveuser 16279
									#var_dump,交給下個 processFuncs 處理
16280
									$result["status"]="false";
226 liveuser 16281
 
3 liveuser 16282
									#回傳結果
16283
									return $result;
226 liveuser 16284
 
3 liveuser 16285
									}#if end
226 liveuser 16286
 
3 liveuser 16287
								#如果沒有該有的關鍵字
16288
								if($delStrBeforeKeyWord["founded"]==="false"){
226 liveuser 16289
 
3 liveuser 16290
									#設置錯誤訊息
16291
									$result["error"]=$delStrBeforeKeyWord;
226 liveuser 16292
 
3 liveuser 16293
									#var_dump,交給下個 processFuncs 處理
16294
									$result["status"]="false";
226 liveuser 16295
 
3 liveuser 16296
									#回傳結果
16297
									return $result;
226 liveuser 16298
 
3 liveuser 16299
									}#if end
226 liveuser 16300
 
3 liveuser 16301
								#解析 bytes start and end
16302
								#函式說明:
16303
								#將固定格式的字串分開,並回傳分開的結果.
16304
								#回傳結果:
16305
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16306
								#$result["error"],錯誤訊息陣列
16307
								#$result["function"],當前執行的函數名稱.
16308
								#$result["argu"],使用的參數.
16309
								#$result["oriStr"],要分割的原始字串內容
16310
								#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
16311
								#$result["dataCounts"],爲總共分成幾段
16312
								#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
16313
								#必填參數:
16314
								#$conf["stringIn"],字串,要處理的字串.
16315
								$conf["stringProcess::spiltString"]["stringIn"]=$delStrBeforeKeyWord["content"];
16316
								#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
16317
								$conf["stringProcess::spiltString"]["spiltSymbol"]="-";
16318
								#可省略參數:
16319
								#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
16320
								#$conf["allowEmptyStr"]="false";
16321
								#參考資料:
16322
								#無.
16323
								#備註:
16324
								#無.
16325
								$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
16326
								unset($conf["stringProcess::spiltString"]);
226 liveuser 16327
 
3 liveuser 16328
								#如果執行失敗
16329
								if($spiltString["status"]==="false"){
226 liveuser 16330
 
3 liveuser 16331
									#設置錯誤訊息
16332
									$result["error"]=$spiltString;
226 liveuser 16333
 
3 liveuser 16334
									#var_dump,交給下個 processFuncs 處理
16335
									$result["status"]="false";
226 liveuser 16336
 
3 liveuser 16337
									#回傳結果
16338
									return $result;
226 liveuser 16339
 
3 liveuser 16340
									}#if end
226 liveuser 16341
 
3 liveuser 16342
								#如果沒有應該有的 - 符號
16343
								if($spiltString["found"]==="false"){
226 liveuser 16344
 
3 liveuser 16345
									#設置錯誤訊息
16346
									$result["error"]=$spiltString;
226 liveuser 16347
 
3 liveuser 16348
									#var_dump,交給下個 processFuncs 處理
16349
									$result["status"]="false";
226 liveuser 16350
 
3 liveuser 16351
									#回傳結果
16352
									return $result;
226 liveuser 16353
 
3 liveuser 16354
									}#if end
226 liveuser 16355
 
3 liveuser 16356
								#如果沒有分割成2段
16357
								if($spiltString["dataCounts"]!==2){
226 liveuser 16358
 
3 liveuser 16359
									#設置錯誤訊息
16360
									$result["error"]=$spiltString;
226 liveuser 16361
 
3 liveuser 16362
									#var_dump,交給下個 processFuncs 處理
16363
									$result["status"]="false";
226 liveuser 16364
 
3 liveuser 16365
									#回傳結果
16366
									return $result;
226 liveuser 16367
 
3 liveuser 16368
									}#if end
226 liveuser 16369
 
3 liveuser 16370
								#依照Range來取得檔案內容
16371
								#函式說明:
16372
								#取得檔案的部分內容
16373
								#回傳結果:
16374
								#$result["status"],"true"代表移除成功,"false"代表移除失敗.
16375
								#$result["error"],錯誤訊息陣列.
16376
								#$result["function"],當前執行的函數名稱.
16377
								#$result["cmd"],執行的指令.
16378
								#$result["content"],取得的檔案內容.
16379
								#$result["length"],取得的內容長度.
16380
								#$result["EOF"],識別是否已經到檔案結尾,"true"代表是,"false"代表不是.
16381
								#$result["mimeType"],檔案的 mime type.
16382
								#必填參數:
16383
								#$conf["file"],字串,檔案的路徑與名稱.
16384
								$conf["fileAccess::getFilePart"]["file"]=$file;
16385
								#$conf["fileArgu"],字串,__FILE__的內容.
16386
								$conf["fileAccess::getFilePart"]["fileArgu"]=__FILE__;
16387
								#$conf["bytes"],整數字串,要讀取多少bytes.
16388
								$conf["fileAccess::getFilePart"]["bytes"]=$spiltString["dataArray"][1]-$spiltString["dataArray"][0]+1;
16389
								#$conf["startIndex"],要從哪個bytes位置開始,起始點為0.
16390
								$conf["fileAccess::getFilePart"]["startIndex"]=$spiltString["dataArray"][0];
16391
								#可省略參數:
16392
								#無
16393
								#參考資料:
16394
								#無.
16395
								#備註:
16396
								#無
16397
								$getFilePart=fileAccess::getFilePart($conf["fileAccess::getFilePart"]);
16398
								unset($conf["fileAccess::getFilePart"]);
226 liveuser 16399
 
3 liveuser 16400
								#如果執行失敗
16401
								if($getFilePart["status"]==="false"){
226 liveuser 16402
 
3 liveuser 16403
									#設置錯誤訊息
16404
									$result["error"]=$getFilePart;
226 liveuser 16405
 
3 liveuser 16406
									#var_dump,交給下個 processFuncs 處理
16407
									$result["status"]="false";
226 liveuser 16408
 
3 liveuser 16409
									#回傳結果
16410
									return $result;
226 liveuser 16411
 
3 liveuser 16412
									}#if end
226 liveuser 16413
 
3 liveuser 16414
								#初始化要傳遞的訊息
16415
								$msg=array();
226 liveuser 16416
 
3 liveuser 16417
								#設置為最後一份了
16418
								$msg["LastPart"]="true";
226 liveuser 16419
 
3 liveuser 16420
								#設置資料內容類型為binary
16421
								$msg["dataType"]="binary";
226 liveuser 16422
 
3 liveuser 16423
								#設置內容
16424
								$msg["content"]=$getFilePart["content"];
226 liveuser 16425
 
3 liveuser 16426
								#設置 mimeType
16427
								$msg["mimeType"]=$getFilePart["mimeType"];
226 liveuser 16428
 
3 liveuser 16429
								#如果有設置 id
16430
								if(isset($revJson["id"])){
226 liveuser 16431
 
3 liveuser 16432
									#設置資料的 id
16433
									$msg["id"]=$revJson["id"];
226 liveuser 16434
 
3 liveuser 16435
									}#if end
226 liveuser 16436
 
3 liveuser 16437
								#函式說明:
226 liveuser 16438
								#加密 handshake 後要傳送的訊息
3 liveuser 16439
								#回傳結果:
16440
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16441
								#$result["error"],執行不正常結束的錯訊息陣列.
16442
								#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
16443
								#$result["argu"],陣列,使用的參數.
16444
								#必填參數:
16445
								#$conf["text"],字串,要加密的訊息.
226 liveuser 16446
								$conf["webSock::encode"]["text"]=base64_encode(urlencode(json_encode($msg)));
3 liveuser 16447
								#可省略參數:
16448
								#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
16449
								#$conf["webSock::encode"]["payloadIsBin"]="true";
16450
								#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
16451
								#$conf["ping"]="false";
16452
								#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
16453
								#$conf["pong"]="false";
16454
								#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
16455
								#$conf["frames"]=array();
16456
								#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
16457
								#$conf["webSock::encode"]["mask"]="false";
16458
								#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
16459
								#$conf["debug"]="false";
16460
								#參考資料:
16461
								#無.
16462
								#備註:
16463
								#無.
16464
								$talkback=webSock::encode($conf["webSock::encode"]);
16465
								unset($conf["webSock::encode"]);
226 liveuser 16466
 
3 liveuser 16467
								#如果執行失敗
16468
								if($talkback["status"]==="false"){
226 liveuser 16469
 
3 liveuser 16470
									#印出結果
16471
									var_dump($talkback);
226 liveuser 16472
 
3 liveuser 16473
									#結束執行
16474
									exit;
226 liveuser 16475
 
3 liveuser 16476
									}#if end
226 liveuser 16477
 
3 liveuser 16478
								#針對每個訊息的分段
16479
								foreach($talkback["content"] as $msg){
226 liveuser 16480
 
3 liveuser 16481
									#回傳訊息
16482
									$socket_write=socket_write($conf["clientSock"], $msg, strlen($msg));
226 liveuser 16483
 
3 liveuser 16484
									#如果傳遞訊息給用戶失敗
16485
									if($socket_write===false){
226 liveuser 16486
 
3 liveuser 16487
										#取得錯誤代碼
16488
										$errorCode=socket_last_error($conf["clientSock"]);
226 liveuser 16489
 
3 liveuser 16490
										#設置執行失敗
16491
										$result["status"]="false";
226 liveuser 16492
 
3 liveuser 16493
										#設置錯誤代碼
16494
										$result["error"][]="error code:".$errorCode;
226 liveuser 16495
 
3 liveuser 16496
										#設置錯誤代碼說明
16497
										$result["erorr"][]="error description:".socket_strerror($errorCode);
226 liveuser 16498
 
3 liveuser 16499
										#回傳結果
16500
										return $result;
226 liveuser 16501
 
3 liveuser 16502
										}#if end
226 liveuser 16503
 
3 liveuser 16504
									}#foreach end
226 liveuser 16505
 
3 liveuser 16506
								#設置正常,結束後面函式的執行
16507
								$result["status"]="true";
226 liveuser 16508
 
3 liveuser 16509
								#回傳結果
16510
								return $result;
226 liveuser 16511
 
3 liveuser 16512
								}#if end
226 liveuser 16513
 
3 liveuser 16514
							#反之沒有 Rnage 參數
16515
							else{
226 liveuser 16516
 
3 liveuser 16517
								#執行到這邊代表要取得全部的檔案內容
226 liveuser 16518
 
3 liveuser 16519
								#debug
16520
								#var_dump(__LINE__,"get full file content");
226 liveuser 16521
 
3 liveuser 16522
								#第一部分的編號
16523
								$partNo=0;
226 liveuser 16524
 
3 liveuser 16525
								#無窮迴圈
16526
								while(true){
226 liveuser 16527
 
3 liveuser 16528
									#分段取得檔案
16529
									#函式說明:
16530
									#取得檔案的部分內容
16531
									#回傳結果:
16532
									#$result["status"],"true"代表移除成功,"false"代表移除失敗.
16533
									#$result["error"],錯誤訊息陣列.
16534
									#$result["function"],當前執行的函數名稱.
16535
									#$result["cmd"],執行的指令.
16536
									#$result["content"],取得的檔案內容.
16537
									#$result["length"],取得的內容長度.
16538
									#$result["EOF"],識別是否已經到檔案結尾,"true"代表是,"false"代表不是.
16539
									#$result["mimeType"],檔案的 mime type.
16540
									#必填參數:
16541
									#$conf["file"],字串,檔案的路徑與名稱.
16542
									$conf["fileAccess::getFilePart"]["file"]=$file;
16543
									#$conf["fileArgu"],字串,__FILE__的內容.
16544
									$conf["fileAccess::getFilePart"]["fileArgu"]=__FILE__;
16545
									#$conf["bytes"],整數字串,要讀取多少bytes.
16546
									$conf["fileAccess::getFilePart"]["bytes"]=$revJson["partSize"];
16547
									#$conf["startIndex"],要從哪個bytes位置開始,起始點為0.
16548
									$conf["fileAccess::getFilePart"]["startIndex"]=$partNo*$revJson["partSize"];
16549
									#可省略參數:
16550
									#無
16551
									#參考資料:
16552
									#無.
16553
									#備註:
16554
									#無
16555
									$getFilePart=fileAccess::getFilePart($conf["fileAccess::getFilePart"]);
16556
									unset($conf["fileAccess::getFilePart"]);
226 liveuser 16557
 
3 liveuser 16558
									#debug
16559
									#var_dump(__LINE__,$getFilePart);
226 liveuser 16560
 
3 liveuser 16561
									#如果執行失敗
16562
									if($getFilePart["status"]==="false"){
226 liveuser 16563
 
3 liveuser 16564
										#設置錯誤訊息
16565
										$result["error"]=$getFilePart;
226 liveuser 16566
 
3 liveuser 16567
										#var_dump,交給下個 processFuncs 處理
16568
										$result["status"]="false";
226 liveuser 16569
 
3 liveuser 16570
										#回傳結果
16571
										return $result;
226 liveuser 16572
 
3 liveuser 16573
										}#if end
226 liveuser 16574
 
3 liveuser 16575
									#初始化要傳遞的訊息
16576
									$msg=array();
226 liveuser 16577
 
3 liveuser 16578
									#設置不為最後一份
16579
									$msg["LastPart"]="false";
226 liveuser 16580
 
3 liveuser 16581
									#設置資料內容類型為binary
16582
									$msg["dataType"]="binary";
226 liveuser 16583
 
3 liveuser 16584
									#設置內容
16585
									$msg["content"]=$getFilePart["content"];
226 liveuser 16586
 
3 liveuser 16587
									#設置 mimeType
16588
									$msg["mimeType"]=$getFilePart["mimeType"];
226 liveuser 16589
 
3 liveuser 16590
									#如果有設置 id
16591
									if(isset($revJson["id"])){
226 liveuser 16592
 
3 liveuser 16593
										#設置資料的 id
16594
										$msg["id"]=$revJson["id"];
226 liveuser 16595
 
3 liveuser 16596
										}#if end
226 liveuser 16597
 
3 liveuser 16598
									#如果偵測到檔案結尾
16599
									if($getFilePart["EOF"]==="true"){
226 liveuser 16600
 
3 liveuser 16601
										#設置為最後一份了
16602
										$msg["LastPart"]="true";
226 liveuser 16603
 
3 liveuser 16604
										#如果沒有內容
16605
										if($getFilePart["length"]===0){
226 liveuser 16606
 
3 liveuser 16607
											#檔案區塊數字-1
16608
											$partNo--;
226 liveuser 16609
 
3 liveuser 16610
											}#if end
16611
 
16612
										#傳遞給 client - start
16613
 
16614
										#編碼後的訊息
16615
										$msgEncoded=base64_encode(urlencode(json_encode($msg)));
16616
 
16617
										#debug
16618
										#var_dump(__LINE__,$msg,$msgEncoded);
16619
 
16620
										#函式說明:
226 liveuser 16621
										#加密 handshake 後要傳送的訊息
3 liveuser 16622
										#回傳結果:
16623
										#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16624
										#$result["error"],執行不正常結束的錯訊息陣列.
16625
										#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
16626
										#$result["argu"],陣列,使用的參數.
16627
										#必填參數:
16628
										#$conf["text"],字串,要加密的訊息.
226 liveuser 16629
										$conf["webSock::encode"]["text"]=$msgEncoded;
3 liveuser 16630
										#可省略參數:
16631
										#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
16632
										#$conf["webSock::encode"]["payloadIsBin"]="false";
16633
										#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
16634
										#$conf["ping"]="false";
16635
										#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
16636
										#$conf["pong"]="false";
16637
										#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
16638
										#$conf["frames"]=array();
16639
										#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
16640
										#$conf["webSock::encode"]["mask"]="false";
16641
										#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
16642
										#$conf["debug"]="false";
16643
										#參考資料:
16644
										#無.
16645
										#備註:
16646
										#無.
16647
										$talkback=webSock::encode($conf["webSock::encode"]);
16648
										unset($conf["webSock::encode"]);
226 liveuser 16649
 
3 liveuser 16650
										#debug
16651
										#var_dump(__LINE__,$talkback);
226 liveuser 16652
 
3 liveuser 16653
										#如果執行失敗
16654
										if($talkback["status"]==="false"){
226 liveuser 16655
 
3 liveuser 16656
											#印出結果
16657
											var_dump($talkback);
226 liveuser 16658
 
3 liveuser 16659
											#結束執行
16660
											exit;
226 liveuser 16661
 
3 liveuser 16662
											}#if end
226 liveuser 16663
 
3 liveuser 16664
										#針對每個訊息的分段
16665
										foreach($talkback["content"] as $msg){
226 liveuser 16666
 
3 liveuser 16667
											#回傳訊息
16668
											$socket_write=socket_write($conf["clientSock"], $msg, strlen($msg));
226 liveuser 16669
 
3 liveuser 16670
											#debug
16671
											#var_dump(__LINE__,$socket_write,$msg);
226 liveuser 16672
 
3 liveuser 16673
											#如果傳遞訊息給用戶失敗
16674
											if($socket_write===false){
226 liveuser 16675
 
3 liveuser 16676
												#取得錯誤代碼
16677
												$errorCode=socket_last_error($conf["clientSock"]);
226 liveuser 16678
 
3 liveuser 16679
												#設置執行失敗
16680
												$result["status"]="false";
226 liveuser 16681
 
3 liveuser 16682
												#設置錯誤代碼
16683
												$result["error"][]="error code:".$errorCode;
226 liveuser 16684
 
3 liveuser 16685
												#設置錯誤代碼說明
16686
												$result["erorr"][]="error description:".socket_strerror($errorCode);
226 liveuser 16687
 
3 liveuser 16688
												#回傳結果
16689
												return $result;
226 liveuser 16690
 
3 liveuser 16691
												}#if end
226 liveuser 16692
 
3 liveuser 16693
											}#foreach end
226 liveuser 16694
 
3 liveuser 16695
										#傳遞給 client - end
226 liveuser 16696
 
3 liveuser 16697
										#結束 while
16698
										break;
226 liveuser 16699
 
3 liveuser 16700
										}#if end
226 liveuser 16701
 
3 liveuser 16702
									#傳遞給 client - start
226 liveuser 16703
 
3 liveuser 16704
									#debug
16705
									#var_dump(__LINE__,"start tranfer");
226 liveuser 16706
 
3 liveuser 16707
									#函式說明:
226 liveuser 16708
									#加密 handshake 後要傳送的訊息
3 liveuser 16709
									#回傳結果:
16710
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16711
									#$result["error"],執行不正常結束的錯訊息陣列.
16712
									#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
16713
									#$result["argu"],陣列,使用的參數.
16714
									#必填參數:
16715
									#$conf["text"],字串,要加密的訊息.
226 liveuser 16716
									$conf["webSock::encode"]["text"]=base64_encode(urlencode(json_encode($msg)));
3 liveuser 16717
									#可省略參數:
16718
									#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
16719
									#$conf["webSock::encode"]["payloadIsBin"]="true";
16720
									#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
16721
									#$conf["ping"]="false";
16722
									#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
16723
									#$conf["pong"]="false";
16724
									#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
16725
									#$conf["frames"]=array();
16726
									#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
16727
									#$conf["webSock::encode"]["mask"]="false";
16728
									#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
16729
									#$conf["debug"]="false";
16730
									#參考資料:
16731
									#無.
16732
									#備註:
16733
									#無.
16734
									$talkback=webSock::encode($conf["webSock::encode"]);
16735
									unset($conf["webSock::encode"]);
226 liveuser 16736
 
3 liveuser 16737
									#如果執行失敗
16738
									if($talkback["status"]==="false"){
226 liveuser 16739
 
3 liveuser 16740
										#印出結果
16741
										var_dump($talkback);
226 liveuser 16742
 
3 liveuser 16743
										#結束執行
16744
										exit;
226 liveuser 16745
 
3 liveuser 16746
										}#if end
226 liveuser 16747
 
3 liveuser 16748
									#針對每個訊息的分段
16749
									foreach($talkback["content"] as $msg){
226 liveuser 16750
 
3 liveuser 16751
										#回傳訊息
16752
										$socket_write=socket_write($conf["clientSock"], $msg, strlen($msg));
226 liveuser 16753
 
3 liveuser 16754
										#如果傳遞訊息給用戶失敗
16755
										if($socket_write===false){
226 liveuser 16756
 
3 liveuser 16757
											#取得錯誤代碼
16758
											$errorCode=socket_last_error($conf["clientSock"]);
226 liveuser 16759
 
3 liveuser 16760
											#設置執行失敗
16761
											$result["status"]="false";
226 liveuser 16762
 
3 liveuser 16763
											#設置錯誤代碼
16764
											$result["error"][]="error code:".$errorCode;
226 liveuser 16765
 
3 liveuser 16766
											#設置錯誤代碼說明
16767
											$result["erorr"][]="error description:".socket_strerror($errorCode);
226 liveuser 16768
 
3 liveuser 16769
											#回傳結果
16770
											return $result;
226 liveuser 16771
 
3 liveuser 16772
											}#if end
226 liveuser 16773
 
3 liveuser 16774
										}#foreach end
226 liveuser 16775
 
3 liveuser 16776
									#傳遞給 client - end
226 liveuser 16777
 
3 liveuser 16778
									#檔案區塊數字+1
16779
									$partNo++;
226 liveuser 16780
 
3 liveuser 16781
									}#while end
226 liveuser 16782
 
3 liveuser 16783
								#設置執行正常
16784
								$result["status"]="true";
226 liveuser 16785
 
3 liveuser 16786
								#回傳結果
16787
								return $result;
226 liveuser 16788
 
3 liveuser 16789
								}#else end
226 liveuser 16790
 
3 liveuser 16791
							}#if end
226 liveuser 16792
 
3 liveuser 16793
						}#if end
226 liveuser 16794
 
3 liveuser 16795
					}#if end
226 liveuser 16796
 
3 liveuser 16797
				}#foreach end
226 liveuser 16798
 
3 liveuser 16799
			#設置執行不正常
16800
			$result["status"]="false";
226 liveuser 16801
 
3 liveuser 16802
			#設置執行錯誤
16803
			$result["error"]="no matched ServerName";
226 liveuser 16804
 
3 liveuser 16805
			#debug
66 liveuser 16806
			var_dump(__FUNCTION__,__LINE__,$result);
226 liveuser 16807
 
3 liveuser 16808
			#回傳結果
16809
			return $result;
226 liveuser 16810
 
3 liveuser 16811
			}#if end
226 liveuser 16812
 
3 liveuser 16813
		#設置執行不正常
16814
		$result["status"]="false";
226 liveuser 16815
 
3 liveuser 16816
		#設置執行錯誤
16817
		$result["error"]="Method should be GET";
226 liveuser 16818
 
3 liveuser 16819
		#回傳結果
16820
		return $result;
226 liveuser 16821
 
3 liveuser 16822
		}#function getFileContent end
226 liveuser 16823
 
66 liveuser 16824
	/*
16825
	#函式說明:
16826
	#提供webSock::nativeSocketTcpIpServer用於接受檢查權限的功能.
16827
	#回傳結果:
16828
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16829
	#$result["error"],執行不正常結束的錯訊息陣列.
16830
	#$result["argu"],陣列,使用的參數.
16831
	#必填參數:
16832
	#$conf["data"],字串,收到的bin2hex編碼後果gpg加密過後的json格式資料,必填的key有"randomStr","username","password".
16833
	$conf["data"]="";
323 liveuser 16834
	#$conf["serverSock"],object,web socket server socket
66 liveuser 16835
	$conf["serverSock"]=$resource;
323 liveuser 16836
	#$conf["clientSock"],$object,web socket client socket
66 liveuser 16837
	$conf["clientSock"]=$resource;
16838
	#$conf["clientInfo"],陣列,web socket client info.
16839
	$conf["clientInfo"]=array();
16840
	#$conf["clientIndex"],整數.web socket client index.
16841
	$conf["clientIndex"];
16842
	#$conf["allConn"],陣列,all web socket client info.
16843
	$conf["allConn"]=array();
16844
	#$conf["func"],字串,要檢查的是否具備權限的函式.
16845
	$conf["func"]="";
16846
	#可省略參數:
16847
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
16848
	#$conf["wsMode"]="true";
16849
	#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
16850
	#$conf["gpgId"]=gnupgId;
16851
	#$conf["falseAllowFuncPlus"],陣列,額外的未認證時可以執行的函式清單.
16852
	#$conf["falseAllowFuncPlus"]=array();
16853
	#$conf["publicAllowFuncPlus"],陣列,額外的認證為public時可以執行的函式清單.
16854
	#$conf["publicAllowFuncPlus"]=array();
16855
	#參考資料:
16856
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
16857
	#備註:
16858
	#無.
16859
	*/
16860
	public static function checkAuth(&$conf){
226 liveuser 16861
 
66 liveuser 16862
		#初始化要回傳的結果
16863
		$result=array();
16864
 
16865
		#取得當前執行的函數名稱
16866
		$result["function"]=__FUNCTION__;
16867
 
16868
		#涵式說明:
16869
		#判斷當前環境為web還是cmd
16870
		#回傳結果:
16871
		#$result,"web"或"cmd"
16872
		if(csInformation::getEnv()==="web"){
226 liveuser 16873
 
66 liveuser 16874
			#設置執行失敗
16875
			$result["status"]="false";
226 liveuser 16876
 
66 liveuser 16877
			#設置執行錯誤訊息
16878
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 16879
 
66 liveuser 16880
			#回傳結果
16881
			return $result;
226 liveuser 16882
 
66 liveuser 16883
			}#if end
16884
 
16885
		#取得參數
16886
		$result["argu"]=$conf;
16887
 
16888
		#如果 $conf 不為陣列
16889
		if(gettype($conf)!="array"){
226 liveuser 16890
 
66 liveuser 16891
			#設置執行失敗
16892
			$result["status"]="false";
226 liveuser 16893
 
66 liveuser 16894
			#設置執行錯誤訊息
16895
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 16896
 
66 liveuser 16897
			#如果傳入的參數為 null
16898
			if($conf==null){
226 liveuser 16899
 
66 liveuser 16900
				#設置執行錯誤訊息
16901
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 16902
 
66 liveuser 16903
				}#if end
16904
 
16905
			#回傳結果
16906
			return $result;
226 liveuser 16907
 
66 liveuser 16908
			}#if end
226 liveuser 16909
 
66 liveuser 16910
		#檢查參數
323 liveuser 16911
		#函式說明:
66 liveuser 16912
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
16913
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16914
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
16915
		#$result["function"],當前執行的函式名稱.
16916
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
16917
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
16918
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
16919
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
16920
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
16921
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
16922
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
16923
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
323 liveuser 16924
		#必填寫的參數:
66 liveuser 16925
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
16926
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
16927
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
323 liveuser 16928
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","clientSock","serverSock","clientInfo","clientIndex","allConn","func");
66 liveuser 16929
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
323 liveuser 16930
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","object","object","array","integer","array","string");
66 liveuser 16931
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
16932
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
323 liveuser 16933
		#可以省略的參數:
66 liveuser 16934
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
16935
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
16936
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
16937
		#$conf["canNotBeEmpty"]=array();
16938
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
16939
		#$conf["canBeEmpty"]=array();
16940
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
16941
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
16942
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
323 liveuser 16943
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode","falseAllowFuncPlus","publicAllowFuncPlus");
226 liveuser 16944
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
323 liveuser 16945
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","array","array");
66 liveuser 16946
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
323 liveuser 16947
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",array(),array());
66 liveuser 16948
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
16949
		#$conf["arrayCountEqualCheck"][]=array();
16950
		#參考資料來源:
16951
		#array_keys=>http://php.net/manual/en/function.array-keys.php
16952
		#建議:
16953
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
16954
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
16955
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 16956
 
66 liveuser 16957
		#如果檢查參數失敗
16958
		if($checkArguments["status"]==="false"){
226 liveuser 16959
 
66 liveuser 16960
			#設置執行失敗
16961
			$result["status"]="false";
226 liveuser 16962
 
66 liveuser 16963
			#設置執行錯誤訊息
16964
			$result["error"]=$checkArguments;
226 liveuser 16965
 
66 liveuser 16966
			#回傳結果
16967
			return $result;
226 liveuser 16968
 
66 liveuser 16969
			}#if end
226 liveuser 16970
 
66 liveuser 16971
		#如果檢查參數不通過
16972
		if($checkArguments["passed"]==="false"){
226 liveuser 16973
 
66 liveuser 16974
			#設置執行失敗
16975
			$result["status"]="false";
226 liveuser 16976
 
66 liveuser 16977
			#設置執行錯誤訊息
16978
			$result["error"]=$checkArguments;
226 liveuser 16979
 
66 liveuser 16980
			#回傳結果
16981
			return $result;
226 liveuser 16982
 
66 liveuser 16983
			}#if end
16984
 
16985
		#取得 server 的 socket
16986
		$serverSocket=$conf["serverSock"];
226 liveuser 16987
 
66 liveuser 16988
		#取得 client 的 socket
16989
		$clientSocket=$conf["clientSock"];
226 liveuser 16990
 
66 liveuser 16991
		#取得 client 的資訊
16992
		$clientInfo=$conf["clientInfo"];
226 liveuser 16993
 
66 liveuser 16994
		#取得 client 的索引
16995
		$clientIndex=$conf["clientIndex"];
226 liveuser 16996
 
66 liveuser 16997
		#取得 all clients 的資訊
16998
		$allConn=&$conf["allConn"];
226 liveuser 16999
 
66 liveuser 17000
		#取得認證狀態
323 liveuser 17001
		$authStatus=$allConn[$clientIndex]["auth"];
226 liveuser 17002
 
66 liveuser 17003
		#判斷 authStatus
17004
		switch($authStatus){
226 liveuser 17005
 
66 liveuser 17006
			#如果未經過認證
17007
			case "false":
226 liveuser 17008
 
66 liveuser 17009
				#預設可以使用的功能只有"auth"跟"checkAuth"
323 liveuser 17010
				$authFunc=array("\qbpwcf\webSock::auth","qbpwcf\webSock::checkAuth");
226 liveuser 17011
 
66 liveuser 17012
				#如果有 $conf["falseAllowFuncPlus"]
17013
				if(count($conf["falseAllowFuncPlus"])>0){
226 liveuser 17014
 
66 liveuser 17015
					#合併 array
17016
					#函式說明:
17017
					#將多個一維陣列串聯起來,key從0開始排序.
17018
					#回傳的結果:
17019
					#$result["status"],"true"表執行正常,"false"代表執行不正常.
17020
					#$result["error"],錯誤訊息陣列.
17021
					#$result["function"],當前執行的函數.
17022
					#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
17023
					#$result["content"],合併好的一維陣列.
17024
					#必填參數
17025
					#$conf["inputArray"],陣列,要合併的一維陣列變數,例如:=array($array1,$array2);
17026
					$conf["arrays::mergeArray"]["inputArray"]=array($authFunc,$conf["falseAllowFuncPlus"]);
17027
					#可省略參數:
17028
					#$conf["allowRepeat"],字串,預設為"true",允許重複的結果;若為"false"則不會出現重複的元素內容.
17029
					$conf["arrays::mergeArray"]["allowRepeat"]="false";
17030
					#$conf["looseDiff"],字串,預設為"false",代表要嚴謹判斷為有相異,例如陣列中元素的key順序不同(整數)就代表有相異;反之為"true",例如陣列中元素的key順序不同(非整數),但value有相同,則視為無相異.
17031
					$conf["arrays::mergeArray"]["looseDiff"]="true";
17032
					#參考資料:
17033
					#無.
17034
					#備註:
17035
					#無.
17036
					$mergeArray=arrays::mergeArray($conf["arrays::mergeArray"]);
17037
					unset($conf["arrays::mergeArray"]);
226 liveuser 17038
 
66 liveuser 17039
					#如果執行失敗
17040
					if($mergeArray["status"]==="false"){
17041
 
17042
						#設置執行異常
17043
						$result["status"]="false";
17044
 
17045
						#設置執行錯誤
17046
						$result["error"]=$mergeArray;
17047
 
17048
						#回傳結果
17049
						return $result;
17050
 
17051
						}#if end
226 liveuser 17052
 
66 liveuser 17053
					#取得合併好允許使用的清單
17054
					$authFunc=$mergeArray["content"];
226 liveuser 17055
 
66 liveuser 17056
					}#if end
226 liveuser 17057
 
17058
				#如果沒有權限使用
66 liveuser 17059
				if(!in_array($conf["func"],$authFunc)){
226 liveuser 17060
 
66 liveuser 17061
					#設置執行異常
17062
					$result["status"]="false";
17063
 
17064
					#設置執行錯誤
17065
					$result["error"][]="no ".$conf["func"]." permission";
226 liveuser 17066
 
66 liveuser 17067
					#回傳結果
17068
					return $result;
226 liveuser 17069
 
66 liveuser 17070
					}#if end
226 liveuser 17071
 
66 liveuser 17072
				#結束 switch
17073
				break;
226 liveuser 17074
 
66 liveuser 17075
			#如果是"root"賬戶,代表系統管理者,擁有所有權限.
17076
			case "root":
226 liveuser 17077
 
66 liveuser 17078
				#預設可以使用的功能只有"*",代表所有功能都能用.
17079
				$authFunc=array("*");
226 liveuser 17080
 
66 liveuser 17081
				/*	允許使用所有函式
226 liveuser 17082
 
17083
				#如果沒有權限使用
66 liveuser 17084
				if(!in_array($conf["func"],$authFunc)){
226 liveuser 17085
 
66 liveuser 17086
					#設置執行異常
17087
					$result["status"]="false";
17088
 
17089
					#設置執行錯誤
17090
					$result["error"][]="no ".$conf["func"]." permission";
226 liveuser 17091
 
66 liveuser 17092
					#回傳結果
17093
					return $result;
226 liveuser 17094
 
66 liveuser 17095
					}#if end
226 liveuser 17096
 
66 liveuser 17097
				*/
226 liveuser 17098
 
66 liveuser 17099
				#結束 switch
17100
				break;
226 liveuser 17101
 
323 liveuser 17102
			#其他結果,代表具備一般使用權限的公用使用者.
17103
			default:
226 liveuser 17104
 
323 liveuser 17105
				#只能使用基礎功能
17106
				$authFunc=array("\qbpwcf\webSock::checkAuth","\qbpwcf\webSock::talk2someoneOnce","\qbpwcf\webSock::talk2everyoneOnce");
226 liveuser 17107
 
66 liveuser 17108
				#如果有 publicAllowFuncPlus
17109
				if(count($conf["publicAllowFuncPlus"])>0){
226 liveuser 17110
 
66 liveuser 17111
					#合併 array
17112
					#函式說明:
17113
					#將多個一維陣列串聯起來,key從0開始排序.
17114
					#回傳的結果:
17115
					#$result["status"],"true"表執行正常,"false"代表執行不正常.
17116
					#$result["error"],錯誤訊息陣列.
17117
					#$result["function"],當前執行的函數.
17118
					#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
17119
					#$result["content"],合併好的一維陣列.
17120
					#必填參數
17121
					#$conf["inputArray"],陣列,要合併的一維陣列變數,例如:=array($array1,$array2);
17122
					$conf["arrays::mergeArray"]["inputArray"]=array($authFunc,$conf["publicAllowFuncPlus"]);
17123
					#可省略參數:
17124
					#$conf["allowRepeat"],字串,預設為"true",允許重複的結果;若為"false"則不會出現重複的元素內容.
17125
					$conf["arrays::mergeArray"]["allowRepeat"]="false";
17126
					#$conf["looseDiff"],字串,預設為"false",代表要嚴謹判斷為有相異,例如陣列中元素的key順序不同(整數)就代表有相異;反之為"true",例如陣列中元素的key順序不同(非整數),但value有相同,則視為無相異.
17127
					$conf["arrays::mergeArray"]["looseDiff"]="true";
17128
					#參考資料:
17129
					#無.
17130
					#備註:
17131
					#無.
17132
					$mergeArray=arrays::mergeArray($conf["arrays::mergeArray"]);
17133
					unset($conf["arrays::mergeArray"]);
226 liveuser 17134
 
66 liveuser 17135
					#如果執行失敗
17136
					if($mergeArray["status"]==="false"){
17137
 
17138
						#設置執行異常
17139
						$result["status"]="false";
17140
 
17141
						#設置執行錯誤
17142
						$result["error"]=$mergeArray;
17143
 
17144
						#回傳結果
17145
						return $result;
17146
 
17147
						}#if end
226 liveuser 17148
 
66 liveuser 17149
					#取得合併好允許使用的清單
17150
					$authFunc=$mergeArray["content"];
226 liveuser 17151
 
66 liveuser 17152
					}#if end
226 liveuser 17153
 
17154
				#如果沒有權限使用
66 liveuser 17155
				if(!in_array($conf["func"],$authFunc)){
226 liveuser 17156
 
66 liveuser 17157
					#設置執行異常
17158
					$result["status"]="false";
17159
 
17160
					#設置執行錯誤
17161
					$result["error"][]="no ".$conf["func"]." permission";
226 liveuser 17162
 
66 liveuser 17163
					#回傳結果
17164
					return $result;
226 liveuser 17165
 
66 liveuser 17166
					}#if end
226 liveuser 17167
 
66 liveuser 17168
			}#switch end
226 liveuser 17169
 
66 liveuser 17170
			#設置執行正常
17171
			$result["status"]="true";
17172
 
17173
			#回傳結果
17174
			return $result;
226 liveuser 17175
 
66 liveuser 17176
		}#function checkAuth end
226 liveuser 17177
 
66 liveuser 17178
	/*
17179
	#函式說明:
17180
	#提供webSock::nativeSocketTcpIpServer用於接受"auth:"開頭的訊息進行認證使用者的功能.
17181
	#回傳結果:
17182
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
17183
	#$result["error"],執行不正常結束的錯訊息陣列.
17184
	#$result["argu"],陣列,使用的參數.
17185
	#必填參數:
17186
	#$conf["data"],字串,收到的bin2hex編碼後果gpg加密過後的json格式資料,必填的key有"randomStr","username","password".
17187
	$conf["data"]="";
17188
	#$conf["serverSock"],resource,web socket server socket
17189
	$conf["serverSock"]=$resource;
17190
	#$conf["clientSock"],$resource,web socket client socket
17191
	$conf["clientSock"]=$resource;
17192
	#$conf["clientInfo"],陣列,web socket client info.
17193
	$conf["clientInfo"]=array();
17194
	#$conf["clientIndex"],整數.web socket client index.
17195
	$conf["clientIndex"];
17196
	#$conf["allConn"],陣列,all web socket client info.
17197
	$conf["allConn"]=array();
17198
	#可省略參數:
17199
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
17200
	#$conf["wsMode"]="true";
17201
	#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
17202
	#$conf["gpgId"]=gnupgId;
17203
	#參考資料:
17204
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
17205
	#備註:
17206
	#無.
17207
	*/
17208
	public static function auth(&$conf){
226 liveuser 17209
 
66 liveuser 17210
		#初始化要回傳的結果
17211
		$result=array();
17212
 
17213
		#取得當前執行的函數名稱
17214
		$result["function"]=__FUNCTION__;
17215
 
17216
		#涵式說明:
17217
		#判斷當前環境為web還是cmd
17218
		#回傳結果:
17219
		#$result,"web"或"cmd"
17220
		if(csInformation::getEnv()==="web"){
226 liveuser 17221
 
66 liveuser 17222
			#設置執行失敗
17223
			$result["status"]="false";
226 liveuser 17224
 
66 liveuser 17225
			#設置執行錯誤訊息
17226
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 17227
 
66 liveuser 17228
			#回傳結果
17229
			return $result;
226 liveuser 17230
 
66 liveuser 17231
			}#if end
17232
 
17233
		#取得參數
17234
		$result["argu"]=$conf;
17235
 
17236
		#如果 $conf 不為陣列
17237
		if(gettype($conf)!="array"){
226 liveuser 17238
 
66 liveuser 17239
			#設置執行失敗
17240
			$result["status"]="false";
226 liveuser 17241
 
66 liveuser 17242
			#設置執行錯誤訊息
17243
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 17244
 
66 liveuser 17245
			#如果傳入的參數為 null
17246
			if($conf==null){
226 liveuser 17247
 
66 liveuser 17248
				#設置執行錯誤訊息
17249
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 17250
 
66 liveuser 17251
				}#if end
17252
 
17253
			#回傳結果
17254
			return $result;
226 liveuser 17255
 
66 liveuser 17256
			}#if end
226 liveuser 17257
 
66 liveuser 17258
		#檢查參數
17259
		#函式說明:
17260
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
17261
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
17262
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
17263
		#$result["function"],當前執行的函式名稱.
17264
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
17265
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
17266
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
17267
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
17268
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
17269
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
17270
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
17271
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
17272
		#必填寫的參數:
17273
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
17274
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
17275
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
17276
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientInfo","clientIndex","allConn");
17277
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
17278
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","array","string","array");
17279
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
17280
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
17281
		#可以省略的參數:
17282
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
17283
		#$conf["canBeEmptyString"]="false";
17284
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
17285
		#$conf["canNotBeEmpty"]=array();
17286
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
17287
		#$conf["canBeEmpty"]=array();
17288
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
17289
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
17290
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
17291
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode","gpgId");
226 liveuser 17292
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 17293
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
17294
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
17295
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",gnupgId);
17296
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
17297
		#$conf["arrayCountEqualCheck"][]=array();
17298
		#參考資料來源:
17299
		#array_keys=>http://php.net/manual/en/function.array-keys.php
17300
		#建議:
17301
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
17302
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
17303
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 17304
 
66 liveuser 17305
		#如果檢查參數失敗
17306
		if($checkArguments["status"]==="false"){
226 liveuser 17307
 
66 liveuser 17308
			#設置執行失敗
17309
			$result["status"]="false";
226 liveuser 17310
 
66 liveuser 17311
			#設置執行錯誤訊息
17312
			$result["error"]=$checkArguments;
226 liveuser 17313
 
66 liveuser 17314
			#回傳結果
17315
			return $result;
226 liveuser 17316
 
66 liveuser 17317
			}#if end
226 liveuser 17318
 
66 liveuser 17319
		#如果檢查參數不通過
17320
		if($checkArguments["passed"]==="false"){
226 liveuser 17321
 
66 liveuser 17322
			#設置執行失敗
17323
			$result["status"]="false";
226 liveuser 17324
 
66 liveuser 17325
			#設置執行錯誤訊息
17326
			$result["error"]=$checkArguments;
226 liveuser 17327
 
66 liveuser 17328
			#回傳結果
17329
			return $result;
226 liveuser 17330
 
66 liveuser 17331
			}#if end
17332
 
17333
		#取得收到的訊息
17334
		$receivedData=$conf["data"];
226 liveuser 17335
 
66 liveuser 17336
		#取得 server 的 socket
17337
		$serverSocket=$conf["serverSock"];
226 liveuser 17338
 
66 liveuser 17339
		#取得 client 的 socket
17340
		$clientSocket=$conf["clientSock"];
226 liveuser 17341
 
66 liveuser 17342
		#取得 client 的資訊
17343
		$clientInfo=$conf["clientInfo"];
226 liveuser 17344
 
66 liveuser 17345
		#取得 client 的索引
17346
		$clientIndex=$conf["clientIndex"];
226 liveuser 17347
 
66 liveuser 17348
		#取得認證狀態
17349
		$authStatus=&$conf["clientInfo"][$conf["clientIndex"]]["auth"];
226 liveuser 17350
 
66 liveuser 17351
		#取得 all clients 的資訊
17352
		$allConn=&$conf["allConn"];
226 liveuser 17353
 
66 liveuser 17354
		#hex2bin
17355
		#函式說明:
17356
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
17357
		#回傳結果:
226 liveuser 17358
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 17359
		#$result["function"],當前執行的函數名稱.
17360
		#$result["content"],加密後的結果.
17361
		#$result["error"],錯誤訊息陣列.
17362
		#$result["argu"],使用的參數.
17363
		#必填參數:
17364
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
17365
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
17366
		#$conf["enCodeType"],"字串",加密的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin",7種,"sha1"較耗時,"md5"較快,"p_hash"適用於密碼加密,"aes256"是對稱式加解密,"qbpwcf"是透過urlencode、json_encode、base64_encode的結果,"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin".
17367
		$conf["authenticate::enCodeStr"]["enCodeType"]="hex2bin";
17368
		#可省略參數:
17369
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
17370
		#$conf["sha1Raw"]="false";
17371
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
17372
		#$conf["p_hash"]="";
17373
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
17374
		#$conf["keyForAes256"]="";
17375
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
17376
		#$conf["aes256Encode"]="";
17377
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
17378
		#$conf["qbpwcfDecode"]="false";
17379
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
17380
		#$conf["gpgDecrypt"]="false";
17381
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
17382
		#$conf["gpgId"]="";
17383
		#參考資料:
17384
		#sha1=>http://php.net/manual/en/function.sha1.php
17385
		#md5=>http://php.net/manual/en/function.md5.php
17386
		#password_hash=>http://php.net/manual/en/function.password-hash.php
17387
		#password_verify=>http://php.net/manual/en/function.password-verify.php
17388
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
17389
		#備註:
17390
		#無.
17391
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
17392
		unset($conf["authenticate::enCodeStr"]);
17393
 
17394
		#如果執行失敗
17395
		if($enCodeStr["status"]==="false"){
17396
 
17397
			#設置執行異常
17398
			$result["status"]="false";
17399
 
17400
			#設置執行錯誤
17401
			$result["error"]=$enCodeStr;
17402
 
17403
			#回傳結果
17404
			return $result;
17405
 
17406
			}#if end
17407
 
17408
		#取得hex2bin後的字串
17409
		$receivedData=$enCodeStr["content"];
226 liveuser 17410
 
66 liveuser 17411
		#gpg decrypt
17412
		#函式說明:
17413
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
17414
		#回傳結果:
226 liveuser 17415
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 17416
		#$result["function"],當前執行的函數名稱.
17417
		#$result["content"],加密後的結果.
17418
		#$result["error"],錯誤訊息陣列.
17419
		#$result["argu"],使用的參數.
17420
		#必填參數:
17421
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
17422
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
17423
		#$conf["enCodeType"],"字串",加密的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin",7種,"sha1"較耗時,"md5"較快,"p_hash"適用於密碼加密,"aes256"是對稱式加解密,"qbpwcf"是透過urlencode、json_encode、base64_encode的結果,"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin".
17424
		$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
17425
		#可省略參數:
17426
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
17427
		#$conf["sha1Raw"]="false";
17428
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
17429
		#$conf["p_hash"]="";
17430
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
17431
		#$conf["keyForAes256"]="";
17432
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
17433
		#$conf["aes256Encode"]="";
17434
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
17435
		#$conf["qbpwcfDecode"]="false";
17436
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
17437
		$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
17438
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
17439
		$conf["authenticate::enCodeStr"]["gpgId"]=$conf["gpgId"];
17440
		#參考資料:
17441
		#sha1=>http://php.net/manual/en/function.sha1.php
17442
		#md5=>http://php.net/manual/en/function.md5.php
17443
		#password_hash=>http://php.net/manual/en/function.password-hash.php
17444
		#password_verify=>http://php.net/manual/en/function.password-verify.php
17445
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
17446
		#備註:
17447
		#無.
17448
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
17449
		unset($conf["authenticate::enCodeStr"]);
17450
 
17451
		#如果執行失敗
17452
		if($enCodeStr["status"]==="false"){
17453
 
17454
			#設置執行異常
17455
			$result["status"]="false";
17456
 
17457
			#設置執行錯誤
17458
			$result["error"]=$enCodeStr;
17459
 
17460
			#回傳結果
17461
			return $result;
17462
 
17463
			}#if end
17464
 
17465
		#取得解密後的字串
17466
		$receivedData=$enCodeStr["content"];
226 liveuser 17467
 
66 liveuser 17468
		#json_decode
17469
		$receivedData=json_decode($receivedData);
226 liveuser 17470
 
66 liveuser 17471
		#如果decode後的內容不為物件
17472
		if(gettype($receivedData)!=="Object"){
226 liveuser 17473
 
66 liveuser 17474
			#設置不適用
17475
			$result["status"]="continue";
226 liveuser 17476
 
66 liveuser 17477
			#回傳結果
17478
			return $result;
226 liveuser 17479
 
66 liveuser 17480
			}#if end
226 liveuser 17481
 
66 liveuser 17482
		#檢查物件是否符合格式
17483
		#函式說明:
17484
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
17485
		#回傳結果:
17486
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
17487
		#$result["error"],執行不正常結束的錯訊息陣列.
17488
		#$result["simpleError"],簡單表示的錯誤訊息.
17489
		#$result["function"],當前執行的函式名稱.
17490
		#$result["argu"],設置給予的參數.
17491
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
17492
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
17493
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
17494
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
17495
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
17496
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
17497
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
17498
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
17499
		#必填參數:
17500
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
17501
		$conf["variableCheck::checkArguments"]["varInput"]=&$receivedData;
17502
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
17503
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
17504
		#可省略參數:
17505
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
17506
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("user","type","secrect");
17507
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
17508
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string","string");
17509
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
17510
		#$conf["canBeEmptyString"]="false";
17511
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
17512
		#$conf["canNotBeEmpty"]=array();
17513
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
17514
		#$conf["canBeEmpty"]=array();
17515
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
17516
		#$conf["skipableVariableCanNotBeEmpty"]=array();
17517
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
17518
		#$conf["skipableVariableName"]=array();
17519
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
17520
		#$conf["skipableVariableType"]=array();
17521
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
17522
		#$conf["skipableVarDefaultValue"]=array("");
17523
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
17524
		#$conf["disallowAllSkipableVarIsEmpty"]="";
17525
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
17526
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
17527
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
17528
		#$conf["disallowAllSkipableVarNotExist"]="";
17529
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
17530
		#$conf["arrayCountEqualCheck"][]=array();
17531
		#參考資料:
17532
		#array_keys=>http://php.net/manual/en/function.array-keys.php
17533
		#備註:
17534
		#無.
17535
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
17536
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 17537
 
66 liveuser 17538
		#如果執行異常
17539
		if($checkArguments["status"]==="false"){
226 liveuser 17540
 
66 liveuser 17541
			#設置異常
17542
			$result["status"]="false";
226 liveuser 17543
 
66 liveuser 17544
			#設置錯誤訊息
17545
			$result["error"]=$checkArguments;
226 liveuser 17546
 
66 liveuser 17547
			#回傳結果
17548
			return $result;
226 liveuser 17549
 
66 liveuser 17550
			}#if end
226 liveuser 17551
 
66 liveuser 17552
		#如果參數不合法
17553
		if($checkArguments["passed"]==="false"){
226 liveuser 17554
 
66 liveuser 17555
			#設置不適用
17556
			$result["status"]="continue";
226 liveuser 17557
 
66 liveuser 17558
			#回傳結果
17559
			return $result;
226 liveuser 17560
 
66 liveuser 17561
			}#if end
226 liveuser 17562
 
66 liveuser 17563
		#取得使用者名稱
17564
		$user=$receivedData->user;
226 liveuser 17565
 
66 liveuser 17566
		#取得密碼或金鑰內容
17567
		$secrect=$receivedData->secrect;
226 liveuser 17568
 
66 liveuser 17569
		#依照驗證方式
17570
		switch($receivedData->type){
226 liveuser 17571
 
66 liveuser 17572
			#若是密碼認證
17573
			case "password":
226 liveuser 17574
 
66 liveuser 17575
				#測試 $user 與 password 的組合是否能夠認證.
17576
				#函式說明:
17577
				#驗證Linux使用者的密碼是否正確.
17578
				#回傳結果:
226 liveuser 17579
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 17580
				#$result["function"],當前執行的函數名稱.
17581
				#$result["error"],錯誤訊息陣列.
17582
				#$result["warninig"],警告訊息陣列.
17583
				#$result["valid"],是否為存在的使用者且密碼正確.
17584
				#必填參數:
17585
				#$conf["username"],字串,要驗證的使用者名稱.
17586
				$conf["authenticate::validUser"]["username"]=$user;
17587
				#$conf["password"],字串,用於驗證使用者的密碼.
17588
				$conf["authenticate::validUser"]["password"]=$secrect;
17589
				#$conf["fileArgu"],字串,變數__FILE__的內容.
17590
				$conf["authenticate::validUser"]["fileArgu"]=__FILE__;
17591
				#可省略參數:
17592
				#無.
17593
				#參考資料:
17594
				#無.
17595
				#備註:
17596
				#僅能在命令列環境下運行.
17597
				$validUser=authenticate::validUser($conf["authenticate::validUser"]);
17598
				unset($conf["authenticate::validUser"]);
226 liveuser 17599
 
66 liveuser 17600
				#如果執行異常
17601
				if($validUser["status"]==="false"){
226 liveuser 17602
 
66 liveuser 17603
					#設置異常
17604
					$result["status"]="false";
226 liveuser 17605
 
66 liveuser 17606
					#設置錯誤訊息
17607
					$result["error"]=$validUser;
226 liveuser 17608
 
66 liveuser 17609
					#回傳結果
17610
					return $result;
226 liveuser 17611
 
66 liveuser 17612
					}#if end
226 liveuser 17613
 
66 liveuser 17614
				#如果認證失敗
17615
				if($validUser["valid"]==="false"){
226 liveuser 17616
 
66 liveuser 17617
					#記錄該 client 認證失敗的事件
17618
					$allConn[$clientIndex]["authFailed"][]=array("time"=>time(),"user"=>$user);
226 liveuser 17619
 
66 liveuser 17620
					#針對每次認證失敗的記錄
17621
					for($i=0;$i<count($allConn[$clientIndex]["authFailed"]);$i++){
226 liveuser 17622
 
66 liveuser 17623
						#如果有下一個事件
17624
						if(isset($allConn[$clientIndex]["authFailed"][$i+1])){
226 liveuser 17625
 
66 liveuser 17626
							#如果本次跟下次事件的時間間隔小於60秒
17627
							if($allConn[$clientIndex]["authFailed"][$i+1]["time"] - $allConn[$clientIndex]["authFailed"][$i]["time"] > 60){
226 liveuser 17628
 
66 liveuser 17629
								#移除本次記錄
17630
								array_shift($allConn[$clientIndex]["authFailed"]);
226 liveuser 17631
 
66 liveuser 17632
								#新記錄的索引減少了1,因此更新$i
17633
								$i--;
226 liveuser 17634
 
66 liveuser 17635
								}#if end
226 liveuser 17636
 
66 liveuser 17637
							}#if end
226 liveuser 17638
 
66 liveuser 17639
						}#foreach end
226 liveuser 17640
 
66 liveuser 17641
					#如果總事件次數大於3
17642
					if(count($allConn[$clientIndex]["authFailed"])>3){
226 liveuser 17643
 
66 liveuser 17644
						#設置異常
17645
						$result["status"]="false";
226 liveuser 17646
 
66 liveuser 17647
						#設置錯誤訊息
17648
						$result["error"]=$allConn[$clientIndex]["authFailed"];
226 liveuser 17649
 
66 liveuser 17650
						#回傳結果
17651
						return $result;
226 liveuser 17652
 
66 liveuser 17653
						}#if end
226 liveuser 17654
 
66 liveuser 17655
					#設置正常
17656
					$result["status"]="true";
226 liveuser 17657
 
66 liveuser 17658
					#回傳結果
17659
					return $result;
226 liveuser 17660
 
66 liveuser 17661
					}#if end
226 liveuser 17662
 
66 liveuser 17663
				#執行到這邊代表使用者認證通過
226 liveuser 17664
 
66 liveuser 17665
				#依照 user 取得其所屬 group
17666
				#函式說明:
17667
				#id指令來取得目標賬號的群組資訊
17668
				#回傳結果:
17669
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
17670
				#$reuslt["error"],執行不正常結束的錯訊息陣列.
17671
				#$result["function"],當前執行的函式名稱.
17672
				#$result["content"],呼叫完WebService所得回傳結果.
17673
				#$result["content"]["groupId"],群組的id.
17674
				#$result["content"]["belongGroupName"],陣列,隸屬的群組名稱陣列.
17675
				#$result["content"]["belongGroupId"],陣列,隸屬的群組id.
17676
				#必填參數:
17677
				#$conf["user"],字串,要取得群組資訊的目標使用者名稱.
17678
				$conf["authenticate::getUserGroup"]["user"]=$user;
17679
				#可省略參數:
17680
				#無.
17681
				#參考資料:
17682
				#無.
17683
				#備註:
17684
				#無.
17685
				$getUserGroup=authenticate::getUserGroup($conf["authenticate::getUserGroup"]);
17686
				unset($conf["authenticate::getUserGroup"]);
226 liveuser 17687
 
66 liveuser 17688
				#如果執行異常
17689
				if($getUserGroup["status"]==="false"){
226 liveuser 17690
 
66 liveuser 17691
					#設置異常
17692
					$result["status"]="false";
226 liveuser 17693
 
66 liveuser 17694
					#設置錯誤訊息
17695
					$result["error"]=$getUserGroup;
226 liveuser 17696
 
66 liveuser 17697
					#回傳結果
17698
					return $result;
226 liveuser 17699
 
66 liveuser 17700
					}#if end
226 liveuser 17701
 
66 liveuser 17702
				#設置預設的權限為 "false"
17703
				$authStatus="false";
226 liveuser 17704
 
66 liveuser 17705
				#針對每個取得的群組名稱
17706
				foreach($getUserGroup["content"]["belongGroupName"] as $groupName){
226 liveuser 17707
 
66 liveuser 17708
					#如果是 root
17709
					if($groupName==="root"){
226 liveuser 17710
 
66 liveuser 17711
						#設置得到的權限
17712
						$authStatus=$groupName;
226 liveuser 17713
 
66 liveuser 17714
						#結束 foreach
17715
						break;
226 liveuser 17716
 
66 liveuser 17717
						}#if end
226 liveuser 17718
 
66 liveuser 17719
					#反之如果是公開的使用者
17720
					else if($groupName==="public"){
226 liveuser 17721
 
66 liveuser 17722
						#設置得到的權限
17723
						$authStatus=$groupName;
226 liveuser 17724
 
66 liveuser 17725
						}#if end
226 liveuser 17726
 
66 liveuser 17727
					#其他群組名稱
17728
					else{
226 liveuser 17729
 
66 liveuser 17730
						#跳過
17731
						continue;
226 liveuser 17732
 
66 liveuser 17733
						}#else end
226 liveuser 17734
 
66 liveuser 17735
					}#foreach end
226 liveuser 17736
 
66 liveuser 17737
				#設置正常
17738
				$result["status"]="true";
226 liveuser 17739
 
66 liveuser 17740
				#回傳結果
17741
				return $result;
226 liveuser 17742
 
66 liveuser 17743
				#跳出 switch
17744
				break;
226 liveuser 17745
 
66 liveuser 17746
			#若是金鑰認證
17747
			case "key":
226 liveuser 17748
 
66 liveuser 17749
				#測試 $user 與 key 的組合是否能夠認證.
17750
				#函式說明:
17751
				#驗證Linux使用者的密碼或ssh private key是否正確.
17752
				#回傳結果:
226 liveuser 17753
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 17754
				#$result["function"],當前執行的函數名稱.
17755
				#$result["error"],錯誤訊息陣列.
17756
				#$result["warninig"],警告訊息陣列.
17757
				#$result["valid"],是否為存在的使用者且密碼正確.
17758
				#必填參數:
17759
				#$conf["username"],字串,要驗證的使用者名稱.
17760
				$conf["authenticate::validUser"]["username"]=$user;
17761
				#$conf["password"],字串,用於驗證使用者的密碼.
17762
				$conf["authenticate::validUser"]["password"]=$secrect;
17763
				#$conf["fileArgu"],字串,變數__FILE__的內容.
17764
				$conf["authenticate::validUser"]["fileArgu"]=__FILE__;
17765
				#可省略參數:
17766
				#$conf["sshPrivateKey"],字串,"true"代表password為ssh private key的內容;反之預設為密碼,設置為"false".
17767
				$conf["authenticate::validUser"]["sshPrivateKey"]="true";
17768
				#參考資料:
17769
				#無.
17770
				#備註:
17771
				#僅能在命令列環境下運.
17772
				#目前僅支援驗證執行php端的使用者.
17773
				$validUser=authenticate::validUser($conf["authenticate::validUser"]);
17774
				unset($conf["authenticate::validUser"]);
226 liveuser 17775
 
66 liveuser 17776
				#如果執行異常
17777
				if($validUser["status"]==="false"){
226 liveuser 17778
 
66 liveuser 17779
					#設置異常
17780
					$result["status"]="false";
226 liveuser 17781
 
66 liveuser 17782
					#設置錯誤訊息
17783
					$result["error"]=$validUser;
226 liveuser 17784
 
66 liveuser 17785
					#回傳結果
17786
					return $result;
226 liveuser 17787
 
66 liveuser 17788
					}#if end
226 liveuser 17789
 
66 liveuser 17790
				#如果認證失敗
17791
				if($validUser["valid"]==="false"){
226 liveuser 17792
 
66 liveuser 17793
					#記錄該 client 認證失敗的事件
17794
					$allConn[$clientIndex]["authFailed"][]=array("time"=>time(),"user"=>$user);
226 liveuser 17795
 
66 liveuser 17796
					#針對每次認證失敗的記錄
17797
					for($i=0;$i<count($allConn[$clientIndex]["authFailed"]);$i++){
226 liveuser 17798
 
66 liveuser 17799
						#如果有下一個事件
17800
						if(isset($allConn[$clientIndex]["authFailed"][$i+1])){
226 liveuser 17801
 
66 liveuser 17802
							#如果本次跟下次事件的時間間隔小於60秒
17803
							if($allConn[$clientIndex]["authFailed"][$i+1]["time"] - $allConn[$clientIndex]["authFailed"][$i]["time"] > 60){
226 liveuser 17804
 
66 liveuser 17805
								#移除本次記錄
17806
								array_shift($allConn[$clientIndex]["authFailed"]);
226 liveuser 17807
 
66 liveuser 17808
								#新記錄的索引減少了1,因此更新$i
17809
								$i--;
226 liveuser 17810
 
66 liveuser 17811
								}#if end
226 liveuser 17812
 
66 liveuser 17813
							}#if end
226 liveuser 17814
 
66 liveuser 17815
						}#foreach end
226 liveuser 17816
 
66 liveuser 17817
					#如果總事件次數大於3
17818
					if(count($allConn[$clientIndex]["authFailed"])>3){
226 liveuser 17819
 
66 liveuser 17820
						#設置異常
17821
						$result["status"]="false";
226 liveuser 17822
 
66 liveuser 17823
						#設置錯誤訊息
17824
						$result["error"]=$allConn[$clientIndex]["authFailed"];
226 liveuser 17825
 
66 liveuser 17826
						#回傳結果
17827
						return $result;
226 liveuser 17828
 
66 liveuser 17829
						}#if end
226 liveuser 17830
 
66 liveuser 17831
					#設置正常
17832
					$result["status"]="true";
226 liveuser 17833
 
66 liveuser 17834
					#回傳結果
17835
					return $result;
226 liveuser 17836
 
66 liveuser 17837
					}#if end
226 liveuser 17838
 
66 liveuser 17839
				#執行到這邊代表使用者認證通過
226 liveuser 17840
 
66 liveuser 17841
				#依照 user 取得其所屬 group
17842
				#函式說明:
17843
				#id指令來取得目標賬號的群組資訊
17844
				#回傳結果:
17845
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
17846
				#$reuslt["error"],執行不正常結束的錯訊息陣列.
17847
				#$result["function"],當前執行的函式名稱.
17848
				#$result["content"],呼叫完WebService所得回傳結果.
17849
				#$result["content"]["groupId"],群組的id.
17850
				#$result["content"]["belongGroupName"],陣列,隸屬的群組名稱陣列.
17851
				#$result["content"]["belongGroupId"],陣列,隸屬的群組id.
17852
				#必填參數:
17853
				#$conf["user"],字串,要取得群組資訊的目標使用者名稱.
17854
				$conf["authenticate::getUserGroup"]["user"]=$user;
17855
				#可省略參數:
17856
				#無.
17857
				#參考資料:
17858
				#無.
17859
				#備註:
17860
				#無.
17861
				$getUserGroup=authenticate::getUserGroup($conf["authenticate::getUserGroup"]);
17862
				unset($conf["authenticate::getUserGroup"]);
226 liveuser 17863
 
66 liveuser 17864
				#如果執行異常
17865
				if($getUserGroup["status"]==="false"){
226 liveuser 17866
 
66 liveuser 17867
					#設置異常
17868
					$result["status"]="false";
226 liveuser 17869
 
66 liveuser 17870
					#設置錯誤訊息
17871
					$result["error"]=$getUserGroup;
226 liveuser 17872
 
66 liveuser 17873
					#回傳結果
17874
					return $result;
226 liveuser 17875
 
66 liveuser 17876
					}#if end
226 liveuser 17877
 
66 liveuser 17878
				#設置預設的權限為 "false"
17879
				$authStatus="false";
226 liveuser 17880
 
66 liveuser 17881
				#針對每個取得的群組名稱
17882
				foreach($getUserGroup["content"]["belongGroupName"] as $groupName){
226 liveuser 17883
 
66 liveuser 17884
					#如果是 root
17885
					if($groupName==="root"){
226 liveuser 17886
 
66 liveuser 17887
						#設置得到的權限
17888
						$authStatus=$groupName;
226 liveuser 17889
 
66 liveuser 17890
						#結束 foreach
17891
						break;
226 liveuser 17892
 
66 liveuser 17893
						}#if end
226 liveuser 17894
 
66 liveuser 17895
					#反之如果是公開的使用者
17896
					else if($groupName==="public"){
226 liveuser 17897
 
66 liveuser 17898
						#設置得到的權限
17899
						$authStatus=$groupName;
226 liveuser 17900
 
66 liveuser 17901
						}#if end
226 liveuser 17902
 
66 liveuser 17903
					#其他群組名稱
17904
					else{
226 liveuser 17905
 
66 liveuser 17906
						#跳過
17907
						continue;
226 liveuser 17908
 
66 liveuser 17909
						}#else end
226 liveuser 17910
 
66 liveuser 17911
					}#foreach end
226 liveuser 17912
 
66 liveuser 17913
				#設置正常
17914
				$result["status"]="true";
226 liveuser 17915
 
66 liveuser 17916
				#回傳結果
17917
				return $result;
226 liveuser 17918
 
66 liveuser 17919
				#跳出 switch
17920
				break;
226 liveuser 17921
 
66 liveuser 17922
			#其他類型
17923
			default:
226 liveuser 17924
 
66 liveuser 17925
				#設置不適用
17926
				$result["status"]="continue";
226 liveuser 17927
 
66 liveuser 17928
				#回傳結果
17929
				return $result;
226 liveuser 17930
 
66 liveuser 17931
			}#switch end
226 liveuser 17932
 
66 liveuser 17933
		#執行到這邊代表異常
17934
 
17935
		#設置異常
17936
		$result["status"]="false";
17937
 
17938
		#回傳結果
17939
		return $result;
226 liveuser 17940
 
66 liveuser 17941
		}#function auth end
226 liveuser 17942
 
66 liveuser 17943
	/*
17944
	#函式說明:
17945
	#提供webSock::nativeSocketTcpIpServer使用基本功能(basic).
17946
	#回傳結果:
17947
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
17948
	#$result["error"],執行不正常結束的錯訊息陣列.
17949
	#$result["argu"],陣列,使用的參數.
17950
	#必填參數:
17951
	#$conf["data"],字串,收到的bin2hex編碼後再gpg加密過後的json格式資料.
17952
	$conf["data"]="";
17953
	#$conf["serverSock"],resource,web socket server socket
17954
	$conf["serverSock"]=$resource;
17955
	#$conf["clientSock"],$resource,web socket client socket
17956
	$conf["clientSock"]=$resource;
17957
	#$conf["clientInfo"],陣列,web socket client info.
17958
	$conf["clientInfo"]=array();
17959
	#$conf["clientIndex"],整數.web socket client index.
17960
	$conf["clientIndex"];
17961
	#$conf["allConn"],陣列,all web socket client info.
17962
	$conf["allConn"]=array();
17963
	#可省略參數:
17964
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
17965
	#$conf["wsMode"]="true";
17966
	#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
17967
	#$conf["gpgId"]=gnupgId;
17968
	#參考資料:
17969
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
17970
	#備註:
17971
	#收到用戶的"id?"訊息,會回傳用戶的id.
17972
	#收到用戶的"ids?"訊息,會回傳非自己的所有用戶id.
17973
	#收到用戶的"talkTo?"訊息,會回傳目前在跟誰談話.
17974
	#收到用戶的"talkTo:client-id"訊息,會建立與id對應的用戶對話,此後傳遞的訊息均會給對方.
17975
	#結束連線的訊息"quit".
323 liveuser 17976
	#目前不適用於webSock::nativeSocketTcpIpServer.
66 liveuser 17977
	*/
17978
	public static function basic(&$conf){
226 liveuser 17979
 
66 liveuser 17980
		#初始化要回傳的結果
17981
		$result=array();
17982
 
17983
		#取得當前執行的函數名稱
17984
		$result["function"]=__FUNCTION__;
17985
 
17986
		#涵式說明:
17987
		#判斷當前環境為web還是cmd
17988
		#回傳結果:
17989
		#$result,"web"或"cmd"
17990
		if(csInformation::getEnv()==="web"){
226 liveuser 17991
 
66 liveuser 17992
			#設置執行失敗
17993
			$result["status"]="false";
226 liveuser 17994
 
66 liveuser 17995
			#設置執行錯誤訊息
17996
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 17997
 
66 liveuser 17998
			#回傳結果
17999
			return $result;
226 liveuser 18000
 
66 liveuser 18001
			}#if end
18002
 
18003
		#取得參數
18004
		$result["argu"]=$conf;
18005
 
18006
		#如果 $conf 不為陣列
18007
		if(gettype($conf)!="array"){
226 liveuser 18008
 
66 liveuser 18009
			#設置執行失敗
18010
			$result["status"]="false";
226 liveuser 18011
 
66 liveuser 18012
			#設置執行錯誤訊息
18013
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 18014
 
66 liveuser 18015
			#如果傳入的參數為 null
18016
			if($conf==null){
226 liveuser 18017
 
66 liveuser 18018
				#設置執行錯誤訊息
18019
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 18020
 
66 liveuser 18021
				}#if end
18022
 
18023
			#回傳結果
18024
			return $result;
226 liveuser 18025
 
66 liveuser 18026
			}#if end
226 liveuser 18027
 
66 liveuser 18028
		#檢查參數
18029
		#函式說明:
18030
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
18031
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18032
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
18033
		#$result["function"],當前執行的函式名稱.
18034
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
18035
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
18036
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
18037
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
18038
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
18039
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
18040
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
18041
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
18042
		#必填寫的參數:
18043
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
18044
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
18045
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
18046
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientInfo","clientIndex","allConn");
18047
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
18048
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","array","string","array");
18049
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
18050
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
18051
		#可以省略的參數:
18052
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
18053
		#$conf["canBeEmptyString"]="false";
18054
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
18055
		#$conf["canNotBeEmpty"]=array();
18056
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
18057
		#$conf["canBeEmpty"]=array();
18058
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
18059
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
18060
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
18061
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode","gpgId");
226 liveuser 18062
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 18063
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
18064
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
18065
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",gnupgId);
18066
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
18067
		#$conf["arrayCountEqualCheck"][]=array();
18068
		#參考資料來源:
18069
		#array_keys=>http://php.net/manual/en/function.array-keys.php
18070
		#建議:
18071
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
18072
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
18073
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 18074
 
66 liveuser 18075
		#如果檢查參數失敗
18076
		if($checkArguments["status"]==="false"){
226 liveuser 18077
 
66 liveuser 18078
			#設置執行失敗
18079
			$result["status"]="false";
226 liveuser 18080
 
66 liveuser 18081
			#設置執行錯誤訊息
18082
			$result["error"]=$checkArguments;
226 liveuser 18083
 
66 liveuser 18084
			#回傳結果
18085
			return $result;
226 liveuser 18086
 
66 liveuser 18087
			}#if end
226 liveuser 18088
 
66 liveuser 18089
		#如果檢查參數不通過
18090
		if($checkArguments["passed"]==="false"){
226 liveuser 18091
 
66 liveuser 18092
			#設置執行失敗
18093
			$result["status"]="false";
226 liveuser 18094
 
66 liveuser 18095
			#設置執行錯誤訊息
18096
			$result["error"]=$checkArguments;
226 liveuser 18097
 
66 liveuser 18098
			#回傳結果
18099
			return $result;
226 liveuser 18100
 
66 liveuser 18101
			}#if end
18102
 
18103
		#取得收到的訊息
18104
		$receivedData=$conf["data"];
226 liveuser 18105
 
66 liveuser 18106
		#取得 server 的 socket
18107
		$serverSocket=$conf["serverSock"];
226 liveuser 18108
 
66 liveuser 18109
		#取得 client 的 socket
18110
		$clientSocket=$conf["clientSock"];
226 liveuser 18111
 
66 liveuser 18112
		#取得 client 的資訊
18113
		$clientInfo=$conf["clientInfo"];
226 liveuser 18114
 
66 liveuser 18115
		#取得 client 的索引
18116
		$clientIndex=$conf["clientIndex"];
226 liveuser 18117
 
66 liveuser 18118
		#取得 all clients 的資訊
18119
		$allConn=&$conf["allConn"];
226 liveuser 18120
 
66 liveuser 18121
		#hex2bin
18122
		#函式說明:
18123
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
18124
		#回傳結果:
226 liveuser 18125
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 18126
		#$result["function"],當前執行的函數名稱.
18127
		#$result["content"],加密後的結果.
18128
		#$result["error"],錯誤訊息陣列.
18129
		#$result["argu"],使用的參數.
18130
		#必填參數:
18131
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
18132
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
18133
		#$conf["enCodeType"],"字串",加密的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin",7種,"sha1"較耗時,"md5"較快,"p_hash"適用於密碼加密,"aes256"是對稱式加解密,"qbpwcf"是透過urlencode、json_encode、base64_encode的結果,"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin".
18134
		$conf["authenticate::enCodeStr"]["enCodeType"]="hex2bin";
18135
		#可省略參數:
18136
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
18137
		#$conf["sha1Raw"]="false";
18138
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
18139
		#$conf["p_hash"]="";
18140
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
18141
		#$conf["keyForAes256"]="";
18142
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
18143
		#$conf["aes256Encode"]="";
18144
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
18145
		#$conf["qbpwcfDecode"]="false";
18146
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
18147
		#$conf["gpgDecrypt"]="false";
18148
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
18149
		#$conf["gpgId"]="";
18150
		#參考資料:
18151
		#sha1=>http://php.net/manual/en/function.sha1.php
18152
		#md5=>http://php.net/manual/en/function.md5.php
18153
		#password_hash=>http://php.net/manual/en/function.password-hash.php
18154
		#password_verify=>http://php.net/manual/en/function.password-verify.php
18155
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
18156
		#備註:
18157
		#無.
18158
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
18159
		unset($conf["authenticate::enCodeStr"]);
18160
 
18161
		#如果執行失敗
18162
		if($enCodeStr["status"]==="false"){
18163
 
18164
			#設置執行異常
18165
			$result["status"]="false";
18166
 
18167
			#設置執行錯誤
18168
			$result["error"]=$enCodeStr;
18169
 
18170
			#回傳結果
18171
			return $result;
18172
 
18173
			}#if end
18174
 
18175
		#取得hex2bin後的字串
18176
		$receivedData=$enCodeStr["content"];
226 liveuser 18177
 
66 liveuser 18178
		#gpg decrypt
18179
		#函式說明:
18180
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
18181
		#回傳結果:
226 liveuser 18182
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 18183
		#$result["function"],當前執行的函數名稱.
18184
		#$result["content"],加密後的結果.
18185
		#$result["error"],錯誤訊息陣列.
18186
		#$result["argu"],使用的參數.
18187
		#必填參數:
18188
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
18189
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
18190
		#$conf["enCodeType"],"字串",加密的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin",7種,"sha1"較耗時,"md5"較快,"p_hash"適用於密碼加密,"aes256"是對稱式加解密,"qbpwcf"是透過urlencode、json_encode、base64_encode的結果,"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin".
18191
		$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
18192
		#可省略參數:
18193
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
18194
		#$conf["sha1Raw"]="false";
18195
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
18196
		#$conf["p_hash"]="";
18197
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
18198
		#$conf["keyForAes256"]="";
18199
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
18200
		#$conf["aes256Encode"]="";
18201
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
18202
		#$conf["qbpwcfDecode"]="false";
18203
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
18204
		$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
18205
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
18206
		$conf["authenticate::enCodeStr"]["gpgId"]=$conf["gpgId"];
18207
		#參考資料:
18208
		#sha1=>http://php.net/manual/en/function.sha1.php
18209
		#md5=>http://php.net/manual/en/function.md5.php
18210
		#password_hash=>http://php.net/manual/en/function.password-hash.php
18211
		#password_verify=>http://php.net/manual/en/function.password-verify.php
18212
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
18213
		#備註:
18214
		#無.
18215
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
18216
		unset($conf["authenticate::enCodeStr"]);
18217
 
18218
		#如果執行失敗
18219
		if($enCodeStr["status"]==="false"){
18220
 
18221
			#設置執行異常
18222
			$result["status"]="false";
18223
 
18224
			#設置執行錯誤
18225
			$result["error"]=$enCodeStr;
18226
 
18227
			#回傳結果
18228
			return $result;
18229
 
18230
			}#if end
18231
 
18232
		#取得解密後的字串
18233
		$receivedData=$enCodeStr["content"];
226 liveuser 18234
 
66 liveuser 18235
		#json_decode
18236
		$receivedData=json_decode($receivedData);
226 liveuser 18237
 
66 liveuser 18238
		#如果收到的是 id?
18239
		if($receivedData==="id?"){
226 liveuser 18240
 
66 liveuser 18241
			#如果尚未認證
18242
			if($connections[$conIndex]["auth"]==="false"){
226 liveuser 18243
 
66 liveuser 18244
				#設置要回傳的訊息
18245
				$talkback="permission denied";
226 liveuser 18246
 
66 liveuser 18247
				}#if end
226 liveuser 18248
 
66 liveuser 18249
			else{
226 liveuser 18250
 
66 liveuser 18251
				#設置要回傳的訊息
18252
				$talkback=$connections[$conIndex]["id"];
226 liveuser 18253
 
66 liveuser 18254
				}#else end
18255
 
18256
			#debug
18257
			#var_dump(__LINE__,$talkback);
18258
 
18259
			#json encode 要回傳的訊息
18260
			$talkback=json_encode($talkback);
226 liveuser 18261
 
66 liveuser 18262
			#debug
18263
			#var_dump(__LINE__,$talkback);
226 liveuser 18264
 
66 liveuser 18265
			#如果是 ws 模式
18266
			if($conf["wsMode"]==="true"){
226 liveuser 18267
 
66 liveuser 18268
				#如果已經 handshake 過
18269
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18270
 
18271
					#如果要 unmask
66 liveuser 18272
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18273
 
66 liveuser 18274
						#函式說明:
226 liveuser 18275
						#加密 handshake 後要傳送的訊息
66 liveuser 18276
						#回傳結果:
18277
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18278
						#$result["error"],執行不正常結束的錯訊息陣列.
18279
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18280
						#$result["argu"],陣列,使用的參數.
18281
						#必填參數:
18282
						#$conf["text"],字串,要加密的訊息.
226 liveuser 18283
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18284
						#可省略參數:
18285
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18286
						#$conf["payloadIsBin"]="false";
18287
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18288
						#$conf["ping"]="false";
18289
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18290
						#$conf["pong"]="false";
18291
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18292
						#$conf["frames"]=array();
18293
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18294
						#$conf["mask"]="false";
18295
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18296
						#$conf["debug"]="false";
18297
						#參考資料:
18298
						#無.
18299
						#備註:
18300
						#目前$conf["text"]長度超過125會出錯.
18301
						$talkback=webSock::encode($conf["webSock::encode"]);
18302
						unset($conf["webSock::encode"]);
226 liveuser 18303
 
66 liveuser 18304
						#如果執行失敗
18305
						if($talkback["status"]==="false"){
226 liveuser 18306
 
66 liveuser 18307
							#印出結果
18308
							var_dump($talkback);
226 liveuser 18309
 
66 liveuser 18310
							#結束執行
18311
							exit;
226 liveuser 18312
 
66 liveuser 18313
							}#if end
226 liveuser 18314
 
66 liveuser 18315
						#debug
18316
						#var_dump(__LINE__,$talkback);
226 liveuser 18317
 
66 liveuser 18318
						}#if end
226 liveuser 18319
 
66 liveuser 18320
					}#if end
226 liveuser 18321
 
66 liveuser 18322
				}#if end
226 liveuser 18323
 
66 liveuser 18324
			#反之不為 web socket 訊息
18325
			else{
226 liveuser 18326
 
66 liveuser 18327
				#儲存成只有一個訊息
18328
				$talkback["content"][]=$talkback;
226 liveuser 18329
 
66 liveuser 18330
				}#else
226 liveuser 18331
 
66 liveuser 18332
			#針對每個訊息的分段
18333
			foreach($talkback["content"] as $msg){
226 liveuser 18334
 
66 liveuser 18335
				#debug
18336
				var_dump(__LINE__,$msg);
226 liveuser 18337
 
66 liveuser 18338
				#回傳訊息
18339
				$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 18340
 
66 liveuser 18341
				#debug
18342
				var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 18343
 
66 liveuser 18344
				}#foreach end
226 liveuser 18345
 
66 liveuser 18346
			#設置執行正常
18347
			$result["status"]="true";
226 liveuser 18348
 
66 liveuser 18349
			#回傳結果
18350
			return $result;
226 liveuser 18351
 
66 liveuser 18352
			}#if end
226 liveuser 18353
 
66 liveuser 18354
		#反之如果收到的是 "quit"
18355
		else if($receivedData==="quit"){
226 liveuser 18356
 
66 liveuser 18357
			#設置要回傳的訊息
18358
			$talkback="結束與 server 的連線";
226 liveuser 18359
 
66 liveuser 18360
			#json encode 要回傳的訊息
18361
			$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 18362
 
66 liveuser 18363
			#如果是 ws 模式
18364
			if($conf["wsMode"]==="true"){
226 liveuser 18365
 
66 liveuser 18366
				#如果已經 handshake 過
18367
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18368
 
18369
					#如果要 unmask
66 liveuser 18370
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18371
 
66 liveuser 18372
						#函式說明:
226 liveuser 18373
						#加密 handshake 後要傳送的訊息
66 liveuser 18374
						#回傳結果:
18375
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18376
						#$result["error"],執行不正常結束的錯訊息陣列.
18377
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18378
						#$result["argu"],陣列,使用的參數.
18379
						#必填參數:
18380
						#$conf["text"],字串,要加密的訊息.
226 liveuser 18381
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18382
						#可省略參數:
18383
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18384
						#$conf["payloadIsBin"]="false";
18385
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18386
						#$conf["ping"]="false";
18387
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18388
						#$conf["pong"]="false";
18389
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18390
						#$conf["frames"]=array();
18391
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18392
						#$conf["mask"]="false";
18393
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18394
						#$conf["debug"]="false";
18395
						#參考資料:
18396
						#無.
18397
						#備註:
18398
						#目前$conf["text"]長度超過125會出錯.
18399
						$talkback=webSock::encode($conf["webSock::encode"]);
18400
						unset($conf["webSock::encode"]);
226 liveuser 18401
 
66 liveuser 18402
						#如果執行失敗
18403
						if($talkback["status"]==="false"){
226 liveuser 18404
 
66 liveuser 18405
							#印出結果
18406
							var_dump($talkback);
226 liveuser 18407
 
66 liveuser 18408
							#結束執行
18409
							exit;
226 liveuser 18410
 
66 liveuser 18411
							}#if end
226 liveuser 18412
 
66 liveuser 18413
						#debug
18414
						#var_dump(__LINE__,$talkback);
226 liveuser 18415
 
66 liveuser 18416
						}#if end
226 liveuser 18417
 
66 liveuser 18418
					}#if end
226 liveuser 18419
 
66 liveuser 18420
				}#if end
226 liveuser 18421
 
66 liveuser 18422
			#反之不為 web socket 訊息
18423
			else{
226 liveuser 18424
 
66 liveuser 18425
				#儲存成只有一個訊息
18426
				$talkback["content"][]=$talkback;
226 liveuser 18427
 
66 liveuser 18428
				}#else
226 liveuser 18429
 
66 liveuser 18430
			#針對每個訊息的分段
18431
			foreach($talkback["content"] as $msg){
226 liveuser 18432
 
66 liveuser 18433
				#回傳訊息
18434
				$socket_write=socket_write($con["connect"], $msg, strlen($msg));
226 liveuser 18435
 
66 liveuser 18436
				#debug
18437
				#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 18438
 
66 liveuser 18439
				}#foreach end
226 liveuser 18440
 
18441
			#關閉被 client 的連線
66 liveuser 18442
			socket_close($con["connect"]);
226 liveuser 18443
 
66 liveuser 18444
			#清理連線的陣列
18445
			unset($connections[$conIndex]);
226 liveuser 18446
 
66 liveuser 18447
			#設置執行正常
18448
			$result["status"]="true";
226 liveuser 18449
 
66 liveuser 18450
			#回傳結果
18451
			return $result;
226 liveuser 18452
 
66 liveuser 18453
			}#if end
226 liveuser 18454
 
66 liveuser 18455
		#反之是如果收到的是 ids?
18456
		else if($receivedData === 'ids?'){
226 liveuser 18457
 
66 liveuser 18458
			#如果尚未認證
18459
			if($connections[$conIndex]["auth"]==="false"){
226 liveuser 18460
 
66 liveuser 18461
				#設置要回傳的訊息
18462
				$talkback=json_encode("permission denied");
226 liveuser 18463
 
66 liveuser 18464
				}#if end
226 liveuser 18465
 
66 liveuser 18466
			#反之
18467
			else{
226 liveuser 18468
 
66 liveuser 18469
				#設置要回傳的訊息
18470
				$talkback=array();
226 liveuser 18471
 
66 liveuser 18472
				#針對每個連線
18473
				foreach($connections as $conIndex_ids => $con_ids){
18474
 
18475
					#如果不是自己
18476
					if($con_ids["connect"]!==$connections[$conIndex]["connect"]){
226 liveuser 18477
 
66 liveuser 18478
						#記錄其他人的id
18479
						$talkback[]=$con_ids["id"];
226 liveuser 18480
 
66 liveuser 18481
						}#if end
226 liveuser 18482
 
66 liveuser 18483
					}#foreach end
226 liveuser 18484
 
66 liveuser 18485
				#json encode要回傳的id陣列
18486
				$talkback=json_encode($talkback);
226 liveuser 18487
 
66 liveuser 18488
				}#else end
226 liveuser 18489
 
66 liveuser 18490
			#如果是 ws 模式
18491
			if($conf["wsMode"]==="true"){
226 liveuser 18492
 
66 liveuser 18493
				#如果已經 handshake 過
18494
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18495
 
66 liveuser 18496
					#如果要 unmask
18497
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18498
 
66 liveuser 18499
						#函式說明:
226 liveuser 18500
						#加密 handshake 後要傳送的訊息
66 liveuser 18501
						#回傳結果:
18502
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18503
						#$result["error"],執行不正常結束的錯訊息陣列.
18504
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18505
						#$result["argu"],陣列,使用的參數.
18506
						#必填參數:
18507
						#$conf["text"],字串,要加密的訊息.
226 liveuser 18508
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18509
						#可省略參數:
18510
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18511
						#$conf["payloadIsBin"]="false";
18512
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18513
						#$conf["ping"]="false";
18514
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18515
						#$conf["pong"]="false";
18516
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18517
						#$conf["frames"]=array();
18518
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18519
						#$conf["mask"]="false";
18520
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18521
						#$conf["debug"]="false";
18522
						#參考資料:
18523
						#無.
18524
						#備註:
18525
						#目前$conf["text"]長度超過125會出錯.
18526
						$talkback=webSock::encode($conf["webSock::encode"]);
18527
						unset($conf["webSock::encode"]);
226 liveuser 18528
 
66 liveuser 18529
						#如果執行失敗
18530
						if($talkback["status"]==="false"){
226 liveuser 18531
 
66 liveuser 18532
							#印出結果
18533
							var_dump($talkback);
226 liveuser 18534
 
66 liveuser 18535
							#結束執行
18536
							exit;
226 liveuser 18537
 
66 liveuser 18538
							}#if end
226 liveuser 18539
 
66 liveuser 18540
						#debug
18541
						#var_dump(__LINE__,$talkback);
226 liveuser 18542
 
66 liveuser 18543
						}#if end
226 liveuser 18544
 
66 liveuser 18545
					}#if end
226 liveuser 18546
 
66 liveuser 18547
				}#if end
226 liveuser 18548
 
66 liveuser 18549
			#反之不為 web socket 訊息
18550
			else{
226 liveuser 18551
 
66 liveuser 18552
				#儲存成只有一個訊息
18553
				$talkback["content"][]=$talkback;
226 liveuser 18554
 
66 liveuser 18555
				}#else
226 liveuser 18556
 
66 liveuser 18557
			#針對每個訊息的分段
18558
			foreach($talkback["content"] as $msg){
226 liveuser 18559
 
66 liveuser 18560
				#回傳訊息
18561
				$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 18562
 
66 liveuser 18563
				#debug
18564
				var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 18565
 
66 liveuser 18566
				}#foreach end
226 liveuser 18567
 
66 liveuser 18568
			#設置執行正常
18569
			$result["status"]="true";
226 liveuser 18570
 
66 liveuser 18571
			#回傳結果
18572
			return $result;
226 liveuser 18573
 
66 liveuser 18574
			}#if end
226 liveuser 18575
 
66 liveuser 18576
		#反之如果收到 "talkTo?"
18577
		else if($receivedData==="talkTo?"){
226 liveuser 18578
 
66 liveuser 18579
			#如果尚未認證
18580
			if($connections[$conIndex]["auth"]==="false"){
226 liveuser 18581
 
66 liveuser 18582
				#設置要回傳的訊息
18583
				$talkback=json_encode("permission denied");
226 liveuser 18584
 
66 liveuser 18585
				}#if end
226 liveuser 18586
 
66 liveuser 18587
			#反之
18588
			else{
226 liveuser 18589
 
66 liveuser 18590
				#初始化要講話的id陣列
18591
				$talkback=array();
226 liveuser 18592
 
66 liveuser 18593
				#有幾個要講話的人就執行幾次
18594
				foreach($connections[$conIndex]["talkTo"] as $to){
226 liveuser 18595
 
66 liveuser 18596
					#串街要講話的人
18597
					$talkback[]=$to;
226 liveuser 18598
 
66 liveuser 18599
					}#foreach end
226 liveuser 18600
 
66 liveuser 18601
				#設置要回傳的訊息
18602
				$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 18603
 
66 liveuser 18604
				}#else end
226 liveuser 18605
 
66 liveuser 18606
			#如果是 ws 模式
18607
			if($conf["wsMode"]==="true"){
226 liveuser 18608
 
66 liveuser 18609
				#如果已經 handshake 過
18610
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18611
 
18612
					#如果要 unmask
66 liveuser 18613
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18614
 
66 liveuser 18615
						#函式說明:
226 liveuser 18616
						#加密 handshake 後要傳送的訊息
66 liveuser 18617
						#回傳結果:
18618
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18619
						#$result["error"],執行不正常結束的錯訊息陣列.
18620
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18621
						#$result["argu"],陣列,使用的參數.
18622
						#必填參數:
18623
						#$conf["text"],字串,要加密的訊息.
226 liveuser 18624
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18625
						#可省略參數:
18626
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18627
						#$conf["payloadIsBin"]="false";
18628
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18629
						#$conf["ping"]="false";
18630
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18631
						#$conf["pong"]="false";
18632
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18633
						#$conf["frames"]=array();
18634
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18635
						#$conf["mask"]="false";
18636
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18637
						#$conf["debug"]="false";
18638
						#參考資料:
18639
						#無.
18640
						#備註:
18641
						#目前$conf["text"]長度超過125會出錯.
18642
						$talkback=webSock::encode($conf["webSock::encode"]);
18643
						unset($conf["webSock::encode"]);
226 liveuser 18644
 
66 liveuser 18645
						#如果執行失敗
18646
						if($talkback["status"]==="false"){
226 liveuser 18647
 
66 liveuser 18648
							#印出結果
18649
							var_dump($talkback);
226 liveuser 18650
 
66 liveuser 18651
							#結束執行
18652
							exit;
226 liveuser 18653
 
66 liveuser 18654
							}#if end
226 liveuser 18655
 
66 liveuser 18656
						#debug
18657
						#var_dump(__LINE__,$talkback);
226 liveuser 18658
 
66 liveuser 18659
						}#if end
226 liveuser 18660
 
66 liveuser 18661
					}#if end
226 liveuser 18662
 
66 liveuser 18663
				}#if end
226 liveuser 18664
 
66 liveuser 18665
			#反之不為 web socket 訊息
18666
			else{
226 liveuser 18667
 
66 liveuser 18668
				#儲存成只有一個訊息
18669
				$talkback["content"][]=$talkback;
226 liveuser 18670
 
66 liveuser 18671
				}#else
226 liveuser 18672
 
66 liveuser 18673
			#針對每個訊息的分段
18674
			foreach($talkback["content"] as $msg){
226 liveuser 18675
 
66 liveuser 18676
				#回傳訊息
18677
				$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 18678
 
66 liveuser 18679
				#debug
18680
				#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 18681
 
66 liveuser 18682
				}#foreach end
226 liveuser 18683
 
66 liveuser 18684
			#設置執行正常
18685
			$result["status"]="true";
226 liveuser 18686
 
66 liveuser 18687
			#回傳結果
18688
			return $result;
226 liveuser 18689
 
66 liveuser 18690
			}#if end
226 liveuser 18691
 
66 liveuser 18692
		#如果收到的訊息長度大於 "talkTo:"
18693
		if(strlen($receivedData)>strlen("talkTo:")){
226 liveuser 18694
 
66 liveuser 18695
			#如果收到開頭為 "talkTo:"
18696
			#涵式說明:
18697
			#取得符合特定字首與字尾的字串
18698
			#回傳的結果:
18699
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
18700
			#$result["function"],當前執行的函數名稱.
18701
			#$result["error"],錯誤訊息陣列.
18702
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
18703
			#$result["returnString"],爲符合字首條件的字串內容。
18704
			#必填參數:
18705
			#$conf["checkString"],字串,要檢查的字串.
18706
			$conf["search::getMeetConditionsString"]["checkString"]=$receivedData;
18707
			#可省略參數:
18708
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
18709
			$conf["search::getMeetConditionsString"]["frontWord"]="talkTo:";
18710
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
18711
			#$conf["tailWord"]="";
18712
			#參考資料:
18713
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
18714
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
18715
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 18716
 
66 liveuser 18717
			#如果選找前置字串 "talkTo:" 失敗
18718
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 18719
 
66 liveuser 18720
				#設置執行失敗
18721
				$result["status"]="false";
226 liveuser 18722
 
66 liveuser 18723
				#設置執行錯誤訊息
18724
				$result["error"]=$getMeetConditionsString;
226 liveuser 18725
 
66 liveuser 18726
				#回傳結果
18727
				return $result;
226 liveuser 18728
 
66 liveuser 18729
				}#if end
226 liveuser 18730
 
66 liveuser 18731
			#如果存在 "talkTo:" 前置字串
18732
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 18733
 
66 liveuser 18734
				#如果尚未認證
18735
				if($connections[$conIndex]["auth"]==="false"){
226 liveuser 18736
 
66 liveuser 18737
					#設置要回傳的訊息
18738
					$talkback=json_encode("permission denied");
226 liveuser 18739
 
66 liveuser 18740
					#如果是 ws 模式
18741
					if($conf["wsMode"]==="true"){
226 liveuser 18742
 
66 liveuser 18743
						#如果已經 handshake 過
18744
						if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18745
 
18746
							#如果要 unmask
66 liveuser 18747
							if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18748
 
66 liveuser 18749
								#函式說明:
226 liveuser 18750
								#加密 handshake 後要傳送的訊息
66 liveuser 18751
								#回傳結果:
18752
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18753
								#$result["error"],執行不正常結束的錯訊息陣列.
18754
								#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18755
								#$result["argu"],陣列,使用的參數.
18756
								#必填參數:
18757
								#$conf["text"],字串,要加密的訊息.
226 liveuser 18758
								$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18759
								#可省略參數:
18760
								#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18761
								#$conf["payloadIsBin"]="false";
18762
								#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18763
								#$conf["ping"]="false";
18764
								#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18765
								#$conf["pong"]="false";
18766
								#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18767
								#$conf["frames"]=array();
18768
								#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18769
								#$conf["mask"]="false";
18770
								#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18771
								#$conf["debug"]="false";
18772
								#參考資料:
18773
								#無.
18774
								#備註:
18775
								#目前$conf["text"]長度超過125會出錯.
18776
								$talkback=webSock::encode($conf["webSock::encode"]);
18777
								unset($conf["webSock::encode"]);
226 liveuser 18778
 
66 liveuser 18779
								#如果執行失敗
18780
								if($talkback["status"]==="false"){
226 liveuser 18781
 
66 liveuser 18782
									#印出結果
18783
									var_dump($talkback);
226 liveuser 18784
 
66 liveuser 18785
									#結束執行
18786
									exit;
226 liveuser 18787
 
66 liveuser 18788
									}#if end
226 liveuser 18789
 
66 liveuser 18790
								#debug
18791
								#var_dump(__LINE__,$talkback);
226 liveuser 18792
 
66 liveuser 18793
								}#if end
226 liveuser 18794
 
66 liveuser 18795
							}#if end
226 liveuser 18796
 
66 liveuser 18797
						}#if end
226 liveuser 18798
 
66 liveuser 18799
					#反之不為 web socket 訊息
18800
					else{
226 liveuser 18801
 
66 liveuser 18802
						#儲存成只有一個訊息
18803
						$talkback["content"][]=$talkback;
226 liveuser 18804
 
66 liveuser 18805
						}#else
226 liveuser 18806
 
66 liveuser 18807
					#針對每個訊息的分段
18808
					foreach($talkback["content"] as $msg){
226 liveuser 18809
 
66 liveuser 18810
						#回傳訊息
18811
						$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 18812
 
66 liveuser 18813
						#debug
18814
						#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 18815
 
66 liveuser 18816
						}#foreach end
226 liveuser 18817
 
66 liveuser 18818
					#設置執行正常
18819
					$result["status"]="true";
226 liveuser 18820
 
66 liveuser 18821
					#回傳結果
18822
					return $result;
226 liveuser 18823
 
66 liveuser 18824
					}#if end
226 liveuser 18825
 
66 liveuser 18826
				#用 "talkTo:" 分割收到的訊息
18827
				#涵式說明:
18828
				#將固定格式的字串分開,並回傳分開的結果。
18829
				#回傳結果:
18830
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18831
				#$result["error"],錯誤訊息陣列
18832
				#$result["function"],當前執行的函數名稱.
18833
				#$result["oriStr"],要分割的原始字串內容
18834
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
18835
				#$result["dataCounts"],爲總共分成幾段
18836
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
18837
				#必填的參數:
18838
				$conf["stringProcess::spiltString"]["stringIn"]=$receivedData;#要處理的字串。
18839
				$conf["stringProcess::spiltString"]["spiltSymbol"]="talkTo:";#爲以哪個符號作爲分割
18840
				#可省略參數:
18841
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
18842
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
18843
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
18844
				unset($conf["stringProcess::spiltString"]);
226 liveuser 18845
 
66 liveuser 18846
				#如果分割字串失敗
18847
				if($spiltString["status"]==="false"){
226 liveuser 18848
 
66 liveuser 18849
					#設置執行失敗
18850
					$result["status"]="false";
226 liveuser 18851
 
66 liveuser 18852
					#設置執行錯誤訊息
18853
					$result["error"]=$spiltString;
226 liveuser 18854
 
66 liveuser 18855
					#回傳結果
18856
					return $result;
226 liveuser 18857
 
66 liveuser 18858
					}#if end
226 liveuser 18859
 
66 liveuser 18860
				#如果剛好分割出一筆資料
18861
				if($spiltString["dataCounts"]===1){
226 liveuser 18862
 
66 liveuser 18863
					#取得自己的id
18864
					$myId=$connections[$conIndex]["id"];
226 liveuser 18865
 
66 liveuser 18866
					#取得講話對象的id
18867
					$toId=$spiltString["dataArray"][0];
226 liveuser 18868
 
66 liveuser 18869
					#設置對象不存在的識別
18870
					$targetExist=false;
226 liveuser 18871
 
66 liveuser 18872
					#設置通話對象的key
18873
					$targetKey="";
226 liveuser 18874
 
66 liveuser 18875
					#取得除了自己的id以外的所有連線
18876
					foreach($connections as $index=>$talkInfo){
226 liveuser 18877
 
66 liveuser 18878
						#除了自己的id
18879
						if($talkInfo["id"]!==$myId){
226 liveuser 18880
 
66 liveuser 18881
							#如果存在要對話的對象
18882
							if($talkInfo["id"]===$toId){
226 liveuser 18883
 
66 liveuser 18884
								#設置對象存在的識別
18885
								$targetExist=true;
226 liveuser 18886
 
66 liveuser 18887
								#通話對象的key
18888
								$targetKey=$index;
226 liveuser 18889
 
66 liveuser 18890
								}#if end
226 liveuser 18891
 
66 liveuser 18892
							}#if end
226 liveuser 18893
 
66 liveuser 18894
						}#for each end
18895
 
18896
					#如果通話對象存在
18897
					if($targetExist){
226 liveuser 18898
 
66 liveuser 18899
						#保存自己的通話對象
18900
						$connections[$conIndex]["talkTo"][]=$toId;
226 liveuser 18901
 
66 liveuser 18902
						#設置要給自己看的訊息
18903
						$talkback="您與 ".$toId." 展開對話";
226 liveuser 18904
 
66 liveuser 18905
						#json encode 要給自己看的訊息
18906
						$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 18907
 
66 liveuser 18908
						#如果是 ws 模式
18909
						if($conf["wsMode"]==="true"){
226 liveuser 18910
 
66 liveuser 18911
							#如果已經 handshake 過
18912
							if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18913
 
18914
								#如果要 unmask
66 liveuser 18915
								if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18916
 
66 liveuser 18917
									#函式說明:
226 liveuser 18918
									#加密 handshake 後要傳送的訊息
66 liveuser 18919
									#回傳結果:
18920
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18921
									#$result["error"],執行不正常結束的錯訊息陣列.
18922
									#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18923
									#$result["argu"],陣列,使用的參數.
18924
									#必填參數:
18925
									#$conf["text"],字串,要加密的訊息.
226 liveuser 18926
									$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18927
									#可省略參數:
18928
									#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18929
									#$conf["payloadIsBin"]="false";
18930
									#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18931
									#$conf["ping"]="false";
18932
									#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18933
									#$conf["pong"]="false";
18934
									#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18935
									#$conf["frames"]=array();
18936
									#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18937
									#$conf["mask"]="false";
18938
									#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18939
									#$conf["debug"]="false";
18940
									#參考資料:
18941
									#無.
18942
									#備註:
18943
									#目前$conf["text"]長度超過125會出錯.
18944
									$talkback=webSock::encode($conf["webSock::encode"]);
18945
									unset($conf["webSock::encode"]);
226 liveuser 18946
 
66 liveuser 18947
									#如果執行失敗
18948
									if($talkback["status"]==="false"){
226 liveuser 18949
 
66 liveuser 18950
										#印出結果
18951
										var_dump($talkback);
226 liveuser 18952
 
66 liveuser 18953
										#結束執行
18954
										exit;
226 liveuser 18955
 
66 liveuser 18956
										}#if end
226 liveuser 18957
 
66 liveuser 18958
									#debug
18959
									#var_dump(__LINE__,$talkback);
226 liveuser 18960
 
66 liveuser 18961
									}#if end
226 liveuser 18962
 
66 liveuser 18963
								}#if end
226 liveuser 18964
 
66 liveuser 18965
							}#if end
226 liveuser 18966
 
66 liveuser 18967
						#反之不為 web socket 訊息
18968
						else{
226 liveuser 18969
 
66 liveuser 18970
							#儲存成只有一個訊息
18971
							$talkback["content"][]=$talkback;
226 liveuser 18972
 
66 liveuser 18973
							}#else
226 liveuser 18974
 
66 liveuser 18975
						#針對每個訊息的分段
18976
						foreach($talkback["content"] as $msg){
226 liveuser 18977
 
66 liveuser 18978
							#回傳訊息
18979
							$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 18980
 
66 liveuser 18981
							#debug
18982
							#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 18983
 
66 liveuser 18984
							}#foreach end
226 liveuser 18985
 
66 liveuser 18986
						#讓對方可以跟自己對話
18987
						$connections[$targetKey]["talkTo"][]=$myId;
226 liveuser 18988
 
66 liveuser 18989
						#設置要給對方看的訊息
18990
						$talkback=$connections[$conIndex]["id"]." 與您展開對話";
226 liveuser 18991
 
66 liveuser 18992
						#json encode 設置要給對方看的訊息
18993
						$talkback=json_encode($talkback);
226 liveuser 18994
 
66 liveuser 18995
						#如果是 ws 模式
18996
						if($conf["wsMode"]==="true"){
226 liveuser 18997
 
66 liveuser 18998
							#如果已經 handshake 過
18999
							if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 19000
 
19001
								#如果要 unmask
66 liveuser 19002
								if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 19003
 
66 liveuser 19004
									#函式說明:
226 liveuser 19005
									#加密 handshake 後要傳送的訊息
66 liveuser 19006
									#回傳結果:
19007
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
19008
									#$result["error"],執行不正常結束的錯訊息陣列.
19009
									#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
19010
									#$result["argu"],陣列,使用的參數.
19011
									#必填參數:
19012
									#$conf["text"],字串,要加密的訊息.
226 liveuser 19013
									$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 19014
									#可省略參數:
19015
									#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
19016
									#$conf["payloadIsBin"]="false";
19017
									#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
19018
									#$conf["ping"]="false";
19019
									#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
19020
									#$conf["pong"]="false";
19021
									#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
19022
									#$conf["frames"]=array();
19023
									#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
19024
									#$conf["mask"]="false";
19025
									#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
19026
									#$conf["debug"]="false";
19027
									#參考資料:
19028
									#無.
19029
									#備註:
19030
									#目前$conf["text"]長度超過125會出錯.
19031
									$talkback=webSock::encode($conf["webSock::encode"]);
19032
									unset($conf["webSock::encode"]);
226 liveuser 19033
 
66 liveuser 19034
									#如果執行失敗
19035
									if($talkback["status"]==="false"){
226 liveuser 19036
 
66 liveuser 19037
										#印出結果
19038
										var_dump($talkback);
226 liveuser 19039
 
66 liveuser 19040
										#結束執行
19041
										exit;
226 liveuser 19042
 
66 liveuser 19043
										}#if end
226 liveuser 19044
 
66 liveuser 19045
									#debug
19046
									#var_dump(__LINE__,$talkback);
226 liveuser 19047
 
66 liveuser 19048
									}#if end
226 liveuser 19049
 
66 liveuser 19050
								}#if end
226 liveuser 19051
 
66 liveuser 19052
							}#if end
226 liveuser 19053
 
66 liveuser 19054
						#反之不為 web socket 訊息
19055
						else{
226 liveuser 19056
 
66 liveuser 19057
							#儲存成只有一個訊息
19058
							$talkback["content"][]=$talkback;
226 liveuser 19059
 
66 liveuser 19060
							}#else
226 liveuser 19061
 
66 liveuser 19062
						#針對每個訊息的分段
19063
						foreach($talkback["content"] as $msg){
226 liveuser 19064
 
66 liveuser 19065
							#給對方看的訊息
19066
							$socket_write=socket_write($connections[$targetKey]["connect"], $msg, strlen($msg));
226 liveuser 19067
 
66 liveuser 19068
							#debug
19069
							#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 19070
 
66 liveuser 19071
							}#foreach end
226 liveuser 19072
 
66 liveuser 19073
						#設置執行正常
19074
						$result["status"]="true";
226 liveuser 19075
 
66 liveuser 19076
						#回傳結果
19077
						return $result;
226 liveuser 19078
 
66 liveuser 19079
						}#if end
226 liveuser 19080
 
66 liveuser 19081
					}#if end
226 liveuser 19082
 
66 liveuser 19083
				}#if end
226 liveuser 19084
 
66 liveuser 19085
			}#if end
226 liveuser 19086
 
66 liveuser 19087
		#不是支援的訊息
19088
		$result["status"]="continue";
226 liveuser 19089
 
66 liveuser 19090
		#回傳結果
19091
		return $result;
226 liveuser 19092
 
66 liveuser 19093
		}#function basic end
226 liveuser 19094
 
66 liveuser 19095
	/*
19096
	#函式說明:
323 liveuser 19097
	#提供webSock::nativeSocketTcpIpServer使用talk2someoneOnce功能.
19098
	#回傳結果:
19099
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
19100
	#$result["error"],執行不正常結束的錯訊息陣列.
19101
	#$result["function"],當前函式的名稱.
19102
	#$result["argu"],陣列,使用的參數.
19103
	#必填參數:
19104
	#$conf["serverSock"],object,web socket server socket
19105
	$conf["serverSock"]=;
19106
	#$conf["clientSock"],$object,web socket client socket
19107
	$conf["clientSock"]=;
19108
	#$conf["clientInfo"],陣列,web socket client info.
19109
	$conf["clientInfo"]=array();
19110
	#$conf["clientIndex"],整數.web socket client index.
19111
	$conf["clientIndex"];
19112
	#$conf["allConn"],陣列,all web socket client info.
19113
	$conf["allConn"]=array();
19114
	#可省略參數:
19115
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
19116
	#$conf["wsMode"]="true";
19117
	#參考資料:
19118
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
19119
	#備註:
19120
	#無.
19121
	*/
19122
	public static function talk2someoneOnce(&$conf){
19123
 
19124
		#初始化要回傳的結果
19125
		$result=array();
19126
 
19127
		#取得當前執行的函數名稱
19128
		$result["function"]=__FUNCTION__;
19129
 
19130
		#涵式說明:
19131
		#判斷當前環境為web還是cmd
19132
		#回傳結果:
19133
		#$result,"web"或"cmd"
19134
		if(csInformation::getEnv()==="web"){
19135
 
19136
			#設置執行失敗
19137
			$result["status"]="false";
19138
 
19139
			#設置執行錯誤訊息
19140
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
19141
 
19142
			#回傳結果
19143
			return $result;
19144
 
19145
			}#if end
19146
 
19147
		#取得參數
19148
		$result["argu"]=$conf;
19149
 
19150
		#如果 $conf 不為陣列
19151
		if(gettype($conf)!="array"){
19152
 
19153
			#設置執行失敗
19154
			$result["status"]="false";
19155
 
19156
			#設置執行錯誤訊息
19157
			$result["error"][]="\$conf變數須為陣列形態";
19158
 
19159
			#如果傳入的參數為 null
19160
			if($conf==null){
19161
 
19162
				#設置執行錯誤訊息
19163
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
19164
 
19165
				}#if end
19166
 
19167
			#回傳結果
19168
			return $result;
19169
 
19170
			}#if end
19171
 
19172
		#檢查參數
19173
		#函式說明:
19174
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
19175
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
19176
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
19177
		#$result["function"],當前執行的函式名稱.
19178
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
19179
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
19180
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
19181
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
19182
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
19183
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
19184
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
19185
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
19186
		#必填寫的參數:
19187
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
19188
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
19189
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
19190
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","clientSock","serverSock","clientInfo","clientIndex","allConn");
19191
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
19192
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","object","object","array","integer","array");
19193
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
19194
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
19195
		#可以省略的參數:
19196
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
19197
		#$conf["canBeEmptyString"]="false";
19198
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
19199
		#$conf["canNotBeEmpty"]=array();
19200
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
19201
		#$conf["canBeEmpty"]=array();
19202
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
19203
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
19204
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
19205
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode");
19206
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
19207
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
19208
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
19209
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true");
19210
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
19211
		#$conf["arrayCountEqualCheck"][]=array();
19212
		#參考資料來源:
19213
		#array_keys=>http://php.net/manual/en/function.array-keys.php
19214
		#建議:
19215
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
19216
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
19217
		unset($conf["variableCheck::checkArguments"]);
19218
 
19219
		#如果檢查參數失敗
19220
		if($checkArguments["status"]==="false"){
19221
 
19222
			#設置執行失敗
19223
			$result["status"]="false";
19224
 
19225
			#設置執行錯誤訊息
19226
			$result["error"]=$checkArguments;
19227
 
19228
			#回傳結果
19229
			return $result;
19230
 
19231
			}#if end
19232
 
19233
		#如果檢查參數不通過
19234
		if($checkArguments["passed"]==="false"){
19235
 
19236
			#設置執行失敗
19237
			$result["status"]="false";
19238
 
19239
			#設置執行錯誤訊息
19240
			$result["error"]=$checkArguments;
19241
 
19242
			#回傳結果
19243
			return $result;
19244
 
19245
			}#if end
19246
 
19247
		#取得 server 的 socket
19248
		$serverSocket=$conf["serverSock"];
19249
 
19250
		#取得 client 的 socket
19251
		$clientSocket=$conf["clientSock"];
19252
 
19253
		#取得 client 的資訊
19254
		$clientInfo=$conf["clientInfo"];
19255
 
19256
		#取得 client 的索引
19257
		$conIndex=$conf["clientIndex"];
19258
 
19259
		#取得 all clients 的資訊
19260
		$connections=&$conf["allConn"];
19261
 
19262
		#如果有訊息要傳遞
19263
		if(count($connections[$conIndex]["msg"])>0){
19264
 
19265
			#取得要傳送的訊息
19266
			$msgPrepare2send=$connections[$conIndex]["msg"][count($connections[$conIndex]["msg"])-1];
19267
 
19268
			#取得給予client端識別訊息歸屬的id
19269
			$id=$msgPrepare2send["id"];
19270
 
19271
			#取得訊息接收者
19272
			$to=$msgPrepare2send["to"];
19273
 
324 liveuser 19274
			#預設的from
19275
			$from=$connections[$conIndex]["id"];
19276
 
19277
			#如果有要指定from
19278
			if(isset($msgPrepare2send["from"])){
19279
 
19280
				#更新from
19281
				$from=$msgPrepare2send["from"];
19282
 
19283
				}#if end
19284
 
323 liveuser 19285
			#取得要傳送的訊息內容
19286
			$msgPrepare2send=$msgPrepare2send["msg"];
19287
 
19288
			#預設沒有找到收訊息的人
19289
			$receiverNotFound=true;
19290
 
19291
			#依據每個連線資訊
19292
			foreach($connections as $index=>$connInfo){
19293
 
19294
				#如果不是要接收訊息的對象
19295
				if($connections[$index]["id"]!==$to){
19296
 
19297
					#跳過
19298
					continue;
19299
 
19300
					}#if end
19301
 
19302
				#執行到這邊代表需要接受訊息的目標存在
19303
				$receiverNotFound=true;
19304
 
19305
				#取得要接收訊息的msgSock
19306
				$receiveMsgSock=$connections[$index]["connect"];
19307
 
19308
				#初始化要傳遞訊息的陣列
19309
				$talkback=array();
19310
 
19311
				#設置訊息來自誰
324 liveuser 19312
				$talkback["from"]=$from;
323 liveuser 19313
 
19314
				#設置訊息內容
19315
				$talkback["msg"]=$msgPrepare2send;
19316
 
19317
				#設置給予用戶端識別的id
19318
				$talkback["id"]=$id;
19319
 
19320
				#json encode 要傳送的訊息
19321
				$talkback=json_encode($talkback);
19322
 
19323
				#如果是 ws 模式
19324
				if($conf["wsMode"]==="true"){
19325
 
19326
					#如果已經 handshake 過
19327
					if($connections[$conIndex]["handshaked"]==="true"){
19328
 
19329
						#如果要 unmask
19330
						if($connections[$conIndex]["unmask"]==="true"){
19331
 
19332
							#加密
19333
							$conf["webSock::encode"]["text"]=$talkback;
19334
							$talkback=webSock::encode($conf["webSock::encode"]);
19335
							unset($conf["webSock::encode"]);
19336
 
19337
							#如果執行異常
19338
							if($talkback["status"]==="false"){
19339
 
19340
								#設置執行錯誤訊息
19341
								$result["erorr"]=$talkback;
19342
 
19343
								#設置執行異常
19344
								$result["status"]="false";
19345
 
19346
								}#if end
19347
 
19348
							}#if end
19349
 
19350
						}#if end
19351
 
19352
					}#if end
19353
 
19354
				#反之不為 web socket 訊息
19355
				else{
19356
 
19357
					#儲存成只有一個訊息
19358
					$talkback["content"][]=$talkback;
19359
 
19360
					}#else
19361
 
19362
				#針對每個訊息的分段
19363
				foreach($talkback["content"] as $msg){
19364
 
19365
					#回傳訊息
19366
					$socket_write=socket_write($receiveMsgSock, $msg, strlen($msg));
19367
 
19368
					#如果傳遞訊息失敗
19369
					if($socket_write===false){
19370
 
19371
						#設置執行錯誤訊息
19372
						$result["erorr"]=socket_strerror(socket_last_error($receiveMsgSock));
19373
 
19374
						#設置執行異常
19375
						$result["status"]="false";
19376
 
19377
						}#if end
19378
 
19379
					#反之
19380
					else{
19381
 
19382
						#卸除傳遞成功的訊息
19383
						unset($connections[$conIndex]["msg"][count($connections[$conIndex]["msg"])-1]);
19384
 
19385
						#設置執行正常
19386
						$result["status"]="true";
19387
 
19388
						}#else end
19389
 
19390
					}#foreach end
19391
 
19392
				}#foreach end
19393
 
19394
			#如果收件人不存在
19395
			if($receiverNotFound===false){
19396
 
19397
				#收件人不存在先跳過
19398
				$result["status"]="continue";
19399
 
19400
				}#if end
19401
 
19402
			}#if end
19403
 
19404
		#反之沒有訊息要傳遞
19405
		else{
19406
 
19407
			#不是支援的訊息
19408
			$result["status"]="continue";
19409
 
19410
			}#else end
19411
 
19412
		#回傳結果
19413
		return $result;
19414
 
19415
		}#function talk2someoneOnce end
19416
 
19417
	/*
19418
	#函式說明:
19419
	#提供webSock::nativeSocketTcpIpServer使用talk2everyoneOnce功能.
19420
	#回傳結果:
19421
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
19422
	#$result["error"],執行不正常結束的錯訊息陣列.
19423
	#$result["function"],當前函式的名稱.
19424
	#$result["argu"],陣列,使用的參數.
19425
	#必填參數:
19426
	#$conf["data"],message reveiced.
19427
	$conf["data"]="";
19428
	#$conf["serverSock"],object,web socket server socket
19429
	$conf["serverSock"]=$object;
19430
	#$conf["clientSock"],$object,web socket client socket
19431
	$conf["clientSock"]=$object;
19432
	#$conf["clientInfo"],陣列,web socket client info.
19433
	$conf["clientInfo"]=array();
19434
	#$conf["clientIndex"],整數.web socket client index.
19435
	$conf["clientIndex"];
19436
	#$conf["allConn"],陣列,all web socket client info.
19437
	$conf["allConn"]=array();
19438
	#可省略參數:
19439
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
19440
	#$conf["wsMode"]="true";
19441
	#參考資料:
19442
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
19443
	#備註:
19444
	#無.
19445
	*/
19446
	public static function talk2everyoneOnce(&$conf){
19447
 
19448
		#初始化要回傳的結果
19449
		$result=array();
19450
 
19451
		#取得當前執行的函數名稱
19452
		$result["function"]=__FUNCTION__;
19453
 
19454
		#涵式說明:
19455
		#判斷當前環境為web還是cmd
19456
		#回傳結果:
19457
		#$result,"web"或"cmd"
19458
		if(csInformation::getEnv()==="web"){
19459
 
19460
			#設置執行失敗
19461
			$result["status"]="false";
19462
 
19463
			#設置執行錯誤訊息
19464
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
19465
 
19466
			#回傳結果
19467
			return $result;
19468
 
19469
			}#if end
19470
 
19471
		#取得參數
19472
		$result["argu"]=$conf;
19473
 
19474
		#如果 $conf 不為陣列
19475
		if(gettype($conf)!="array"){
19476
 
19477
			#設置執行失敗
19478
			$result["status"]="false";
19479
 
19480
			#設置執行錯誤訊息
19481
			$result["error"][]="\$conf變數須為陣列形態";
19482
 
19483
			#如果傳入的參數為 null
19484
			if($conf==null){
19485
 
19486
				#設置執行錯誤訊息
19487
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
19488
 
19489
				}#if end
19490
 
19491
			#回傳結果
19492
			return $result;
19493
 
19494
			}#if end
19495
 
19496
		#檢查參數
19497
		#函式說明:
19498
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
19499
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
19500
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
19501
		#$result["function"],當前執行的函式名稱.
19502
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
19503
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
19504
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
19505
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
19506
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
19507
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
19508
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
19509
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
19510
		#必填寫的參數:
19511
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
19512
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
19513
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
19514
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","clientSock","serverSock","clientInfo","clientIndex","allConn");
19515
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
19516
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","object","object","array","integer","array");
19517
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
19518
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
19519
		#可以省略的參數:
19520
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
19521
		#$conf["canBeEmptyString"]="false";
19522
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
19523
		#$conf["canNotBeEmpty"]=array();
19524
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
19525
		#$conf["canBeEmpty"]=array();
19526
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
19527
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
19528
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
19529
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode");
19530
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
19531
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string");
19532
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
19533
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true");
19534
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
19535
		#$conf["arrayCountEqualCheck"][]=array();
19536
		#參考資料來源:
19537
		#array_keys=>http://php.net/manual/en/function.array-keys.php
19538
		#建議:
19539
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
19540
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
19541
		unset($conf["variableCheck::checkArguments"]);
19542
 
19543
		#如果檢查參數失敗
19544
		if($checkArguments["status"]==="false"){
19545
 
19546
			#設置執行失敗
19547
			$result["status"]="false";
19548
 
19549
			#設置執行錯誤訊息
19550
			$result["error"]=$checkArguments;
19551
 
19552
			#回傳結果
19553
			return $result;
19554
 
19555
			}#if end
19556
 
19557
		#如果檢查參數不通過
19558
		if($checkArguments["passed"]==="false"){
19559
 
19560
			#設置執行失敗
19561
			$result["status"]="false";
19562
 
19563
			#設置執行錯誤訊息
19564
			$result["error"]=$checkArguments;
19565
 
19566
			#回傳結果
19567
			return $result;
19568
 
19569
			}#if end
19570
 
19571
		#取得 server 的 socket
19572
		$serverSocket=$conf["serverSock"];
19573
 
19574
		#取得 client 的 socket
19575
		$clientSocket=$conf["clientSock"];
19576
 
19577
		#取得 client 的資訊
19578
		$clientInfo=$conf["clientInfo"];
19579
 
19580
		#取得 client 的索引
19581
		$conIndex=$conf["clientIndex"];
19582
 
19583
		#取得 all clients 的資訊
19584
		$connections=&$conf["allConn"];
19585
 
19586
		#如果有廣播訊息要傳遞
19587
		if(count($connections[$conIndex]["broadMsg"])>0){
19588
 
19589
			#取得要廣播的訊息
19590
			$msgPrepare2send=$connections[$conIndex]["broadMsg"][count($connections[$conIndex]["broadMsg"])-1];
19591
 
19592
			#依據每個連線資訊
19593
			foreach($connections as $index=>$broadcast){
19594
 
19595
				#如果是自己
19596
				if($connections[$conIndex]["id"]===$broadcast["id"]){
19597
 
19598
					#跳過
19599
					continue;
19600
 
19601
					}#if end
19602
 
19603
				#儲存要接收廣播訊息的id
19604
				$broadcastId[$index]=$broadcast["id"];
19605
 
19606
				}#foreach end
19607
 
19608
			#針對每個要接收廣播的 id
19609
			foreach($broadcastId as $index=>$id){
19610
 
19611
				#取得要接收訊息的msgSock
19612
				$receiveMsgSock=$connections[$index]["connect"];
19613
 
19614
				#初始化要傳遞訊息的陣列
19615
				$talkback=array();
19616
 
19617
				#設置訊息來自誰
19618
				$talkback["from"]=$connections[$conIndex]["id"];
19619
 
19620
				#設置訊息內容
19621
				$talkback["msg"]=$msgPrepare2send;
19622
 
19623
				#json encode 要傳送的訊息
19624
				$talkback=json_encode($talkback);
19625
 
19626
				#如果是 ws 模式
19627
				if($conf["wsMode"]==="true"){
19628
 
19629
					#如果已經 handshake 過
19630
					if($connections[$conIndex]["handshaked"]==="true"){
19631
 
19632
						#如果要 unmask
19633
						if($connections[$conIndex]["unmask"]==="true"){
19634
 
19635
							#加密
19636
							$conf["webSock::encode"]["text"]=$talkback;
19637
							$talkback=webSock::encode($conf["webSock::encode"]);
19638
							unset($conf["webSock::encode"]);
19639
 
19640
							#如果執行異常
19641
							if($talkback["status"]==="false"){
19642
 
19643
								#設置執行錯誤訊息
19644
								$result["erorr"]=$talkback;
19645
 
19646
								#設置執行異常
19647
								$result["status"]="false";
19648
 
19649
								}#if end
19650
 
19651
							}#if end
19652
 
19653
						}#if end
19654
 
19655
					}#if end
19656
 
19657
				#反之不為 web socket 訊息
19658
				else{
19659
 
19660
					#儲存成只有一個訊息
19661
					$talkback["content"][]=$talkback;
19662
 
19663
					}#else
19664
 
19665
				#針對每個訊息的分段
19666
				foreach($talkback["content"] as $msg){
19667
 
19668
					#回傳訊息
19669
					$socket_write=socket_write($receiveMsgSock, $msg, strlen($msg));
19670
 
19671
					#如果傳遞訊息失敗
19672
					if($socket_write===false){
19673
 
19674
						#debug
19675
						var_dump(__LINE__,$receiveMsgSock,socket_strerror(socket_last_error($receiveMsgSock)));
19676
 
19677
						}#if end
19678
 
19679
					}#foreach end
19680
 
19681
				}#foreach end
19682
 
19683
			#卸除廣播好的訊息
19684
			unset($connections[$conIndex]["broadMsg"][count($connections[$conIndex]["broadMsg"])-1]);
19685
 
19686
			}#if end
19687
 
19688
		#反之沒有訊息要傳遞
19689
		else{
19690
 
19691
			#不是支援的訊息
19692
			$result["status"]="continue";
19693
 
19694
			}#else end
19695
 
19696
		#回傳結果
19697
		return $result;
19698
 
19699
		}#function talk2everyoneOnce end
19700
 
19701
	/*
19702
	#函式說明:
66 liveuser 19703
	#提供webSock::nativeSocketTcpIpServer使用系統功能(system).
19704
	#回傳結果:
19705
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
19706
	#$result["error"],執行不正常結束的錯訊息陣列.
19707
	#$result["argu"],陣列,使用的參數.
19708
	#必填參數:
19709
	#$conf["data"],字串,收到的bin2hex編碼後再gpg加密過後的json格式資料,必填的key有"randomStr","username","password".
19710
	$conf["data"]="";
19711
	#$conf["serverSock"],resource,web socket server socket
19712
	$conf["serverSock"]=$resource;
19713
	#$conf["clientSock"],$resource,web socket client socket
19714
	$conf["clientSock"]=$resource;
19715
	#$conf["clientInfo"],陣列,web socket client info.
19716
	$conf["clientInfo"]=array();
19717
	#$conf["clientIndex"],整數.web socket client index.
19718
	$conf["clientIndex"];
19719
	#$conf["allConn"],陣列,all web socket client info.
19720
	$conf["allConn"]=array();
19721
	#可省略參數:
19722
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
19723
	#$conf["wsMode"]="true";
19724
	#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
19725
	#$conf["gpgId"]=gnupgId;
19726
	#參考資料:
19727
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
19728
	#備註:
19729
	#收到用戶的"shutdown"訊息,會重新啟動webSocket server.
19730
	#無.
19731
	*/
19732
	public static function system(&$conf){
226 liveuser 19733
 
66 liveuser 19734
		#初始化要回傳的結果
19735
		$result=array();
19736
 
19737
		#取得當前執行的函數名稱
19738
		$result["function"]=__FUNCTION__;
19739
 
19740
		#涵式說明:
19741
		#判斷當前環境為web還是cmd
19742
		#回傳結果:
19743
		#$result,"web"或"cmd"
19744
		if(csInformation::getEnv()==="web"){
226 liveuser 19745
 
66 liveuser 19746
			#設置執行失敗
19747
			$result["status"]="false";
226 liveuser 19748
 
66 liveuser 19749
			#設置執行錯誤訊息
19750
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 19751
 
66 liveuser 19752
			#回傳結果
19753
			return $result;
226 liveuser 19754
 
66 liveuser 19755
			}#if end
19756
 
19757
		#取得參數
19758
		$result["argu"]=$conf;
19759
 
19760
		#如果 $conf 不為陣列
19761
		if(gettype($conf)!="array"){
226 liveuser 19762
 
66 liveuser 19763
			#設置執行失敗
19764
			$result["status"]="false";
226 liveuser 19765
 
66 liveuser 19766
			#設置執行錯誤訊息
19767
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 19768
 
66 liveuser 19769
			#如果傳入的參數為 null
19770
			if($conf==null){
226 liveuser 19771
 
66 liveuser 19772
				#設置執行錯誤訊息
19773
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 19774
 
66 liveuser 19775
				}#if end
19776
 
19777
			#回傳結果
19778
			return $result;
226 liveuser 19779
 
66 liveuser 19780
			}#if end
226 liveuser 19781
 
66 liveuser 19782
		#檢查參數
19783
		#函式說明:
19784
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
19785
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
19786
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
19787
		#$result["function"],當前執行的函式名稱.
19788
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
19789
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
19790
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
19791
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
19792
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
19793
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
19794
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
19795
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
19796
		#必填寫的參數:
19797
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
19798
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
19799
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
19800
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientInfo","clientIndex","allConn");
19801
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
19802
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","array","string","array");
19803
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
19804
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
19805
		#可以省略的參數:
19806
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
19807
		#$conf["canBeEmptyString"]="false";
19808
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
19809
		#$conf["canNotBeEmpty"]=array();
19810
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
19811
		#$conf["canBeEmpty"]=array();
19812
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
19813
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
19814
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
19815
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode","gpgId");
226 liveuser 19816
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 19817
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
19818
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
19819
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",gnupgId);
19820
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
19821
		#$conf["arrayCountEqualCheck"][]=array();
19822
		#參考資料來源:
19823
		#array_keys=>http://php.net/manual/en/function.array-keys.php
19824
		#建議:
19825
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
19826
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
19827
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 19828
 
66 liveuser 19829
		#如果檢查參數失敗
19830
		if($checkArguments["status"]==="false"){
226 liveuser 19831
 
66 liveuser 19832
			#設置執行失敗
19833
			$result["status"]="false";
226 liveuser 19834
 
66 liveuser 19835
			#設置執行錯誤訊息
19836
			$result["error"]=$checkArguments;
226 liveuser 19837
 
66 liveuser 19838
			#回傳結果
19839
			return $result;
226 liveuser 19840
 
66 liveuser 19841
			}#if end
226 liveuser 19842
 
66 liveuser 19843
		#如果檢查參數不通過
19844
		if($checkArguments["passed"]==="false"){
226 liveuser 19845
 
66 liveuser 19846
			#設置執行失敗
19847
			$result["status"]="false";
226 liveuser 19848
 
66 liveuser 19849
			#設置執行錯誤訊息
19850
			$result["error"]=$checkArguments;
226 liveuser 19851
 
66 liveuser 19852
			#回傳結果
19853
			return $result;
226 liveuser 19854
 
66 liveuser 19855
			}#if end
19856
 
19857
		#取得收到的訊息
19858
		$receivedData=$conf["data"];
226 liveuser 19859
 
66 liveuser 19860
		#取得 server 的 socket
19861
		$serverSocket=$conf["serverSock"];
226 liveuser 19862
 
66 liveuser 19863
		#取得 client 的 socket
19864
		$clientSocket=$conf["clientSock"];
226 liveuser 19865
 
66 liveuser 19866
		#取得 client 的資訊
19867
		$clientInfo=$conf["clientInfo"];
226 liveuser 19868
 
66 liveuser 19869
		#取得 client 的索引
19870
		$clientIndex=$conf["clientIndex"];
226 liveuser 19871
 
66 liveuser 19872
		#取得 all clients 的資訊
19873
		$allConn=&$conf["allConn"];
226 liveuser 19874
 
66 liveuser 19875
		#hex2bin
19876
		#函式說明:
19877
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
19878
		#回傳結果:
226 liveuser 19879
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 19880
		#$result["function"],當前執行的函數名稱.
19881
		#$result["content"],加密後的結果.
19882
		#$result["error"],錯誤訊息陣列.
19883
		#$result["argu"],使用的參數.
19884
		#必填參數:
19885
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
19886
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
19887
		#$conf["enCodeType"],"字串",加密的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin",7種,"sha1"較耗時,"md5"較快,"p_hash"適用於密碼加密,"aes256"是對稱式加解密,"qbpwcf"是透過urlencode、json_encode、base64_encode的結果,"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin".
19888
		$conf["authenticate::enCodeStr"]["enCodeType"]="hex2bin";
19889
		#可省略參數:
19890
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
19891
		#$conf["sha1Raw"]="false";
19892
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
19893
		#$conf["p_hash"]="";
19894
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
19895
		#$conf["keyForAes256"]="";
19896
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
19897
		#$conf["aes256Encode"]="";
19898
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
19899
		#$conf["qbpwcfDecode"]="false";
19900
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
19901
		#$conf["gpgDecrypt"]="false";
19902
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
19903
		#$conf["gpgId"]="";
19904
		#參考資料:
19905
		#sha1=>http://php.net/manual/en/function.sha1.php
19906
		#md5=>http://php.net/manual/en/function.md5.php
19907
		#password_hash=>http://php.net/manual/en/function.password-hash.php
19908
		#password_verify=>http://php.net/manual/en/function.password-verify.php
19909
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
19910
		#備註:
19911
		#無.
19912
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
19913
		unset($conf["authenticate::enCodeStr"]);
19914
 
19915
		#如果執行失敗
19916
		if($enCodeStr["status"]==="false"){
19917
 
19918
			#設置執行異常
19919
			$result["status"]="false";
19920
 
19921
			#設置執行錯誤
19922
			$result["error"]=$enCodeStr;
19923
 
19924
			#回傳結果
19925
			return $result;
19926
 
19927
			}#if end
19928
 
19929
		#取得hex2bin後的字串
19930
		$receivedData=$enCodeStr["content"];
226 liveuser 19931
 
66 liveuser 19932
		#gpg decrypt
19933
		#函式說明:
19934
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
19935
		#回傳結果:
226 liveuser 19936
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 19937
		#$result["function"],當前執行的函數名稱.
19938
		#$result["content"],加密後的結果.
19939
		#$result["error"],錯誤訊息陣列.
19940
		#$result["argu"],使用的參數.
19941
		#必填參數:
19942
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
19943
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
19944
		#$conf["enCodeType"],"字串",加密的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin",7種,"sha1"較耗時,"md5"較快,"p_hash"適用於密碼加密,"aes256"是對稱式加解密,"qbpwcf"是透過urlencode、json_encode、base64_encode的結果,"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin".
19945
		$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
19946
		#可省略參數:
19947
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
19948
		#$conf["sha1Raw"]="false";
19949
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
19950
		#$conf["p_hash"]="";
19951
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
19952
		#$conf["keyForAes256"]="";
19953
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
19954
		#$conf["aes256Encode"]="";
19955
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
19956
		#$conf["qbpwcfDecode"]="false";
19957
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
19958
		$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
19959
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
19960
		$conf["authenticate::enCodeStr"]["gpgId"]=$conf["gpgId"];
19961
		#參考資料:
19962
		#sha1=>http://php.net/manual/en/function.sha1.php
19963
		#md5=>http://php.net/manual/en/function.md5.php
19964
		#password_hash=>http://php.net/manual/en/function.password-hash.php
19965
		#password_verify=>http://php.net/manual/en/function.password-verify.php
19966
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
19967
		#備註:
19968
		#無.
19969
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
19970
		unset($conf["authenticate::enCodeStr"]);
19971
 
19972
		#如果執行失敗
19973
		if($enCodeStr["status"]==="false"){
19974
 
19975
			#設置執行異常
19976
			$result["status"]="false";
19977
 
19978
			#設置執行錯誤
19979
			$result["error"]=$enCodeStr;
19980
 
19981
			#回傳結果
19982
			return $result;
19983
 
19984
			}#if end
19985
 
19986
		#取得解密後的字串
19987
		$receivedData=$enCodeStr["content"];
226 liveuser 19988
 
66 liveuser 19989
		#json_decode
19990
		$receivedData=json_decode($receivedData);
226 liveuser 19991
 
66 liveuser 19992
		#如果收到 "shutdown"
19993
		if($receivedData==="shutdown"){
226 liveuser 19994
 
66 liveuser 19995
			#設置要回傳的訊息
19996
			$talkback="Server 即將關閉";
226 liveuser 19997
 
66 liveuser 19998
			#json encode 要回傳的訊息
19999
			$talkback=json_encode($talkback);
226 liveuser 20000
 
66 liveuser 20001
			#如果是 ws 模式
20002
			if($conf["wsMode"]==="true"){
226 liveuser 20003
 
66 liveuser 20004
				#如果已經 handshake 過
20005
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 20006
 
20007
					#如果要 unmask
66 liveuser 20008
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 20009
 
66 liveuser 20010
						#函式說明:
226 liveuser 20011
						#加密 handshake 後要傳送的訊息
66 liveuser 20012
						#回傳結果:
20013
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
20014
						#$result["error"],執行不正常結束的錯訊息陣列.
20015
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
20016
						#$result["argu"],陣列,使用的參數.
20017
						#必填參數:
20018
						#$conf["text"],字串,要加密的訊息.
226 liveuser 20019
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 20020
						#可省略參數:
20021
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
20022
						#$conf["payloadIsBin"]="false";
20023
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
20024
						#$conf["ping"]="false";
20025
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
20026
						#$conf["pong"]="false";
20027
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
20028
						#$conf["frames"]=array();
20029
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
20030
						#$conf["mask"]="false";
20031
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
20032
						#$conf["debug"]="false";
20033
						#參考資料:
20034
						#無.
20035
						#備註:
20036
						#無.
20037
						$talkback=webSock::encode($conf["webSock::encode"]);
20038
						unset($conf["webSock::encode"]);
226 liveuser 20039
 
66 liveuser 20040
						#如果執行失敗
20041
						if($talkback["status"]==="false"){
226 liveuser 20042
 
66 liveuser 20043
							#印出結果
20044
							var_dump($talkback);
226 liveuser 20045
 
66 liveuser 20046
							#結束執行
20047
							exit;
226 liveuser 20048
 
66 liveuser 20049
							}#if end
226 liveuser 20050
 
66 liveuser 20051
						#debug
20052
						#var_dump(__LINE__,$talkback);
226 liveuser 20053
 
66 liveuser 20054
						}#if end
226 liveuser 20055
 
66 liveuser 20056
					}#if end
226 liveuser 20057
 
66 liveuser 20058
				}#if end
226 liveuser 20059
 
66 liveuser 20060
			#反之不為 web socket 訊息
20061
			else{
226 liveuser 20062
 
66 liveuser 20063
				#儲存成只有一個訊息
20064
				$talkback["content"][]=$talkback;
226 liveuser 20065
 
66 liveuser 20066
				}#else
226 liveuser 20067
 
66 liveuser 20068
			#針對每個訊息的分段
20069
			foreach($talkback["content"] as $msg){
226 liveuser 20070
 
66 liveuser 20071
				#回傳訊息
20072
				$socket_write=socket_write($con["connect"], $msg, strlen($msg));
226 liveuser 20073
 
66 liveuser 20074
				#debug
20075
				#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 20076
 
66 liveuser 20077
				}#foreach end
226 liveuser 20078
 
66 liveuser 20079
			#關閉用戶的連線
20080
			socket_close($con["connect"]);
226 liveuser 20081
 
66 liveuser 20082
			}#if end
226 liveuser 20083
 
66 liveuser 20084
		#關閉 server socket
20085
		socket_close($serverSocket);
226 liveuser 20086
 
66 liveuser 20087
		#設置執行正常
20088
		$result["status"]="true";
226 liveuser 20089
 
66 liveuser 20090
		#回傳結果
20091
		return $result;
226 liveuser 20092
 
66 liveuser 20093
		}#function system end
226 liveuser 20094
 
66 liveuser 20095
	/*
20096
	#函式說明:
323 liveuser 20097
	#提供webSock::nativeSocketTcpIpServer使用noAuth功能.
66 liveuser 20098
	#回傳結果:
20099
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
20100
	#$result["error"],執行不正常結束的錯訊息陣列.
20101
	#$result["argu"],陣列,使用的參數.
20102
	#必填參數:
20103
	#$conf["data"],字串,收到的bin2hex編碼後再gpg加密過後的json格式資料.
20104
	$conf["data"]="";
20105
	#$conf["serverSock"],resource,web socket server socket
20106
	$conf["serverSock"]=$resource;
20107
	#$conf["clientSock"],$resource,web socket client socket
20108
	$conf["clientSock"]=$resource;
20109
	#$conf["clientInfo"],陣列,web socket client info.
20110
	$conf["clientInfo"]=array();
20111
	#$conf["clientIndex"],整數.web socket client index.
20112
	$conf["clientIndex"];
20113
	#$conf["allConn"],陣列,all web socket client info.
20114
	$conf["allConn"]=array();
20115
	#可省略參數:
20116
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
20117
	#$conf["wsMode"]="true";
20118
	#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
20119
	#$conf["gpgId"]=gnupgId;
20120
	#參考資料:
20121
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
20122
	#備註:
20123
	#收到用戶的"quit"訊息,會結束與用戶的連線.
323 liveuser 20124
	#目前不適用於webSock::nativeSocketTcpIpServer 
66 liveuser 20125
	*/
20126
	public static function noAuth(&$conf){
226 liveuser 20127
 
66 liveuser 20128
		#初始化要回傳的結果
20129
		$result=array();
20130
 
20131
		#取得當前執行的函數名稱
20132
		$result["function"]=__FUNCTION__;
20133
 
20134
		#涵式說明:
20135
		#判斷當前環境為web還是cmd
20136
		#回傳結果:
20137
		#$result,"web"或"cmd"
20138
		if(csInformation::getEnv()==="web"){
226 liveuser 20139
 
66 liveuser 20140
			#設置執行失敗
20141
			$result["status"]="false";
226 liveuser 20142
 
66 liveuser 20143
			#設置執行錯誤訊息
20144
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 20145
 
66 liveuser 20146
			#回傳結果
20147
			return $result;
226 liveuser 20148
 
66 liveuser 20149
			}#if end
20150
 
20151
		#取得參數
20152
		$result["argu"]=$conf;
20153
 
20154
		#如果 $conf 不為陣列
20155
		if(gettype($conf)!="array"){
226 liveuser 20156
 
66 liveuser 20157
			#設置執行失敗
20158
			$result["status"]="false";
226 liveuser 20159
 
66 liveuser 20160
			#設置執行錯誤訊息
20161
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 20162
 
66 liveuser 20163
			#如果傳入的參數為 null
20164
			if($conf==null){
226 liveuser 20165
 
66 liveuser 20166
				#設置執行錯誤訊息
20167
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 20168
 
66 liveuser 20169
				}#if end
20170
 
20171
			#回傳結果
20172
			return $result;
226 liveuser 20173
 
66 liveuser 20174
			}#if end
226 liveuser 20175
 
66 liveuser 20176
		#檢查參數
20177
		#函式說明:
20178
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
20179
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
20180
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
20181
		#$result["function"],當前執行的函式名稱.
20182
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
20183
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
20184
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
20185
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
20186
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
20187
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
20188
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
20189
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
20190
		#必填寫的參數:
20191
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
20192
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
20193
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
20194
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientInfo","clientIndex","allConn");
20195
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
20196
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","array","string","array");
20197
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
20198
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
20199
		#可以省略的參數:
20200
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
20201
		#$conf["canBeEmptyString"]="false";
20202
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
20203
		#$conf["canNotBeEmpty"]=array();
20204
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
20205
		#$conf["canBeEmpty"]=array();
20206
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
20207
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
20208
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
20209
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode","gpgId");
226 liveuser 20210
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 20211
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
20212
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
20213
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",gnupgId);
20214
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
20215
		#$conf["arrayCountEqualCheck"][]=array();
20216
		#參考資料來源:
20217
		#array_keys=>http://php.net/manual/en/function.array-keys.php
20218
		#建議:
20219
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
20220
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
20221
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 20222
 
66 liveuser 20223
		#如果檢查參數失敗
20224
		if($checkArguments["status"]==="false"){
226 liveuser 20225
 
66 liveuser 20226
			#設置執行失敗
20227
			$result["status"]="false";
226 liveuser 20228
 
66 liveuser 20229
			#設置執行錯誤訊息
20230
			$result["error"]=$checkArguments;
226 liveuser 20231
 
66 liveuser 20232
			#回傳結果
20233
			return $result;
226 liveuser 20234
 
66 liveuser 20235
			}#if end
226 liveuser 20236
 
66 liveuser 20237
		#如果檢查參數不通過
20238
		if($checkArguments["passed"]==="false"){
226 liveuser 20239
 
66 liveuser 20240
			#設置執行失敗
20241
			$result["status"]="false";
226 liveuser 20242
 
66 liveuser 20243
			#設置執行錯誤訊息
20244
			$result["error"]=$checkArguments;
226 liveuser 20245
 
66 liveuser 20246
			#回傳結果
20247
			return $result;
226 liveuser 20248
 
66 liveuser 20249
			}#if end
20250
 
20251
		#取得收到的訊息
20252
		$receivedData=$conf["data"];
226 liveuser 20253
 
66 liveuser 20254
		#取得 server 的 socket
20255
		$serverSocket=$conf["serverSock"];
226 liveuser 20256
 
66 liveuser 20257
		#取得 client 的 socket
20258
		$clientSocket=$conf["clientSock"];
226 liveuser 20259
 
66 liveuser 20260
		#取得 client 的資訊
20261
		$clientInfo=$conf["clientInfo"];
226 liveuser 20262
 
66 liveuser 20263
		#取得 client 的索引
20264
		$clientIndex=$conf["clientIndex"];
226 liveuser 20265
 
66 liveuser 20266
		#取得 all clients 的資訊
20267
		$allConn=&$conf["allConn"];
226 liveuser 20268
 
66 liveuser 20269
		#hex2bin
20270
		#函式說明:
20271
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
20272
		#回傳結果:
226 liveuser 20273
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 20274
		#$result["function"],當前執行的函數名稱.
20275
		#$result["content"],加密後的結果.
20276
		#$result["error"],錯誤訊息陣列.
20277
		#$result["argu"],使用的參數.
20278
		#必填參數:
20279
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
20280
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
20281
		#$conf["enCodeType"],"字串",加密的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin",7種,"sha1"較耗時,"md5"較快,"p_hash"適用於密碼加密,"aes256"是對稱式加解密,"qbpwcf"是透過urlencode、json_encode、base64_encode的結果,"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin".
20282
		$conf["authenticate::enCodeStr"]["enCodeType"]="hex2bin";
20283
		#可省略參數:
20284
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
20285
		#$conf["sha1Raw"]="false";
20286
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
20287
		#$conf["p_hash"]="";
20288
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
20289
		#$conf["keyForAes256"]="";
20290
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
20291
		#$conf["aes256Encode"]="";
20292
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
20293
		#$conf["qbpwcfDecode"]="false";
20294
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
20295
		#$conf["gpgDecrypt"]="false";
20296
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
20297
		#$conf["gpgId"]="";
20298
		#參考資料:
20299
		#sha1=>http://php.net/manual/en/function.sha1.php
20300
		#md5=>http://php.net/manual/en/function.md5.php
20301
		#password_hash=>http://php.net/manual/en/function.password-hash.php
20302
		#password_verify=>http://php.net/manual/en/function.password-verify.php
20303
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
20304
		#備註:
20305
		#無.
20306
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
20307
		unset($conf["authenticate::enCodeStr"]);
20308
 
20309
		#如果執行失敗
20310
		if($enCodeStr["status"]==="false"){
20311
 
20312
			#設置執行異常
20313
			$result["status"]="false";
20314
 
20315
			#設置執行錯誤
20316
			$result["error"]=$enCodeStr;
20317
 
20318
			#回傳結果
20319
			return $result;
20320
 
20321
			}#if end
20322
 
20323
		#取得hex2bin後的字串
20324
		$receivedData=$enCodeStr["content"];
226 liveuser 20325
 
66 liveuser 20326
		#gpg decrypt
20327
		#函式說明:
20328
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
20329
		#回傳結果:
226 liveuser 20330
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 20331
		#$result["function"],當前執行的函數名稱.
20332
		#$result["content"],加密後的結果.
20333
		#$result["error"],錯誤訊息陣列.
20334
		#$result["argu"],使用的參數.
20335
		#必填參數:
20336
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
20337
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
20338
		#$conf["enCodeType"],"字串",加密的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin",7種,"sha1"較耗時,"md5"較快,"p_hash"適用於密碼加密,"aes256"是對稱式加解密,"qbpwcf"是透過urlencode、json_encode、base64_encode的結果,"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin".
20339
		$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
20340
		#可省略參數:
20341
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
20342
		#$conf["sha1Raw"]="false";
20343
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
20344
		#$conf["p_hash"]="";
20345
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
20346
		#$conf["keyForAes256"]="";
20347
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
20348
		#$conf["aes256Encode"]="";
20349
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
20350
		#$conf["qbpwcfDecode"]="false";
20351
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
20352
		$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
20353
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
20354
		$conf["authenticate::enCodeStr"]["gpgId"]=$conf["gpgId"];
20355
		#參考資料:
20356
		#sha1=>http://php.net/manual/en/function.sha1.php
20357
		#md5=>http://php.net/manual/en/function.md5.php
20358
		#password_hash=>http://php.net/manual/en/function.password-hash.php
20359
		#password_verify=>http://php.net/manual/en/function.password-verify.php
20360
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
20361
		#備註:
20362
		#無.
20363
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
20364
		unset($conf["authenticate::enCodeStr"]);
20365
 
20366
		#如果執行失敗
20367
		if($enCodeStr["status"]==="false"){
20368
 
20369
			#設置執行異常
20370
			$result["status"]="false";
20371
 
20372
			#設置執行錯誤
20373
			$result["error"]=$enCodeStr;
20374
 
20375
			#回傳結果
20376
			return $result;
20377
 
20378
			}#if end
20379
 
20380
		#取得解密後的字串
20381
		$receivedData=$enCodeStr["content"];
226 liveuser 20382
 
66 liveuser 20383
		#json_decode
20384
		$receivedData=json_decode($receivedData);
226 liveuser 20385
 
66 liveuser 20386
		#如果訊息內容為 "quit"
20387
		if($receivedData==="quit"){
226 liveuser 20388
 
66 liveuser 20389
			#設置要回傳的訊息
20390
			$talkback="結束與 server 的連線";
226 liveuser 20391
 
66 liveuser 20392
			#json encode 要回傳的訊息
20393
			$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 20394
 
66 liveuser 20395
			#如果是 ws 模式
20396
			if($conf["wsMode"]==="true"){
226 liveuser 20397
 
66 liveuser 20398
				#如果已經 handshake 過
20399
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 20400
 
20401
					#如果要 unmask
66 liveuser 20402
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 20403
 
66 liveuser 20404
						#函式說明:
226 liveuser 20405
						#加密 handshake 後要傳送的訊息
66 liveuser 20406
						#回傳結果:
20407
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
20408
						#$result["error"],執行不正常結束的錯訊息陣列.
20409
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
20410
						#$result["argu"],陣列,使用的參數.
20411
						#必填參數:
20412
						#$conf["text"],字串,要加密的訊息.
226 liveuser 20413
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 20414
						#可省略參數:
20415
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
20416
						#$conf["payloadIsBin"]="false";
20417
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
20418
						#$conf["ping"]="false";
20419
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
20420
						#$conf["pong"]="false";
20421
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
20422
						#$conf["frames"]=array();
20423
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
20424
						#$conf["mask"]="false";
20425
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
20426
						#$conf["debug"]="false";
20427
						#參考資料:
20428
						#無.
20429
						#備註:
20430
						#目前$conf["text"]長度超過125會出錯.
20431
						$talkback=webSock::encode($conf["webSock::encode"]);
20432
						unset($conf["webSock::encode"]);
226 liveuser 20433
 
66 liveuser 20434
						#如果執行失敗
20435
						if($talkback["status"]==="false"){
226 liveuser 20436
 
66 liveuser 20437
							#印出結果
20438
							var_dump($talkback);
226 liveuser 20439
 
66 liveuser 20440
							#結束執行
20441
							exit;
226 liveuser 20442
 
66 liveuser 20443
							}#if end
226 liveuser 20444
 
66 liveuser 20445
						#debug
20446
						#var_dump(__LINE__,$talkback);
226 liveuser 20447
 
66 liveuser 20448
						}#if end
226 liveuser 20449
 
66 liveuser 20450
					}#if end
226 liveuser 20451
 
66 liveuser 20452
				}#if end
226 liveuser 20453
 
66 liveuser 20454
			#反之不為 web socket 訊息
20455
			else{
226 liveuser 20456
 
66 liveuser 20457
				#儲存成只有一個訊息
20458
				$talkback["content"][]=$talkback;
226 liveuser 20459
 
66 liveuser 20460
				}#else
226 liveuser 20461
 
66 liveuser 20462
			#針對每個訊息的分段
20463
			foreach($talkback["content"] as $msg){
226 liveuser 20464
 
66 liveuser 20465
				#回傳訊息
20466
				$socket_write=socket_write($con["connect"], $msg, strlen($msg));
226 liveuser 20467
 
66 liveuser 20468
				#debug
20469
				#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 20470
 
66 liveuser 20471
				}#foreach end
226 liveuser 20472
 
66 liveuser 20473
			#關閉被 client 的連線
20474
			socket_close($con["connect"]);
226 liveuser 20475
 
66 liveuser 20476
			#清理連線的陣列
20477
			unset($connections[$conIndex]);
226 liveuser 20478
 
66 liveuser 20479
			#設置執行正常
20480
			$result["status"]="true";
226 liveuser 20481
 
66 liveuser 20482
			#回傳結果
20483
			return $result;
226 liveuser 20484
 
66 liveuser 20485
			}#if end
226 liveuser 20486
 
66 liveuser 20487
		}#function noAuth end
226 liveuser 20488
 
66 liveuser 20489
	/*
20490
	#函式說明:
20491
	#依照參數來執行對應的函式.
20492
	#回傳結果:
226 liveuser 20493
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 20494
	#$result["function"],當前執行的函數名稱.
20495
	#$result["content"],加密後的結果.
20496
	#$result["error"],錯誤訊息陣列.
20497
	#$result["argu"],使用的參數.
20498
	#必填參數:
20499
	#$conf["data"],字串,收到bin2hex編碼後再gpg加密後的資料.
20500
	$conf["data"]="";
20501
	#$conf["serverSock"],socket,代表web socket server的socket.
20502
	$conf["serverSock"]=;
20503
	#$conf["clientSock"],socket,代表web socket client的socket.
20504
	#$conf["clientInfo"],陣列,用戶端的資訊.
20505
	$conf["clientInfo"]=array();
20506
	#$conf["clientIndex"],字串,代表client於allConn中的索引.
20507
	$conf["clientIndex"]="";
20508
	#$conf["allConn"],陣列,所有連線的用戶端的連線資訊.
20509
	$conf["allConn"]=array();
20510
	#可省略參數:
20511
	#無.
20512
	#參考資料:
20513
	#無.
20514
	#備註:
20515
	#無.
20516
	*/
20517
	public static function callFunc(&$conf){
20518
 
20519
		#初始化要回傳的結果
20520
		$result=array();
20521
 
20522
		#取得當前執行的函數名稱
20523
		$result["function"]=__FUNCTION__;
20524
 
20525
		#涵式說明:
20526
		#判斷當前環境為web還是cmd
20527
		#回傳結果:
20528
		#$result,"web"或"cmd"
20529
		if(csInformation::getEnv()==="web"){
226 liveuser 20530
 
66 liveuser 20531
			#設置執行失敗
20532
			$result["status"]="false";
226 liveuser 20533
 
66 liveuser 20534
			#設置執行錯誤訊息
20535
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 20536
 
66 liveuser 20537
			#回傳結果
20538
			return $result;
226 liveuser 20539
 
66 liveuser 20540
			}#if end
20541
 
20542
		#取得參數
20543
		$result["argu"]=$conf;
20544
 
20545
		#如果 $conf 不為陣列
20546
		if(gettype($conf)!="array"){
226 liveuser 20547
 
66 liveuser 20548
			#設置執行失敗
20549
			$result["status"]="false";
226 liveuser 20550
 
66 liveuser 20551
			#設置執行錯誤訊息
20552
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 20553
 
66 liveuser 20554
			#如果傳入的參數為 null
20555
			if($conf==null){
226 liveuser 20556
 
66 liveuser 20557
				#設置執行錯誤訊息
20558
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 20559
 
66 liveuser 20560
				}#if end
20561
 
20562
			#回傳結果
20563
			return $result;
226 liveuser 20564
 
66 liveuser 20565
			}#if end
226 liveuser 20566
 
66 liveuser 20567
		#檢查參數
20568
		#函式說明:
20569
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
20570
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
20571
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
20572
		#$result["function"],當前執行的函式名稱.
20573
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
20574
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
20575
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
20576
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
20577
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
20578
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
20579
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
20580
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
20581
		#必填寫的參數:
20582
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
20583
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
20584
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
20585
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientInfo","clientIndex","allConn");
20586
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
20587
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","array","string","array");
20588
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
20589
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
20590
		#可以省略的參數:
20591
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
20592
		#$conf["canBeEmptyString"]="false";
20593
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
20594
		#$conf["canNotBeEmpty"]=array();
20595
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
20596
		#$conf["canBeEmpty"]=array();
20597
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
20598
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
20599
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
20600
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("listenIp","listenPort","wsMode","processFuncs");
226 liveuser 20601
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 20602
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","array");
20603
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
20604
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("127.0.0.1",null,"false",null);
20605
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
20606
		#$conf["arrayCountEqualCheck"][]=array();
20607
		#參考資料來源:
20608
		#array_keys=>http://php.net/manual/en/function.array-keys.php
20609
		#建議:
20610
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
20611
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
20612
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 20613
 
66 liveuser 20614
		#如果檢查參數失敗
20615
		if($checkArguments["status"]==="false"){
226 liveuser 20616
 
66 liveuser 20617
			#設置執行失敗
20618
			$result["status"]="false";
226 liveuser 20619
 
66 liveuser 20620
			#設置執行錯誤訊息
20621
			$result["error"]=$checkArguments;
226 liveuser 20622
 
66 liveuser 20623
			#回傳結果
20624
			return $result;
226 liveuser 20625
 
66 liveuser 20626
			}#if end
226 liveuser 20627
 
66 liveuser 20628
		#如果檢查參數不通過
20629
		if($checkArguments["passed"]==="false"){
226 liveuser 20630
 
66 liveuser 20631
			#設置執行失敗
20632
			$result["status"]="false";
226 liveuser 20633
 
66 liveuser 20634
			#設置執行錯誤訊息
20635
			$result["error"]=$checkArguments;
226 liveuser 20636
 
66 liveuser 20637
			#回傳結果
20638
			return $result;
226 liveuser 20639
 
66 liveuser 20640
			}#if end
20641
 
20642
		#取得收到的訊息
20643
		$receivedData=$conf["data"];
226 liveuser 20644
 
66 liveuser 20645
		#取得 server 的 socket
20646
		$serverSocket=$conf["serverSock"];
226 liveuser 20647
 
66 liveuser 20648
		#取得 client 的 socket
20649
		$clientSocket=$conf["clientSock"];
226 liveuser 20650
 
66 liveuser 20651
		#取得 client 的資訊
20652
		$clientInfo=$conf["clientInfo"];
226 liveuser 20653
 
66 liveuser 20654
		#取得 client 的索引
20655
		$clientIndex=$conf["clientIndex"];
226 liveuser 20656
 
66 liveuser 20657
		#取得 all clients 的資訊
20658
		$allConn=$conf["allConn"];
226 liveuser 20659
 
66 liveuser 20660
		#hex2bin
20661
		#函式說明:
20662
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,gpg,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
20663
		#回傳結果:
226 liveuser 20664
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 20665
		#$result["function"],當前執行的函數名稱.
20666
		#$result["content"],加密後的結果.
20667
		#$result["error"],錯誤訊息陣列.
20668
		#$result["argu"],使用的參數.
20669
		#必填參數:
20670
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
20671
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
20672
		#$conf["enCodeType"],"字串",加密或編碼的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin"與"gpg"與"hex2bin&gpg",9種,"sha1"較耗時;"md5"較快;"p_hash"適用於密碼加密;"aes256"是對稱式加解密;"qbpwcf"是透過urlencode、json_encode、base64_encode的結果;"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin";"gpg"是應用gpg進行加解密,需要先有ID對應的key;"hex2bin&gpg"為先hex2bin在進行gpg加解密.
20673
		$conf["authenticate::enCodeStr"]["enCodeType"]="hex2bin";
20674
		#可省略參數:
20675
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
20676
		#$conf["sha1Raw"]="false";
20677
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
20678
		#$conf["p_hash"]="";
20679
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
20680
		#$conf["keyForAes256"]="";
20681
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
20682
		#$conf["aes256Encode"]="";
20683
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
20684
		#$conf["qbpwcfDecode"]="false";
20685
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
20686
		#$conf["gpgDecrypt"]="false";
20687
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
20688
		$conf["authenticate::enCodeStr"]["gpgId"]=gnupgId;
20689
		#參考資料:
20690
		#sha1=>http://php.net/manual/en/function.sha1.php
20691
		#md5=>http://php.net/manual/en/function.md5.php
20692
		#password_hash=>http://php.net/manual/en/function.password-hash.php
20693
		#password_verify=>http://php.net/manual/en/function.password-verify.php
20694
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
20695
		#備註:
20696
		#無.
20697
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
20698
		unset($conf["authenticate::enCodeStr"]);
226 liveuser 20699
 
66 liveuser 20700
		#如果執行失敗
20701
		if($enCodeStr["status"]==="false"){
226 liveuser 20702
 
66 liveuser 20703
			#印出結果
20704
			return $enCodeStr;
226 liveuser 20705
 
66 liveuser 20706
			}#if end
226 liveuser 20707
 
66 liveuser 20708
		#用GnuPG解密
20709
		#函式說明:
20710
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,gpg,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
20711
		#回傳結果:
226 liveuser 20712
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 20713
		#$result["function"],當前執行的函數名稱.
20714
		#$result["content"],加密後的結果.
20715
		#$result["error"],錯誤訊息陣列.
20716
		#$result["argu"],使用的參數.
20717
		#必填參數:
20718
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
20719
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$$enCodeStr["content"];
20720
		#$conf["enCodeType"],"字串",加密或編碼的類型,有"sha1"與"md5"與"p_hash"與"aes256"與"qbpwcf"與"bin2hex"與"hex2bin"與"gpg"與"hex2bin&gpg",9種,"sha1"較耗時;"md5"較快;"p_hash"適用於密碼加密;"aes256"是對稱式加解密;"qbpwcf"是透過urlencode、json_encode、base64_encode的結果;"bin2hex"是依照每個byte的整數數值轉成"00"~"FF"後的結果,反之為"hex2bin";"gpg"是應用gpg進行加解密,需要先有ID對應的key;"hex2bin&gpg"為先hex2bin在進行gpg加解密.
20721
		$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
20722
		#可省略參數:
20723
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
20724
		#$conf["sha1Raw"]="false";
20725
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
20726
		#$conf["p_hash"]="";
20727
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
20728
		#$conf["keyForAes256"]="";
20729
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
20730
		#$conf["aes256Encode"]="";
20731
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
20732
		#$conf["qbpwcfDecode"]="false";
20733
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
20734
		#$conf["gpgDecrypt"]="false";
20735
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
20736
		$conf["authenticate::enCodeStr"]["gpgId"]=gnupgId;
20737
		#參考資料:
20738
		#sha1=>http://php.net/manual/en/function.sha1.php
20739
		#md5=>http://php.net/manual/en/function.md5.php
20740
		#password_hash=>http://php.net/manual/en/function.password-hash.php
20741
		#password_verify=>http://php.net/manual/en/function.password-verify.php
20742
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
20743
		#備註:
20744
		#無.
20745
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
20746
		unset($conf["authenticate::enCodeStr"]);
226 liveuser 20747
 
66 liveuser 20748
		#如果執行失敗
20749
		if($enCodeStr["status"]==="false"){
226 liveuser 20750
 
66 liveuser 20751
			#印出結果
20752
			return $enCodeStr;
226 liveuser 20753
 
66 liveuser 20754
			}#if end
226 liveuser 20755
 
66 liveuser 20756
		#解碼取得的內容
20757
		$receivedData=json_decode($enCodeStr["content"]);
226 liveuser 20758
 
66 liveuser 20759
		#如果有設置 callFunc
20760
		if(isset($receivedData->callFunc)){
226 liveuser 20761
 
66 liveuser 20762
			#取得要呼叫的函式
20763
			$func=$receivedData->callFunc;
226 liveuser 20764
 
66 liveuser 20765
			#檢查是否有權限執行該函式
20766
			#函式說明:
20767
			#提供webSock::nativeSocketTcpIpServer用於接受檢查權限的功能.
20768
			#回傳結果:
20769
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
20770
			#$result["error"],執行不正常結束的錯訊息陣列.
20771
			#$result["argu"],陣列,使用的參數.
20772
			#必填參數:
20773
			#$conf["data"],字串,收到的bin2hex編碼後果gpg加密過後的json格式資料,必填的key有"randomStr","username","password".
20774
			$conf["self::checkAuth"]["data"]=$conf["data"];
20775
			#$conf["serverSock"],resource,web socket server socket
20776
			$conf["self::checkAuth"]["serverSock"]=$conf["serverSock"];
20777
			#$conf["clientSock"],$resource,web socket client socket
20778
			$conf["self::checkAuth"]["clientSock"]=$conf["clientSock"];
20779
			#$conf["clientInfo"],陣列,web socket client info.
20780
			$conf["self::checkAuth"]["clientInfo"]=$conf["clientInfo"];
20781
			#$conf["clientIndex"],整數.web socket client index.
20782
			$conf["self::checkAuth"]["clientIndex"]=$conf["clientIndex"];
20783
			#$conf["allConn"],陣列,all web socket client info.
20784
			$conf["self::checkAuth"]["allConn"]=$conf["allConn"];
20785
			#$conf["func"],字串,要檢查的是否具備權限的函式.
20786
			$conf["self::checkAuth"]["func"]=$func;
20787
			#可省略參數:
20788
			#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
20789
			#$conf["wsMode"]="true";
20790
			#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
20791
			#$conf["gpgId"]=gnupgId;
20792
			#$conf["falseAllowFuncPlus"],陣列,額外的未認證時可以執行的函式清單.
20793
			#$conf["falseAllowFuncPlus"]=array();
20794
			#$conf["publicAllowFuncPlus"],陣列,額外的認證為public時可以執行的函式清單.
20795
			#$conf["publicAllowFuncPlus"]=array();
20796
			#參考資料:
20797
			#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
20798
			#備註:
20799
			#無.
20800
			$checkAuth=self::checkAuth($conf["self::checkAuth"]);
20801
			unset($conf["self::checkAuth"]);
226 liveuser 20802
 
66 liveuser 20803
			#如果異常
20804
			if($checkAuth["status"]==="false"){
226 liveuser 20805
 
66 liveuser 20806
				#回傳結果
20807
				return $checkAuth;
226 liveuser 20808
 
66 liveuser 20809
				}#if end
226 liveuser 20810
 
66 liveuser 20811
			#移除使用好的元素
20812
			unset($receivedData["callFunc"]);
226 liveuser 20813
 
66 liveuser 20814
			#置換data為未加密的內容
20815
			$conf["data"]=json_encode($receivedData);
226 liveuser 20816
 
66 liveuser 20817
			#呼叫對應的函式
20818
			return eval($func."(&\$conf);");
226 liveuser 20819
 
66 liveuser 20820
			}#if end
226 liveuser 20821
 
66 liveuser 20822
		#設置執行失敗
20823
		$result["ststus"]="false";
226 liveuser 20824
 
66 liveuser 20825
		#回傳結果
20826
		return $result;
20827
 
20828
		}#function callFunc end
226 liveuser 20829
 
3 liveuser 20830
	}#class webSock end
20831
 
226 liveuser 20832
?>