Subversion Repositories php-qbpwcf

Rev

Rev 71 | Go to most recent revision | 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.
226 liveuser 6
    Copyright (C) 2014~2025 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
 
3 liveuser 149
        	$this->clients = new \SplObjectStorage;
226 liveuser 150
 
3 liveuser 151
		}#funciton __construct end
226 liveuser 152
 
3 liveuser 153
	#當用戶與伺服器建立連線時
154
    	public function onOpen(ConnectionInterface $conn){
226 liveuser 155
 
3 liveuser 156
		// Store the new connection to send messages to later
157
        	$this->clients->attach($conn);
158
 
159
		#提示server有clent連上web socket.
160
        	echo "New connection! ({$conn->resourceId})\n";
226 liveuser 161
 
3 liveuser 162
		#用client的id為index來儲存額外的資訊
163
        	#元素 "conn" 代表已經建立連線的ConnectionInterface物件
164
 		#元素 "talkTo" 代表要跟誰講話
165
		#元素 "userId" 代表辨識使用者的id
166
		#元素 "loigin=array("ac","pw")" 代表client輸入的帳號與密碼
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
	#當伺服器收到訊息時
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();
3 liveuser 10115
	#參考資料:
10116
	#http://php.net/manual/en/sockets.examples.php
10117
	#http://us3.php.net/manual/en/function.socket-select.php
10118
	#response should at least end with "\r"=>http://stackoverflow.com/questions/25739768/websocket-communication-between-chromeclient-and-hotspotserver-status-line
10119
	#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
10120
	#webSocket實做=>http://srchea.com/build-a-real-time-application-using-html5-websockets
10121
	#webSocketServer實做=>http://www.cuelogic.com/blog/php-and-html5-websocket-server-and-client-communication/
10122
	#備註:
10123
	#僅能在命令列執行.
71 liveuser 10124
	#runPhpWhenIdle的功能尚未實作.
3 liveuser 10125
	*/
10126
	public static function nativeSocketTcpIpServer(&$conf){
226 liveuser 10127
 
3 liveuser 10128
		#初始化要回傳的結果
10129
		$result=array();
10130
 
10131
		#取得當前執行的函數名稱
10132
		$result["function"]=__FUNCTION__;
10133
 
10134
		#涵式說明:
10135
		#判斷當前環境為web還是cmd
10136
		#回傳結果:
10137
		#$result,"web"或"cmd"
10138
		if(csInformation::getEnv()==="web"){
226 liveuser 10139
 
3 liveuser 10140
			#設置執行失敗
10141
			$result["status"]="false";
226 liveuser 10142
 
3 liveuser 10143
			#設置執行錯誤訊息
10144
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 10145
 
3 liveuser 10146
			#回傳結果
10147
			return $result;
226 liveuser 10148
 
3 liveuser 10149
			}#if end
10150
 
10151
		#取得參數
10152
		$result["argu"]=$conf;
10153
 
10154
		#如果 $conf 不為陣列
10155
		if(gettype($conf)!="array"){
226 liveuser 10156
 
3 liveuser 10157
			#設置執行失敗
10158
			$result["status"]="false";
226 liveuser 10159
 
3 liveuser 10160
			#設置執行錯誤訊息
10161
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 10162
 
3 liveuser 10163
			#如果傳入的參數為 null
10164
			if($conf==null){
226 liveuser 10165
 
3 liveuser 10166
				#設置執行錯誤訊息
10167
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 10168
 
3 liveuser 10169
				}#if end
10170
 
10171
			#回傳結果
10172
			return $result;
226 liveuser 10173
 
3 liveuser 10174
			}#if end
226 liveuser 10175
 
3 liveuser 10176
		#檢查參數
10177
		#函式說明:
10178
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
10179
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
10180
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
10181
		#$result["function"],當前執行的函式名稱.
10182
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
10183
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
10184
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
10185
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
10186
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
10187
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
10188
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
10189
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
10190
		#必填寫的參數:
10191
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
10192
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
10193
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
10194
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu");
10195
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
10196
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
10197
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
10198
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
10199
		#可以省略的參數:
10200
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
10201
		#$conf["canBeEmptyString"]="false";
10202
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
10203
		#$conf["canNotBeEmpty"]=array();
10204
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
10205
		#$conf["canBeEmpty"]=array();
10206
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
10207
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
10208
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
66 liveuser 10209
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("listenIp","listenPort","wsMode","processFuncs","idleFunc");
226 liveuser 10210
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 10211
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","array","array");
3 liveuser 10212
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
68 liveuser 10213
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("127.0.0.1",null,"false",array("noAuth"),array());
3 liveuser 10214
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
10215
		#$conf["arrayCountEqualCheck"][]=array();
10216
		#參考資料來源:
10217
		#array_keys=>http://php.net/manual/en/function.array-keys.php
10218
		#建議:
10219
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
10220
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
10221
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 10222
 
3 liveuser 10223
		#如果檢查參數失敗
10224
		if($checkArguments["status"]==="false"){
226 liveuser 10225
 
3 liveuser 10226
			#設置執行失敗
10227
			$result["status"]="false";
226 liveuser 10228
 
3 liveuser 10229
			#設置執行錯誤訊息
10230
			$result["error"]=$checkArguments;
226 liveuser 10231
 
3 liveuser 10232
			#回傳結果
10233
			return $result;
226 liveuser 10234
 
3 liveuser 10235
			}#if end
226 liveuser 10236
 
3 liveuser 10237
		#如果檢查參數不通過
10238
		if($checkArguments["passed"]==="false"){
226 liveuser 10239
 
3 liveuser 10240
			#設置執行失敗
10241
			$result["status"]="false";
226 liveuser 10242
 
3 liveuser 10243
			#設置執行錯誤訊息
10244
			$result["error"]=$checkArguments;
226 liveuser 10245
 
3 liveuser 10246
			#回傳結果
10247
			return $result;
226 liveuser 10248
 
66 liveuser 10249
			}#if end
226 liveuser 10250
 
3 liveuser 10251
		#如果 $conf["listenPort"] 不存在
10252
		if(!isset($conf["listenPort"])){
226 liveuser 10253
 
3 liveuser 10254
			#用nmap掃port
10255
			#函式說明:
10256
			#掃port的程式
10257
			#回傳結果:
10258
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
10259
			#$result["error"],錯誤訊息.
10260
			#$result["function"],當前執行的函數名稱.
10261
			#$result["argu"],使用的參數.
10262
			#$result["content"],掃好可能可以使用的port資訊.
10263
			#必填參數
10264
			#無:
10265
			#可省略參數:
10266
			#$conf["target"],字串,要掃描的主機,預設為"127.0.0.1",
10267
			$conf["cmd::nmap"]["target"]=$conf["listenIp"];
10268
			#$conf["-Pn"],字串,是否要啟用避免ping不到就會掃port失敗的功能,預設為"false".
10269
			#$conf["-Pn"]="false";
10270
			$nmap=cmd::nmap($conf["cmd::nmap"]);
10271
			unset($conf["cmd::nmap"]);
226 liveuser 10272
 
3 liveuser 10273
			#如果掃port失敗
10274
			if($nmap["status"]==="false"){
226 liveuser 10275
 
3 liveuser 10276
				#設置執行失敗
10277
				$result["status"]="false";
226 liveuser 10278
 
3 liveuser 10279
				#設置執行錯誤訊息
10280
				$result["error"]=$nmap;
226 liveuser 10281
 
3 liveuser 10282
				#回傳結果
10283
				return $result;
226 liveuser 10284
 
3 liveuser 10285
				}#if end
226 liveuser 10286
 
3 liveuser 10287
			#如果有掃到port
10288
			if(count($nmap["content"])>0){
226 liveuser 10289
 
3 liveuser 10290
				#找最大的port
10291
				#涵式說明:
10292
				#找最大值,結果會回傳最大值.
10293
				#回傳的結果:
10294
				#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
10295
				#$result["error"],錯誤訊息陣列.
10296
				#$result["function"],當前執行的函數名稱.
10297
				#$result["key"],最大值原先的key.
10298
				#$result["value"],最大值的數字.
10299
				#必填的參數:
10300
				$conf["math::getMaxValue"]["rawDataArray"]=$nmap["content"];#爲原始數據
10301
				$getMaxValue=math::getMaxValue($conf["math::getMaxValue"]);
10302
				unset($conf["math::getMaxValue"]);
226 liveuser 10303
 
3 liveuser 10304
				#如果找最大port失敗
10305
				if($getMaxValue["status"]==="false"){
226 liveuser 10306
 
3 liveuser 10307
					#設置執行失敗
10308
					$result["status"]="false";
226 liveuser 10309
 
3 liveuser 10310
					#設置執行錯誤訊息
10311
					$result["error"]=$getMaxValue;
226 liveuser 10312
 
3 liveuser 10313
					#回傳結果
10314
					return $result;
226 liveuser 10315
 
3 liveuser 10316
					}#if end
226 liveuser 10317
 
3 liveuser 10318
				#設置 $conf["listenPort"] 為最大 port+1
10319
				$conf["listenPort"]=$getMaxValue["value"]+1;
226 liveuser 10320
 
3 liveuser 10321
				#如果port小於4000,會無法讓nmap偵測到有使用
10322
				if($conf["listenPort"]<4000){
226 liveuser 10323
 
3 liveuser 10324
					#設為4000
10325
					$conf["listenPort"]="4000";
226 liveuser 10326
 
3 liveuser 10327
					}#if end
226 liveuser 10328
 
66 liveuser 10329
				}#if end
226 liveuser 10330
 
3 liveuser 10331
			}#if end
226 liveuser 10332
 
3 liveuser 10333
		#反之
10334
		else{
226 liveuser 10335
 
3 liveuser 10336
			#用nmap掃port
10337
			#函式說明:
10338
			#掃port的程式
10339
			#回傳結果:
10340
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
10341
			#$result["error"],錯誤訊息.
10342
			#$result["function"],當前執行的函數名稱.
10343
			#$result["argu"],使用的參數.
10344
			#$result["content"],掃好可能可以使用的port資訊.
10345
			#必填參數
10346
			#無:
10347
			#可省略參數:
10348
			#$conf["target"],字串,要掃描的主機,預設為"127.0.0.1",
10349
			$conf["cmd::nmap"]["target"]=$conf["listenIp"];
10350
			#$conf["-Pn"],字串,是否要啟用避免ping不到就會掃port失敗的功能,預設為"false".
10351
			#$conf["-Pn"]="false";
10352
			#$conf["fileArgu"],字串,變數__FILE__的內容.
10353
			$conf["cmd::nmap"]["fileArgu"]=$conf["fileArgu"];
10354
			$nmap=cmd::nmap($conf["cmd::nmap"]);
10355
			unset($conf["cmd::nmap"]);
226 liveuser 10356
 
3 liveuser 10357
			#如果掃port失敗
10358
			if($nmap["status"]==="false"){
226 liveuser 10359
 
3 liveuser 10360
				#設置執行失敗
10361
				$result["status"]="false";
226 liveuser 10362
 
3 liveuser 10363
				#設置執行錯誤訊息
10364
				$result["error"]=$nmap;
226 liveuser 10365
 
3 liveuser 10366
				#回傳結果
10367
				return $result;
226 liveuser 10368
 
3 liveuser 10369
				}#if end
226 liveuser 10370
 
3 liveuser 10371
			#如果有掃到port
10372
			if(count($nmap["content"])>0){
226 liveuser 10373
 
3 liveuser 10374
				#如果要用來建立socket的port已被使用
10375
				if(in_array($conf["listenPort"],$nmap["content"])){
226 liveuser 10376
 
3 liveuser 10377
					#找最大的port
10378
					#涵式說明:
10379
					#找最大值,結果會回傳最大值.
10380
					#回傳的結果:
10381
					#$result["status"],執行是否正常,"true"為正常,"false"為不正常.
10382
					#$result["error"],錯誤訊息陣列.
10383
					#$result["function"],當前執行的函數名稱.
10384
					#$result["key"],最大值原先的key.
10385
					#$result["value"],最大值的數字.
10386
					#必填的參數:
10387
					$conf["math::getMaxValue"]["rawDataArray"]=$nmap["content"];#爲原始數據
10388
					$getMaxValue=math::getMaxValue($conf["math::getMaxValue"]);
10389
					unset($conf["math::getMaxValue"]);
226 liveuser 10390
 
3 liveuser 10391
					#如果找最大port失敗
10392
					if($getMaxValue["status"]==="false"){
226 liveuser 10393
 
3 liveuser 10394
						#設置執行失敗
10395
						$result["status"]="false";
226 liveuser 10396
 
3 liveuser 10397
						#設置執行錯誤訊息
10398
						$result["error"]=$getMaxValue;
226 liveuser 10399
 
3 liveuser 10400
						#回傳結果
10401
						return $result;
226 liveuser 10402
 
3 liveuser 10403
						}#if end
226 liveuser 10404
 
3 liveuser 10405
					#設置 $conf["listenPort"] 為最大 port+1
10406
					$conf["listenPort"]=$getMaxValue["value"]+1;
226 liveuser 10407
 
3 liveuser 10408
					#如果port小於4000,會無法讓nmap偵測到有使用
10409
					if($conf["listenPort"]<4000){
226 liveuser 10410
 
3 liveuser 10411
						#設為4000
10412
						$conf["listenPort"]="4000";
226 liveuser 10413
 
3 liveuser 10414
						}#if end
226 liveuser 10415
 
3 liveuser 10416
					}#if end
226 liveuser 10417
 
3 liveuser 10418
				}#if end
226 liveuser 10419
 
3 liveuser 10420
			}#else end
226 liveuser 10421
 
3 liveuser 10422
		#回報任何錯誤
10423
		#error_reporting(E_ALL);
10424
 
10425
		/* Allow the script to hang around waiting for connections. */
10426
		set_time_limit(0);
10427
 
10428
		/* Turn on implicit output flushing so we see what we're getting as it comes in. */
10429
		#ob_implicit_flush();
10430
 
10431
		#設定要listen的主機ip
10432
		$address = $conf["listenIp"];
226 liveuser 10433
 
3 liveuser 10434
		#設定要listen的port
10435
		$port = $conf["listenPort"];
10436
 
10437
		#重複做,讓socket服務不會結束.
10438
		do{
226 liveuser 10439
 
3 liveuser 10440
			#如果建立 socket 失敗
10441
			if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false){
226 liveuser 10442
 
3 liveuser 10443
				#印出錯誤訊息
10444
				echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
226 liveuser 10445
 
3 liveuser 10446
				}#if end
226 liveuser 10447
 
3 liveuser 10448
			#設置不等待連線與訊息的到來,變成不會卡位
10449
			socket_set_nonblock($sock);
226 liveuser 10450
 
3 liveuser 10451
			#SOL_SOCKET => socket level
226 liveuser 10452
			#SO_REUSEADDR => Reports whether local addresses can be reused.
3 liveuser 10453
			socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);
226 liveuser 10454
 
3 liveuser 10455
			#如果 Binds a name to a socket 失敗
10456
			if (@socket_bind($sock, $address, $port) === false){
226 liveuser 10457
 
3 liveuser 10458
				#儲存錯誤訊息
10459
				$error=socket_strerror(socket_last_error($sock));
226 liveuser 10460
 
3 liveuser 10461
				#印出錯誤訊息
10462
				echo "socket_bind() failed: reason: " .$error. PHP_EOL;
226 liveuser 10463
 
3 liveuser 10464
				#判斷錯誤訊息的是否有 "Address already in use"
10465
				#函式說明:
10466
				#檢查字串裡面有無指定的關鍵字
10467
				#回傳的結果:
10468
				#$result["status"],"true"代表執行成功,"false"代表執行失敗。
10469
				#$result["error"],錯誤訊息
10470
				#$result["function"],當前執行的函數名稱.
10471
				#$result["founded"],是否找到關鍵字,"true"代表有找到關鍵字;"false"代表沒有找到關鍵字。
10472
				#$result["keyWordCount"],找到的關鍵字數量.
10473
				#必填的參數:
10474
				$conf["search::findKeyWord"]["keyWord"]="Address already in use";#想要搜尋的關鍵字
10475
				$conf["search::findKeyWord"]["string"]=$error;#要被搜尋的字串內容
10476
				#可省略的參數:
10477
				#$conf["completeEqual"]="true";#是否內容要完全符合,不能多出任何不符合的內容,預設為不需要完全符合。
10478
				$findKeyWord=search::findKeyWord($conf["search::findKeyWord"]);
10479
				unset($conf["search::findKeyWord"]);
226 liveuser 10480
 
3 liveuser 10481
				#如果解析錯誤訊息失敗
10482
				if($findKeyWord["status"]==="false"){
226 liveuser 10483
 
3 liveuser 10484
					#設置執行失敗
10485
					$result["status"]="false";
226 liveuser 10486
 
3 liveuser 10487
					#設置執行錯誤訊息
10488
					$result["error"]=$getMeetConditionsString;
226 liveuser 10489
 
3 liveuser 10490
					#回傳結果
10491
					return $result;
226 liveuser 10492
 
3 liveuser 10493
					}#if end
226 liveuser 10494
 
3 liveuser 10495
				#如果錯誤原因為socket的port已經被使用了.
10496
				if($findKeyWord["founded"]==="true"){
226 liveuser 10497
 
3 liveuser 10498
					#port加1
10499
					$port++;
226 liveuser 10500
 
3 liveuser 10501
					#再次建立socket服務
10502
					continue;
226 liveuser 10503
 
3 liveuser 10504
					}#if end
226 liveuser 10505
 
3 liveuser 10506
				#反之
10507
				else{
226 liveuser 10508
 
3 liveuser 10509
					#結束程式
10510
					exit;
226 liveuser 10511
 
10512
					}#else
10513
 
3 liveuser 10514
				}#if end
10515
 
10516
			#如果 listen socket 經過嘗試5次後仍然失敗
10517
			if (socket_listen($sock, 5) === false) {
226 liveuser 10518
 
3 liveuser 10519
				#印出錯誤訊息
10520
				echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . PHP_EOL;
226 liveuser 10521
 
3 liveuser 10522
				}#if end
10523
 
10524
			#初始化儲存已經連線到 socket service 的服務
10525
			$connections=array();
10526
 
66 liveuser 10527
			#初始化 idle 時要呼叫的函式名稱陣列
10528
			$idleFunc=array();
10529
 
3 liveuser 10530
			#提示 listen 的 ip 與 port
10531
			echo "Listen to:".$address.":".$port.PHP_EOL;
10532
 
10533
			#重複做,等待別人連線.
10534
			do{
226 liveuser 10535
 
3 liveuser 10536
				#初始化儲存有需要處理的socket連線
10537
				$read = array();
226 liveuser 10538
 
3 liveuser 10539
				#初始化一開始建立的socket為要處理的項目
10540
				$read[] = $sock;
226 liveuser 10541
 
3 liveuser 10542
				#有幾個連線就執行幾次
10543
				foreach($connections as $conForSockSelect){
226 liveuser 10544
 
3 liveuser 10545
					#產生要合併的陣列
10546
					$arrayToMerage=array($conForSockSelect["connect"]);
226 liveuser 10547
 
3 liveuser 10548
					#合併陣列
10549
					$read = array_merge($read,$arrayToMerage);
226 liveuser 10550
 
3 liveuser 10551
					}#foreach end
226 liveuser 10552
 
3 liveuser 10553
				#從socket物件陣列($read)裡面取出有需要處理連線的socket物件.
10554
				#Set up a blocking call to socket_select
10555
				$write=array();
10556
				$except=array();
10557
				$tv_sec = 1;
10558
				if(socket_select($read, $write, $except, $tv_sec) < 1){
226 liveuser 10559
 
3 liveuser 10560
					#沒有事情發生
10561
					echo ".";
226 liveuser 10562
 
3 liveuser 10563
					#函式說明:
226 liveuser 10564
					#加密 handshake 後要傳送的訊息
3 liveuser 10565
					#回傳結果:
10566
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
10567
					#$result["error"],執行不正常結束的錯訊息陣列.
10568
					#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
10569
					#$result["argu"],陣列,使用的參數.
10570
					#必填參數:
10571
					#$conf["text"],字串,要加密的訊息.
226 liveuser 10572
					$conf["webSock::encode"]["text"]="";
3 liveuser 10573
					#可省略參數:
10574
					#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
10575
					$conf["webSock::encode"]["ping"]="true";
10576
					#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
10577
					#$conf["frames"]=array();
10578
					#參考資料:
10579
					#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
10580
					#備註:
10581
					#無.
10582
					$encode=webSock::encode($conf["webSock::encode"]);
10583
					unset($conf["webSock::encode"]);
226 liveuser 10584
 
3 liveuser 10585
					#debug
10586
					#var_dump(__LINE__,$encode);
226 liveuser 10587
 
3 liveuser 10588
					#如果執行失敗
10589
					if($encode["status"]==="false"){
226 liveuser 10590
 
3 liveuser 10591
						#設置執行失敗
10592
						$result["status"]="false";
226 liveuser 10593
 
3 liveuser 10594
						#設置執行錯誤訊息
10595
						$result["error"]=$encode;
226 liveuser 10596
 
3 liveuser 10597
						#回傳結果
10598
						return $result;
226 liveuser 10599
 
3 liveuser 10600
						}#if end
226 liveuser 10601
 
3 liveuser 10602
					#針對每個連線的 client
10603
					foreach($connections as $client){
226 liveuser 10604
 
3 liveuser 10605
						#如果有 last ping time
10606
						if(isset($client["lastPongTime"])){
226 liveuser 10607
 
3 liveuser 10608
							#如果小於5秒沒有收到pong
10609
							if(time()-$client["lastPongTime"]<5){
226 liveuser 10610
 
66 liveuser 10611
								#看下一個連線,亦即視為用戶已經斷線.
3 liveuser 10612
								continue;
226 liveuser 10613
 
3 liveuser 10614
								}#if end
226 liveuser 10615
 
3 liveuser 10616
							}#if end
226 liveuser 10617
 
3 liveuser 10618
						#取得用戶socket
10619
						$clientSock=$client["connect"];
226 liveuser 10620
 
3 liveuser 10621
						#傳送ping給client
10622
						$socket_write=socket_write($clientSock, $encode["content"][0], strlen($encode["content"][0]));
226 liveuser 10623
 
3 liveuser 10624
						#debug
10625
						#var_dump(__LINE__,"send ping",$socket_write,socket_strerror(socket_last_error($clientSock)));
226 liveuser 10626
 
3 liveuser 10627
						}#foreach end
226 liveuser 10628
 
66 liveuser 10629
					#如果有idle時要做的事情
10630
					if(count($conf["idleFunc"])>0){
226 liveuser 10631
 
66 liveuser 10632
						#取得idleFunc設定
10633
						$idleFunc=$conf["idleFunc"];
226 liveuser 10634
 
66 liveuser 10635
						#移除初始的idelFunc設定
10636
						unset($conf["idleFunc"]);
226 liveuser 10637
 
66 liveuser 10638
						}#if end
226 liveuser 10639
 
66 liveuser 10640
					#如果有idle時要做的事情
10641
					if(count($idleFunc)>0){
226 liveuser 10642
 
66 liveuser 10643
						#針對每個要執行的函式
10644
						foreach($idleFunc as $if){
226 liveuser 10645
 
66 liveuser 10646
							#設置要給予函式的參數陣列
10647
							$param=array("idleFunc"=>&$idleFunc,"serverSock"=>&$sock,"allConn"=>&$connections);
226 liveuser 10648
 
66 liveuser 10649
							#初始化給予 call_user_func_array 的第2個參數
10650
							$params=array();
226 liveuser 10651
 
66 liveuser 10652
							#設置呼叫函式 $if 時要傳遞的參數為一個 $param
10653
							$params[]=&$param;
226 liveuser 10654
 
66 liveuser 10655
							#呼叫函式 $if 與要傳遞的參數.
10656
							$result=call_user_func_array($if,$params);
226 liveuser 10657
 
66 liveuser 10658
							}#foreach end
226 liveuser 10659
 
66 liveuser 10660
						}#if end
226 liveuser 10661
 
71 liveuser 10662
					#如果有 $php2runWhenIdle
10663
					if(isset($php2runWhenIdle)){
226 liveuser 10664
 
71 liveuser 10665
						#如果有php程式要於idle時執行
10666
						while(count($php2runWhenIdle)>0){
226 liveuser 10667
 
71 liveuser 10668
							#取得要執行的 php code
10669
							$phpCode=array_shift($php2runWhenIdle);
226 liveuser 10670
 
71 liveuser 10671
							#...
226 liveuser 10672
 
71 liveuser 10673
							}#while end
226 liveuser 10674
 
71 liveuser 10675
						}#if end
226 liveuser 10676
 
3 liveuser 10677
					#下一輪
10678
					continue;
226 liveuser 10679
 
3 liveuser 10680
					}#if end
226 liveuser 10681
 
3 liveuser 10682
				#有事情發生
10683
				echo "something happen".PHP_EOL;
226 liveuser 10684
 
3 liveuser 10685
				#如果有socket要處理
10686
				if(in_array($sock,$read)){
226 liveuser 10687
 
3 liveuser 10688
					#如果有接收到 socket 連線
10689
					if (($msgsock = socket_accept($sock)) !== false) {
226 liveuser 10690
 
3 liveuser 10691
						#初始化不是既有的 sock
10692
						$existSock=false;
226 liveuser 10693
 
3 liveuser 10694
						#尋找是哪個 socket
10695
						for($i=0;$i<count($connections);$i++){
226 liveuser 10696
 
3 liveuser 10697
							#如果是既有的 sock
10698
							if($connections[$i]["connect"]===$msgsock){
226 liveuser 10699
 
3 liveuser 10700
								#設置是既有的 sock
10701
								$existSock=true;
226 liveuser 10702
 
3 liveuser 10703
								}#if end
226 liveuser 10704
 
3 liveuser 10705
							}#for end
226 liveuser 10706
 
3 liveuser 10707
						#如果該 socket 是新的
10708
						if(!$existSock){
226 liveuser 10709
 
3 liveuser 10710
							#重複做
10711
							do{
226 liveuser 10712
 
3 liveuser 10713
								#亂數產生連線id
10714
								#涵式說明:
10715
								#建立以圖片(PNG格式)呈現的驗證碼.
10716
								#回傳的解果:
10717
								#$result["status"],執行是否正常,"true"代表執行成功,"false"代表執行失敗.
10718
								#$result["error"],錯誤訊息.
10719
								#$result["function"],檔前執行的函數名稱.
10720
								#$result["randNumberWord"],傳驗證碼的內容.
10721
								#$result["imgAddress"],圖片的位置與名稱.
10722
								#必填的參數:
10723
								#$conf["imgAddressAndName"],字串,爲驗證碼圖片儲存的位置與名稱,副檔名程式會自動產生
10724
								$conf["authenticate::validationCode"]["imgAddressAndName"]="no used!";
10725
								#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
10726
								$conf["authenticate::validationCode"]["fileArgu"]=$conf["fileArgu"];
10727
								#可省略的參數:
10728
								#$conf["num"],字串,爲驗證碼的位數,請輸入阿拉伯數字,預設為"8"位數.
10729
								#$conf["num"]="8";
10730
								#$conf["disableImg"],字串,是否要取消驗證碼圖片的輸出,"true"為要取消,預設為"false"為不取消
10731
								$conf["authenticate::validationCode"]["disableImg"]="true";
10732
								#$conf["imgToData"],字串,預設為"true"代表將圖片轉存成base64圖片,並將原始圖片移除;反之為"false"
10733
								#$conf["authenticate::validationCode"]["imgToData"]="true";
10734
								$validationCode=authenticate::validationCode($conf["authenticate::validationCode"]);
10735
								unset($conf["authenticate::validationCode"]);
226 liveuser 10736
 
3 liveuser 10737
								#如果產生亂數失敗
10738
								if($validationCode["status"]==="false"){
226 liveuser 10739
 
3 liveuser 10740
									#設置執行失敗
10741
									$result["status"]="false";
226 liveuser 10742
 
3 liveuser 10743
									#設置執行錯誤訊息
10744
									$result["error"]=$validationCode;
226 liveuser 10745
 
3 liveuser 10746
									#回傳結果
10747
									return $result;
226 liveuser 10748
 
3 liveuser 10749
									}#if end
226 liveuser 10750
 
3 liveuser 10751
								#如果不存在既有的連線資訊
10752
								if(count($connections)<1){
226 liveuser 10753
 
3 liveuser 10754
									#跳出迴圈
10755
									break;
226 liveuser 10756
 
3 liveuser 10757
									}#if end
226 liveuser 10758
 
3 liveuser 10759
								#初始化連線id的陣列
10760
								$idArray=array();
226 liveuser 10761
 
3 liveuser 10762
								#針對既有的連線
10763
								foreach($connections as $exist_conn){
226 liveuser 10764
 
3 liveuser 10765
									#儲存連線id
10766
									$idArray[]=$exist_conn["id"];
226 liveuser 10767
 
3 liveuser 10768
									}#foreach end
226 liveuser 10769
 
3 liveuser 10770
								}#do end
226 liveuser 10771
 
3 liveuser 10772
							#檢查id有無重複
10773
							while(in_array($validationCode["randNumberWord"],$idArray));
226 liveuser 10774
 
66 liveuser 10775
							#如果不是 ws 模式
3 liveuser 10776
							if($conf["wsMode"]==="false"){
226 liveuser 10777
 
3 liveuser 10778
								#儲存連線到陣列裡面
10779
								$connections[]=array("connect"=>$msgsock,"buf"=>"","id"=>$validationCode["randNumberWord"],"talkTo"=>array());
226 liveuser 10780
 
3 liveuser 10781
								}#if end
226 liveuser 10782
 
3 liveuser 10783
							#如果是 ws 模式
10784
							if($conf["wsMode"]==="true"){
226 liveuser 10785
 
3 liveuser 10786
								#儲存連線到陣列裡面
10787
								$connections[]=array("connect"=>$msgsock,"buf"=>"","id"=>$validationCode["randNumberWord"],"talkTo"=>array(),"handshaked"=>"false","unmask"=>"false","userAgent"=>"false","3rn"=>0,"receivedMsgFromServer"=>array());
226 liveuser 10788
 
3 liveuser 10789
								}#if end
226 liveuser 10790
 
3 liveuser 10791
							#debug,提示 Server 給予的新 Id
10792
							echo "new connection:".PHP_EOL;
226 liveuser 10793
 
3 liveuser 10794
							#初始化連線後要回傳的訊息
10795
							$msg="";
226 liveuser 10796
 
3 liveuser 10797
							#如果不是 ws 模式
10798
							if($conf["wsMode"]!=="true"){
226 liveuser 10799
 
3 liveuser 10800
								#提示client連上線後得到的訊息
10801
								$msg = $msg.PHP_EOL."Welcome to the PHP Test Server.".PHP_EOL;
10802
								$msg = $msg."To quit, type 'quit'. To shut down the server type 'shutdown'.".PHP_EOL;
10803
								socket_write($msgsock, $msg, strlen($msg));
226 liveuser 10804
 
3 liveuser 10805
								}#if end
226 liveuser 10806
 
3 liveuser 10807
							}#if end
226 liveuser 10808
 
3 liveuser 10809
						}#if end
226 liveuser 10810
 
3 liveuser 10811
					}#if end
226 liveuser 10812
 
3 liveuser 10813
				#重新排序 $connections
10814
				#函式說明:
10815
				#將陣列的key重新排序,然後回傳,以便後續存取,也可以指定key的內容,但一定要跟元素數量相同。
10816
				#回傳的解果:
10817
				#$result["status"],執行是否成功,"true"代表成功,"false"代表失敗.
10818
				#$result["error"],執行錯誤的訊息.
10819
				#$result["function"],當前執行的函數名稱.
10820
				#$result["dataContent"],儲存陣列元素的內容.
10821
				#若指定了key的名稱,則 $result["dataContent"] 會變成 $result["dataContent"]["指定的key名稱"]
10822
				#$result["dataCount"],儲存陣列元素的數量。
10823
				#必填的參數:
10824
				$conf["arrays::createV2"]["arrayContent"]=$connections;#陣列變數
10825
				#可省略的參數:
10826
				#$conf["specifiesKeyArray"]=array();#指定key的名稱,須與$conf["arrayContent"]的元素數量相同
10827
				$createV2=arrays::createV2($conf["arrays::createV2"]);
10828
				unset($conf["arrays::createV2"]);
226 liveuser 10829
 
3 liveuser 10830
				#如果重新排序失敗
10831
				if($createV2["status"]==="false"){
226 liveuser 10832
 
3 liveuser 10833
					#設置執行失敗
10834
					$result["status"]="false";
226 liveuser 10835
 
3 liveuser 10836
					#設置執行錯誤訊息
10837
					$result["error"]=$createV2;
226 liveuser 10838
 
3 liveuser 10839
					#回傳結果
10840
					return $result;
226 liveuser 10841
 
3 liveuser 10842
					}#if end
226 liveuser 10843
 
3 liveuser 10844
				#取得重新排序好的陣列
10845
				$connections=$createV2["dataContent"];
226 liveuser 10846
 
3 liveuser 10847
				#依據每個 client 的連線
10848
				foreach($connections as $conIndex => $con){
226 liveuser 10849
 
3 liveuser 10850
					#如果有要處理的socket連線項目
10851
					if(in_array($con["connect"], $read)){
226 liveuser 10852
 
3 liveuser 10853
						#如果不存在 handshaked
10854
						if(!isset($con["handshaked"])){
226 liveuser 10855
 
3 liveuser 10856
							#預設為 "false"
10857
							$con["handshaked"]="false";
226 liveuser 10858
 
3 liveuser 10859
							}#if end
226 liveuser 10860
 
3 liveuser 10861
						#如果有 handshaked
10862
						if($con["handshaked"]==="true"){
226 liveuser 10863
 
66 liveuser 10864
							#讀取內容
3 liveuser 10865
							$buf = @socket_read($con["connect"], 2048, PHP_BINARY_READ);
226 liveuser 10866
 
3 liveuser 10867
							#設置要 unmask
10868
							$connections[$conIndex]["unmask"]="true";
226 liveuser 10869
 
66 liveuser 10870
							#設置尚未 auth
10871
							$connections[$conIndex]["auth"]="false";
226 liveuser 10872
 
3 liveuser 10873
							}#if end
226 liveuser 10874
 
3 liveuser 10875
						#反之
10876
						else{
226 liveuser 10877
 
3 liveuser 10878
							#讀取內容
10879
							$buf = @socket_read($con["connect"], 2048, PHP_NORMAL_READ);
226 liveuser 10880
 
3 liveuser 10881
							}#else end
226 liveuser 10882
 
3 liveuser 10883
						#如果讀取出錯
10884
						if($buf===false){
226 liveuser 10885
 
3 liveuser 10886
							#印出錯誤訊息
10887
							echo "socket_recv() failed: reason: " . socket_strerror(socket_last_error($con["connect"])) . PHP_EOL;
226 liveuser 10888
 
3 liveuser 10889
							#移除該連線的資料
226 liveuser 10890
							unset($connections[$conIndex]);
10891
 
3 liveuser 10892
							#跳到下一輪
10893
							continue;
226 liveuser 10894
 
3 liveuser 10895
							}#if end
226 liveuser 10896
 
3 liveuser 10897
						#如果收到的資料長度為 0 bytes
10898
						if($buf===""){
226 liveuser 10899
 
3 liveuser 10900
							#關閉 socket msg
226 liveuser 10901
							socket_close($con["connect"]);
10902
 
3 liveuser 10903
							#移除該連線的資料
10904
							unset($connections[$conIndex]);
226 liveuser 10905
 
3 liveuser 10906
							#跳到下一輪
10907
							continue;
226 liveuser 10908
 
3 liveuser 10909
							}#if end
226 liveuser 10910
 
3 liveuser 10911
						#印出接受的非換行符號內容
10912
						if($buf!==PHP_EOL){
226 liveuser 10913
 
3 liveuser 10914
							#debug
10915
							echo "received:".$buf.PHP_EOL;
226 liveuser 10916
 
3 liveuser 10917
							}#if end
226 liveuser 10918
 
3 liveuser 10919
						#如果無 handshaked
10920
						if($con["handshaked"]!=="true"){
226 liveuser 10921
 
3 liveuser 10922
							#清除換行字元
10923
							$buf=trim($buf);
226 liveuser 10924
 
3 liveuser 10925
							}#if end
226 liveuser 10926
 
3 liveuser 10927
						#web socket mode
10928
						if($conf["wsMode"]==="true"){
226 liveuser 10929
 
3 liveuser 10930
							#如果不需要 unmask
10931
							if($connections[$conIndex]["unmask"]==="false"){
226 liveuser 10932
 
3 liveuser 10933
								#提示還不用 unmask
10934
								echo "don't need unmask now".PHP_EOL;
226 liveuser 10935
 
3 liveuser 10936
								#重新計數 \r\n
10937
								$connections[$conIndex]["3rn"]=0;
226 liveuser 10938
 
3 liveuser 10939
								}#if end
226 liveuser 10940
 
3 liveuser 10941
							}#if end
226 liveuser 10942
 
3 liveuser 10943
						#如果有內容(不是換行符號)
10944
						$st=trim($buf);
226 liveuser 10945
 
3 liveuser 10946
						#如果是 ws 模式
10947
						if($conf["wsMode"]==="true"){
226 liveuser 10948
 
3 liveuser 10949
							#如果尚未 handshake
10950
							if($connections[$conIndex]["handshaked"]==="false"){
226 liveuser 10951
 
3 liveuser 10952
								#提示 server 在檢查 handshake 用的 key 是否存在.
10953
								echo "check Sec-WebSocket-Key ..".PHP_EOL;
226 liveuser 10954
 
3 liveuser 10955
								#handshake
10956
								#如果收到的內容$buf含有 Sec-WebSocket-Key: 字串開頭,擷取後面的內容存到$matchs裡面.
10957
								if(preg_match("/Sec-WebSocket-Key: (.*)/",$buf,$matchs)){
226 liveuser 10958
 
3 liveuser 10959
									#提示serve在handshake
10960
									echo "do handshake...".PHP_EOL.PHP_EOL;
226 liveuser 10961
 
3 liveuser 10962
									#handshake
10963
									$key = $matchs[1].'258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
226 liveuser 10964
									$key =  base64_encode(sha1($key, true));
10965
 
3 liveuser 10966
									#設置 handshake 的 header
226 liveuser 10967
									$headers =
3 liveuser 10968
									"HTTP/1.1 101 Switching Protocols".PHP_EOL.
10969
									"Upgrade: websocket".PHP_EOL.
10970
									"Connection: Upgrade".PHP_EOL.
10971
									"Sec-WebSocket-Accept: ".$key.PHP_EOL.
10972
									"X-Powered-By: qbpwcf".PHP_EOL.
10973
									PHP_EOL;
226 liveuser 10974
 
3 liveuser 10975
									#傳送header給client
10976
									socket_write($con["connect"], $headers);
226 liveuser 10977
 
3 liveuser 10978
									#儲存server傳送給client的訊息
10979
									#$connections[$conIndex]["receivedMsgFromServer"][]=$headers;
226 liveuser 10980
 
3 liveuser 10981
									#提示serve handshake 完畢
10982
									echo "handshak done...".PHP_EOL;
226 liveuser 10983
 
3 liveuser 10984
									#設置已經 handshake
10985
									$connections[$conIndex]["handshaked"]="true";
226 liveuser 10986
 
3 liveuser 10987
									}#if end
226 liveuser 10988
 
3 liveuser 10989
								}#if end
226 liveuser 10990
 
3 liveuser 10991
							}#if end
226 liveuser 10992
 
3 liveuser 10993
						#如果是 ws 模式
10994
						if($conf["wsMode"]==="true"){
226 liveuser 10995
 
3 liveuser 10996
							#如果尚未 handshake 過
10997
							if($connections[$conIndex]["handshaked"]==="false"){
226 liveuser 10998
 
3 liveuser 10999
								#跳過
11000
								continue;
226 liveuser 11001
 
3 liveuser 11002
								}#if end
226 liveuser 11003
 
66 liveuser 11004
							#如果還不用要 unmask
3 liveuser 11005
							if($connections[$conIndex]["unmask"]==="false"){
226 liveuser 11006
 
3 liveuser 11007
								#跳過
11008
								continue;
226 liveuser 11009
 
3 liveuser 11010
								}#if end
226 liveuser 11011
 
3 liveuser 11012
							}#if end
226 liveuser 11013
 
3 liveuser 11014
						#如果是 ws 模式
11015
						if($conf["wsMode"]==="true"){
226 liveuser 11016
 
3 liveuser 11017
							#debug
11018
							#var_dump(__LINE__,$connections[$conIndex]);
226 liveuser 11019
 
3 liveuser 11020
							#如果已經 handshake 過
11021
							if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 11022
 
11023
								#如果要 unmask
3 liveuser 11024
								if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 11025
 
3 liveuser 11026
									#如果收到的訊息不為空
11027
									if(!empty($buf)){
226 liveuser 11028
 
3 liveuser 11029
										echo "start unmask...".PHP_EOL;
226 liveuser 11030
 
3 liveuser 11031
										#debug
11032
										#var_dump(__LINE__,$buf);
226 liveuser 11033
 
3 liveuser 11034
										#解密 $buf
11035
										#回傳結果:
11036
										#$result["function"],當前函式的名稱.
11037
										#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
11038
										#$result["content"],unmask後的內容.
11039
										#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong.
11040
										#$result["error"],錯誤訊息陣列.
11041
										$conf["self::unmask"]["payload"]=$buf;
11042
										#$conf["self::unmask"]["debug"]="true";
11043
										$buf=webSock::unmask($conf["self::unmask"]);
11044
										unset($conf["self::unmask"]);
226 liveuser 11045
 
3 liveuser 11046
										#如果執行失敗
11047
										if($buf["status"]==="false"){
226 liveuser 11048
 
3 liveuser 11049
											#印出結果
11050
											var_dump($buf);
226 liveuser 11051
 
3 liveuser 11052
											#結束執行
11053
											exit;
226 liveuser 11054
 
3 liveuser 11055
											}#if end
226 liveuser 11056
 
3 liveuser 11057
										#如果是 ping 的回應 pong
11058
										if($buf["type"]==="pong"){
226 liveuser 11059
 
3 liveuser 11060
											#提示收到 pong
11061
											echo "got pong".PHP_EOL;
226 liveuser 11062
 
3 liveuser 11063
											#更新的連線的 last pong time
11064
											$connections[$conIndex]["lastPongTime"]=time();
226 liveuser 11065
 
3 liveuser 11066
											#換處理下一則訊息
11067
											continue;
226 liveuser 11068
 
3 liveuser 11069
											}#if end
226 liveuser 11070
 
3 liveuser 11071
										#如果不是 web socket frame
11072
										if($buf["type"]==="invalid"){
226 liveuser 11073
 
3 liveuser 11074
											#提示收到非 web socket frame
11075
											echo "not web socket frame".PHP_EOL;
226 liveuser 11076
 
3 liveuser 11077
											#debug
11078
											#var_dump(__LINE__,$buf);
226 liveuser 11079
 
3 liveuser 11080
											#換處理下一則訊息
11081
											continue;
226 liveuser 11082
 
3 liveuser 11083
											}#if end
226 liveuser 11084
 
3 liveuser 11085
										#取得umask後的內容
11086
										$buf=$buf["content"];
226 liveuser 11087
 
3 liveuser 11088
										#提示 unmask 結束
11089
										echo "end unmask()".PHP_EOL;
226 liveuser 11090
 
3 liveuser 11091
										#提示 web socket server 收到訊息的長度(bytes)
11092
										echo "Server receviced plain content(".strlen($buf)."):".PHP_EOL;
226 liveuser 11093
 
3 liveuser 11094
										#提示 web socket server 收到的訊息內容
11095
										echo $buf.PHP_EOL;
226 liveuser 11096
 
3 liveuser 11097
										}#if end
226 liveuser 11098
 
3 liveuser 11099
									}#if end
226 liveuser 11100
 
3 liveuser 11101
								}#if end
226 liveuser 11102
 
3 liveuser 11103
							}#if end
226 liveuser 11104
 
66 liveuser 11105
						/*
226 liveuser 11106
 
3 liveuser 11107
						#如果收到的是 id?
11108
						if($buf === 'id?'){
226 liveuser 11109
 
66 liveuser 11110
							#如果尚未認證
11111
							if($connections[$conIndex]["auth"]==="false"){
226 liveuser 11112
 
66 liveuser 11113
								#設置要回傳的訊息
11114
								$talkback="permission denied";
226 liveuser 11115
 
66 liveuser 11116
								}#if end
226 liveuser 11117
 
66 liveuser 11118
							else{
226 liveuser 11119
 
66 liveuser 11120
								#設置要回傳的訊息
11121
								$talkback=$connections[$conIndex]["id"];
226 liveuser 11122
 
66 liveuser 11123
								}#else end
3 liveuser 11124
 
11125
							#debug
11126
							#var_dump(__LINE__,$talkback);
11127
 
11128
							#json encode 要回傳的訊息
11129
							$talkback=json_encode($talkback);
226 liveuser 11130
 
3 liveuser 11131
							#debug
11132
							#var_dump(__LINE__,$talkback);
226 liveuser 11133
 
3 liveuser 11134
							#如果是 ws 模式
11135
							if($conf["wsMode"]==="true"){
226 liveuser 11136
 
3 liveuser 11137
								#如果已經 handshake 過
11138
								if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 11139
 
11140
									#如果要 unmask
3 liveuser 11141
									if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 11142
 
3 liveuser 11143
										#函式說明:
226 liveuser 11144
										#加密 handshake 後要傳送的訊息
3 liveuser 11145
										#回傳結果:
11146
										#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11147
										#$result["error"],執行不正常結束的錯訊息陣列.
11148
										#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
11149
										#$result["argu"],陣列,使用的參數.
11150
										#必填參數:
11151
										#$conf["text"],字串,要加密的訊息.
226 liveuser 11152
										$conf["webSock::encode"]["text"]=$talkback;
3 liveuser 11153
										#可省略參數:
11154
										#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
11155
										#$conf["payloadIsBin"]="false";
11156
										#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
11157
										#$conf["ping"]="false";
11158
										#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
11159
										#$conf["pong"]="false";
11160
										#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
11161
										#$conf["frames"]=array();
11162
										#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
11163
										#$conf["mask"]="false";
11164
										#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
11165
										#$conf["debug"]="false";
11166
										#參考資料:
11167
										#無.
11168
										#備註:
11169
										#目前$conf["text"]長度超過125會出錯.
11170
										$talkback=webSock::encode($conf["webSock::encode"]);
11171
										unset($conf["webSock::encode"]);
226 liveuser 11172
 
3 liveuser 11173
										#如果執行失敗
11174
										if($talkback["status"]==="false"){
226 liveuser 11175
 
3 liveuser 11176
											#印出結果
11177
											var_dump($talkback);
226 liveuser 11178
 
3 liveuser 11179
											#結束執行
11180
											exit;
226 liveuser 11181
 
3 liveuser 11182
											}#if end
226 liveuser 11183
 
3 liveuser 11184
										#debug
11185
										#var_dump(__LINE__,$talkback);
226 liveuser 11186
 
3 liveuser 11187
										}#if end
226 liveuser 11188
 
3 liveuser 11189
									}#if end
226 liveuser 11190
 
3 liveuser 11191
								}#if end
226 liveuser 11192
 
3 liveuser 11193
							#反之不為 web socket 訊息
11194
							else{
226 liveuser 11195
 
3 liveuser 11196
								#儲存成只有一個訊息
11197
								$talkback["content"][]=$talkback;
226 liveuser 11198
 
3 liveuser 11199
								}#else
226 liveuser 11200
 
3 liveuser 11201
							#針對每個訊息的分段
11202
							foreach($talkback["content"] as $msg){
226 liveuser 11203
 
3 liveuser 11204
								#debug
11205
								var_dump(__LINE__,$msg);
226 liveuser 11206
 
3 liveuser 11207
								#回傳訊息
11208
								$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 11209
 
3 liveuser 11210
								#debug
11211
								var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 11212
 
3 liveuser 11213
								}#foreach end
226 liveuser 11214
 
3 liveuser 11215
							#跳到下一輪
11216
							continue;
226 liveuser 11217
 
3 liveuser 11218
							}#if end
226 liveuser 11219
 
11220
						*/
11221
 
66 liveuser 11222
						/*
226 liveuser 11223
 
3 liveuser 11224
						#如果收到的是 ids?
11225
						if($buf === 'ids?'){
226 liveuser 11226
 
66 liveuser 11227
							#如果尚未認證
11228
							if($connections[$conIndex]["auth"]==="false"){
226 liveuser 11229
 
66 liveuser 11230
								#設置要回傳的訊息
11231
								$talkback=json_encode("permission denied");
226 liveuser 11232
 
66 liveuser 11233
								}#if end
226 liveuser 11234
 
66 liveuser 11235
							#反之
11236
							else{
226 liveuser 11237
 
66 liveuser 11238
								#設置要回傳的訊息
11239
								$talkback=array();
226 liveuser 11240
 
66 liveuser 11241
								#針對每個連線
11242
								foreach($connections as $conIndex_ids => $con_ids){
11243
 
11244
									#如果不是自己
11245
									if($con_ids["connect"]!==$connections[$conIndex]["connect"]){
226 liveuser 11246
 
66 liveuser 11247
										#記錄其他人的id
11248
										$talkback[]=$con_ids["id"];
226 liveuser 11249
 
66 liveuser 11250
										}#if end
226 liveuser 11251
 
66 liveuser 11252
									}#foreach end
226 liveuser 11253
 
66 liveuser 11254
								#json encode要回傳的id陣列
11255
								$talkback=json_encode($talkback);
226 liveuser 11256
 
66 liveuser 11257
								}#else end
226 liveuser 11258
 
3 liveuser 11259
							#如果是 ws 模式
11260
							if($conf["wsMode"]==="true"){
226 liveuser 11261
 
3 liveuser 11262
								#如果已經 handshake 過
11263
								if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 11264
 
66 liveuser 11265
									#如果要 unmask
3 liveuser 11266
									if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 11267
 
3 liveuser 11268
										#函式說明:
226 liveuser 11269
										#加密 handshake 後要傳送的訊息
3 liveuser 11270
										#回傳結果:
11271
										#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11272
										#$result["error"],執行不正常結束的錯訊息陣列.
11273
										#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
11274
										#$result["argu"],陣列,使用的參數.
11275
										#必填參數:
11276
										#$conf["text"],字串,要加密的訊息.
226 liveuser 11277
										$conf["webSock::encode"]["text"]=$talkback;
3 liveuser 11278
										#可省略參數:
11279
										#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
11280
										#$conf["payloadIsBin"]="false";
11281
										#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
11282
										#$conf["ping"]="false";
11283
										#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
11284
										#$conf["pong"]="false";
11285
										#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
11286
										#$conf["frames"]=array();
11287
										#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
11288
										#$conf["mask"]="false";
11289
										#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
11290
										#$conf["debug"]="false";
11291
										#參考資料:
11292
										#無.
11293
										#備註:
11294
										#目前$conf["text"]長度超過125會出錯.
11295
										$talkback=webSock::encode($conf["webSock::encode"]);
11296
										unset($conf["webSock::encode"]);
226 liveuser 11297
 
3 liveuser 11298
										#如果執行失敗
11299
										if($talkback["status"]==="false"){
226 liveuser 11300
 
3 liveuser 11301
											#印出結果
11302
											var_dump($talkback);
226 liveuser 11303
 
3 liveuser 11304
											#結束執行
11305
											exit;
226 liveuser 11306
 
3 liveuser 11307
											}#if end
226 liveuser 11308
 
3 liveuser 11309
										#debug
11310
										#var_dump(__LINE__,$talkback);
226 liveuser 11311
 
3 liveuser 11312
										}#if end
226 liveuser 11313
 
3 liveuser 11314
									}#if end
226 liveuser 11315
 
3 liveuser 11316
								}#if end
226 liveuser 11317
 
3 liveuser 11318
							#反之不為 web socket 訊息
11319
							else{
226 liveuser 11320
 
3 liveuser 11321
								#儲存成只有一個訊息
11322
								$talkback["content"][]=$talkback;
226 liveuser 11323
 
3 liveuser 11324
								}#else
226 liveuser 11325
 
3 liveuser 11326
							#針對每個訊息的分段
11327
							foreach($talkback["content"] as $msg){
226 liveuser 11328
 
3 liveuser 11329
								#回傳訊息
11330
								$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 11331
 
3 liveuser 11332
								#debug
11333
								var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 11334
 
3 liveuser 11335
								}#foreach end
226 liveuser 11336
 
3 liveuser 11337
							#跳到下一輪
11338
							continue;
226 liveuser 11339
 
3 liveuser 11340
							}#if end
226 liveuser 11341
 
3 liveuser 11342
						#如果收到 "talkTo?"
11343
						if($buf==="talkTo?"){
226 liveuser 11344
 
66 liveuser 11345
							#如果尚未認證
11346
							if($connections[$conIndex]["auth"]==="false"){
226 liveuser 11347
 
66 liveuser 11348
								#設置要回傳的訊息
11349
								$talkback=json_encode("permission denied");
226 liveuser 11350
 
66 liveuser 11351
								}#if end
226 liveuser 11352
 
66 liveuser 11353
							#反之
11354
							else{
226 liveuser 11355
 
66 liveuser 11356
								#初始化要講話的id陣列
11357
								$talkback=array();
226 liveuser 11358
 
66 liveuser 11359
								#有幾個要講話的人就執行幾次
11360
								foreach($connections[$conIndex]["talkTo"] as $to){
226 liveuser 11361
 
66 liveuser 11362
									#串街要講話的人
11363
									$talkback[]=$to;
226 liveuser 11364
 
66 liveuser 11365
									}#foreach end
226 liveuser 11366
 
66 liveuser 11367
								#設置要回傳的訊息
11368
								$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 11369
 
66 liveuser 11370
								}#else end
226 liveuser 11371
 
3 liveuser 11372
							#如果是 ws 模式
11373
							if($conf["wsMode"]==="true"){
226 liveuser 11374
 
3 liveuser 11375
								#如果已經 handshake 過
11376
								if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 11377
 
11378
									#如果要 unmask
3 liveuser 11379
									if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 11380
 
3 liveuser 11381
										#函式說明:
226 liveuser 11382
										#加密 handshake 後要傳送的訊息
3 liveuser 11383
										#回傳結果:
11384
										#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11385
										#$result["error"],執行不正常結束的錯訊息陣列.
11386
										#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
11387
										#$result["argu"],陣列,使用的參數.
11388
										#必填參數:
11389
										#$conf["text"],字串,要加密的訊息.
226 liveuser 11390
										$conf["webSock::encode"]["text"]=$talkback;
3 liveuser 11391
										#可省略參數:
11392
										#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
11393
										#$conf["payloadIsBin"]="false";
11394
										#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
11395
										#$conf["ping"]="false";
11396
										#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
11397
										#$conf["pong"]="false";
11398
										#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
11399
										#$conf["frames"]=array();
11400
										#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
11401
										#$conf["mask"]="false";
11402
										#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
11403
										#$conf["debug"]="false";
11404
										#參考資料:
11405
										#無.
11406
										#備註:
11407
										#目前$conf["text"]長度超過125會出錯.
11408
										$talkback=webSock::encode($conf["webSock::encode"]);
11409
										unset($conf["webSock::encode"]);
226 liveuser 11410
 
3 liveuser 11411
										#如果執行失敗
11412
										if($talkback["status"]==="false"){
226 liveuser 11413
 
3 liveuser 11414
											#印出結果
11415
											var_dump($talkback);
226 liveuser 11416
 
3 liveuser 11417
											#結束執行
11418
											exit;
226 liveuser 11419
 
3 liveuser 11420
											}#if end
226 liveuser 11421
 
3 liveuser 11422
										#debug
11423
										#var_dump(__LINE__,$talkback);
226 liveuser 11424
 
3 liveuser 11425
										}#if end
226 liveuser 11426
 
3 liveuser 11427
									}#if end
226 liveuser 11428
 
3 liveuser 11429
								}#if end
226 liveuser 11430
 
3 liveuser 11431
							#反之不為 web socket 訊息
11432
							else{
226 liveuser 11433
 
3 liveuser 11434
								#儲存成只有一個訊息
11435
								$talkback["content"][]=$talkback;
226 liveuser 11436
 
3 liveuser 11437
								}#else
226 liveuser 11438
 
3 liveuser 11439
							#針對每個訊息的分段
11440
							foreach($talkback["content"] as $msg){
226 liveuser 11441
 
3 liveuser 11442
								#回傳訊息
11443
								$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 11444
 
3 liveuser 11445
								#debug
11446
								#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 11447
 
3 liveuser 11448
								}#foreach end
226 liveuser 11449
 
3 liveuser 11450
							#跳到下一輪
11451
							continue;
226 liveuser 11452
 
3 liveuser 11453
							}#if end
226 liveuser 11454
 
3 liveuser 11455
						#如果收到的$buf長度大於 "talkTo:"
11456
						if(strlen($buf)>strlen("talkTo:")){
226 liveuser 11457
 
3 liveuser 11458
							#如果收到開頭為 "talkTo:"
11459
							#涵式說明:
11460
							#取得符合特定字首與字尾的字串
11461
							#回傳的結果:
11462
							#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
11463
							#$result["function"],當前執行的函數名稱.
11464
							#$result["error"],錯誤訊息陣列.
11465
							#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
11466
							#$result["returnString"],爲符合字首條件的字串內容。
11467
							#必填參數:
11468
							#$conf["checkString"],字串,要檢查的字串.
11469
							$conf["search::getMeetConditionsString"]["checkString"]=$buf;
11470
							#可省略參數:
11471
							#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
11472
							$conf["search::getMeetConditionsString"]["frontWord"]="talkTo:";
11473
							#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
11474
							#$conf["tailWord"]="";
11475
							#參考資料:
11476
							#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
11477
							$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
11478
							unset($conf["search::getMeetConditionsString"]);
226 liveuser 11479
 
3 liveuser 11480
							#如果選找前置字串 "talkTo:" 失敗
11481
							if($getMeetConditionsString["status"]==="false"){
226 liveuser 11482
 
3 liveuser 11483
								#設置執行失敗
11484
								$result["status"]="false";
226 liveuser 11485
 
3 liveuser 11486
								#設置執行錯誤訊息
11487
								$result["error"]=$getMeetConditionsString;
226 liveuser 11488
 
3 liveuser 11489
								#回傳結果
11490
								return $result;
226 liveuser 11491
 
3 liveuser 11492
								}#if end
226 liveuser 11493
 
3 liveuser 11494
							#如果存在 "talkTo:" 前置字串
11495
							if($getMeetConditionsString["founded"]==="true"){
226 liveuser 11496
 
66 liveuser 11497
								#如果尚未認證
11498
								if($connections[$conIndex]["auth"]==="false"){
226 liveuser 11499
 
66 liveuser 11500
									#設置要回傳的訊息
11501
									$talkback=json_encode("permission denied");
226 liveuser 11502
 
66 liveuser 11503
									#如果是 ws 模式
11504
									if($conf["wsMode"]==="true"){
226 liveuser 11505
 
66 liveuser 11506
										#如果已經 handshake 過
11507
										if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 11508
 
11509
											#如果要 unmask
66 liveuser 11510
											if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 11511
 
66 liveuser 11512
												#函式說明:
226 liveuser 11513
												#加密 handshake 後要傳送的訊息
66 liveuser 11514
												#回傳結果:
11515
												#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11516
												#$result["error"],執行不正常結束的錯訊息陣列.
11517
												#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
11518
												#$result["argu"],陣列,使用的參數.
11519
												#必填參數:
11520
												#$conf["text"],字串,要加密的訊息.
226 liveuser 11521
												$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 11522
												#可省略參數:
11523
												#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
11524
												#$conf["payloadIsBin"]="false";
11525
												#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
11526
												#$conf["ping"]="false";
11527
												#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
11528
												#$conf["pong"]="false";
11529
												#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
11530
												#$conf["frames"]=array();
11531
												#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
11532
												#$conf["mask"]="false";
11533
												#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
11534
												#$conf["debug"]="false";
11535
												#參考資料:
11536
												#無.
11537
												#備註:
11538
												#目前$conf["text"]長度超過125會出錯.
11539
												$talkback=webSock::encode($conf["webSock::encode"]);
11540
												unset($conf["webSock::encode"]);
226 liveuser 11541
 
66 liveuser 11542
												#如果執行失敗
11543
												if($talkback["status"]==="false"){
226 liveuser 11544
 
66 liveuser 11545
													#印出結果
11546
													var_dump($talkback);
226 liveuser 11547
 
66 liveuser 11548
													#結束執行
11549
													exit;
226 liveuser 11550
 
66 liveuser 11551
													}#if end
226 liveuser 11552
 
66 liveuser 11553
												#debug
11554
												#var_dump(__LINE__,$talkback);
226 liveuser 11555
 
66 liveuser 11556
												}#if end
226 liveuser 11557
 
66 liveuser 11558
											}#if end
226 liveuser 11559
 
66 liveuser 11560
										}#if end
226 liveuser 11561
 
66 liveuser 11562
									#反之不為 web socket 訊息
11563
									else{
226 liveuser 11564
 
66 liveuser 11565
										#儲存成只有一個訊息
11566
										$talkback["content"][]=$talkback;
226 liveuser 11567
 
66 liveuser 11568
										}#else
226 liveuser 11569
 
66 liveuser 11570
									#針對每個訊息的分段
11571
									foreach($talkback["content"] as $msg){
226 liveuser 11572
 
66 liveuser 11573
										#回傳訊息
11574
										$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 11575
 
66 liveuser 11576
										#debug
11577
										#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 11578
 
66 liveuser 11579
										}#foreach end
226 liveuser 11580
 
66 liveuser 11581
									#跳到下一輪
11582
									continue;
226 liveuser 11583
 
66 liveuser 11584
									}#if end
226 liveuser 11585
 
3 liveuser 11586
								#用 "talkTo:" 分割 $buf
11587
								#涵式說明:
11588
								#將固定格式的字串分開,並回傳分開的結果。
11589
								#回傳結果:
11590
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11591
								#$result["error"],錯誤訊息陣列
11592
								#$result["function"],當前執行的函數名稱.
11593
								#$result["oriStr"],要分割的原始字串內容
11594
								#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
11595
								#$result["dataCounts"],爲總共分成幾段
11596
								#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
11597
								#必填的參數:
11598
								$conf["stringProcess::spiltString"]["stringIn"]=$buf;#要處理的字串。
11599
								$conf["stringProcess::spiltString"]["spiltSymbol"]="talkTo:";#爲以哪個符號作爲分割
11600
								#可省略參數:
11601
								#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
11602
								$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
11603
								$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
11604
								unset($conf["stringProcess::spiltString"]);
226 liveuser 11605
 
3 liveuser 11606
								#如果分割字串失敗
11607
								if($spiltString["status"]==="false"){
226 liveuser 11608
 
3 liveuser 11609
									#設置執行失敗
11610
									$result["status"]="false";
226 liveuser 11611
 
3 liveuser 11612
									#設置執行錯誤訊息
11613
									$result["error"]=$spiltString;
226 liveuser 11614
 
3 liveuser 11615
									#回傳結果
11616
									return $result;
226 liveuser 11617
 
3 liveuser 11618
									}#if end
226 liveuser 11619
 
3 liveuser 11620
								#如果剛好分割出一筆資料
11621
								if($spiltString["dataCounts"]===1){
226 liveuser 11622
 
3 liveuser 11623
									#取得自己的id
11624
									$myId=$connections[$conIndex]["id"];
226 liveuser 11625
 
3 liveuser 11626
									#取得講話對象的id
11627
									$toId=$spiltString["dataArray"][0];
226 liveuser 11628
 
3 liveuser 11629
									#設置對象不存在的識別
11630
									$targetExist=false;
226 liveuser 11631
 
3 liveuser 11632
									#設置通話對象的key
11633
									$targetKey="";
226 liveuser 11634
 
3 liveuser 11635
									#取得除了自己的id以外的所有連線
11636
									foreach($connections as $index=>$talkInfo){
226 liveuser 11637
 
3 liveuser 11638
										#除了自己的id
11639
										if($talkInfo["id"]!==$myId){
226 liveuser 11640
 
3 liveuser 11641
											#如果存在要對話的對象
11642
											if($talkInfo["id"]===$toId){
226 liveuser 11643
 
3 liveuser 11644
												#設置對象存在的識別
11645
												$targetExist=true;
226 liveuser 11646
 
3 liveuser 11647
												#通話對象的key
11648
												$targetKey=$index;
226 liveuser 11649
 
3 liveuser 11650
												}#if end
226 liveuser 11651
 
3 liveuser 11652
											}#if end
226 liveuser 11653
 
3 liveuser 11654
										}#for each end
11655
 
11656
									#如果通話對象存在
11657
									if($targetExist){
226 liveuser 11658
 
3 liveuser 11659
										#保存自己的通話對象
11660
										$connections[$conIndex]["talkTo"][]=$toId;
226 liveuser 11661
 
3 liveuser 11662
										#設置要給自己看的訊息
11663
										$talkback="您與 ".$toId." 展開對話";
226 liveuser 11664
 
3 liveuser 11665
										#json encode 要給自己看的訊息
11666
										$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 11667
 
3 liveuser 11668
										#如果是 ws 模式
11669
										if($conf["wsMode"]==="true"){
226 liveuser 11670
 
3 liveuser 11671
											#如果已經 handshake 過
11672
											if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 11673
 
11674
												#如果要 unmask
3 liveuser 11675
												if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 11676
 
3 liveuser 11677
													#函式說明:
226 liveuser 11678
													#加密 handshake 後要傳送的訊息
3 liveuser 11679
													#回傳結果:
11680
													#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11681
													#$result["error"],執行不正常結束的錯訊息陣列.
11682
													#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
11683
													#$result["argu"],陣列,使用的參數.
11684
													#必填參數:
11685
													#$conf["text"],字串,要加密的訊息.
226 liveuser 11686
													$conf["webSock::encode"]["text"]=$talkback;
3 liveuser 11687
													#可省略參數:
11688
													#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
11689
													#$conf["payloadIsBin"]="false";
11690
													#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
11691
													#$conf["ping"]="false";
11692
													#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
11693
													#$conf["pong"]="false";
11694
													#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
11695
													#$conf["frames"]=array();
11696
													#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
11697
													#$conf["mask"]="false";
11698
													#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
11699
													#$conf["debug"]="false";
11700
													#參考資料:
11701
													#無.
11702
													#備註:
11703
													#目前$conf["text"]長度超過125會出錯.
11704
													$talkback=webSock::encode($conf["webSock::encode"]);
11705
													unset($conf["webSock::encode"]);
226 liveuser 11706
 
3 liveuser 11707
													#如果執行失敗
11708
													if($talkback["status"]==="false"){
226 liveuser 11709
 
3 liveuser 11710
														#印出結果
11711
														var_dump($talkback);
226 liveuser 11712
 
3 liveuser 11713
														#結束執行
11714
														exit;
226 liveuser 11715
 
3 liveuser 11716
														}#if end
226 liveuser 11717
 
3 liveuser 11718
													#debug
11719
													#var_dump(__LINE__,$talkback);
226 liveuser 11720
 
3 liveuser 11721
													}#if end
226 liveuser 11722
 
3 liveuser 11723
												}#if end
226 liveuser 11724
 
3 liveuser 11725
											}#if end
226 liveuser 11726
 
3 liveuser 11727
										#反之不為 web socket 訊息
11728
										else{
226 liveuser 11729
 
3 liveuser 11730
											#儲存成只有一個訊息
11731
											$talkback["content"][]=$talkback;
226 liveuser 11732
 
3 liveuser 11733
											}#else
226 liveuser 11734
 
3 liveuser 11735
										#針對每個訊息的分段
11736
										foreach($talkback["content"] as $msg){
226 liveuser 11737
 
3 liveuser 11738
											#回傳訊息
11739
											$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 11740
 
3 liveuser 11741
											#debug
11742
											#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 11743
 
3 liveuser 11744
											}#foreach end
226 liveuser 11745
 
3 liveuser 11746
										#讓對方可以跟自己對話
11747
										$connections[$targetKey]["talkTo"][]=$myId;
226 liveuser 11748
 
3 liveuser 11749
										#設置要給對方看的訊息
11750
										$talkback=$connections[$conIndex]["id"]." 與您展開對話";
226 liveuser 11751
 
3 liveuser 11752
										#json encode 設置要給對方看的訊息
11753
										$talkback=json_encode($talkback);
226 liveuser 11754
 
3 liveuser 11755
										#如果是 ws 模式
11756
										if($conf["wsMode"]==="true"){
226 liveuser 11757
 
3 liveuser 11758
											#如果已經 handshake 過
11759
											if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 11760
 
11761
												#如果要 unmask
3 liveuser 11762
												if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 11763
 
3 liveuser 11764
													#函式說明:
226 liveuser 11765
													#加密 handshake 後要傳送的訊息
3 liveuser 11766
													#回傳結果:
11767
													#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11768
													#$result["error"],執行不正常結束的錯訊息陣列.
11769
													#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
11770
													#$result["argu"],陣列,使用的參數.
11771
													#必填參數:
11772
													#$conf["text"],字串,要加密的訊息.
226 liveuser 11773
													$conf["webSock::encode"]["text"]=$talkback;
3 liveuser 11774
													#可省略參數:
11775
													#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
11776
													#$conf["payloadIsBin"]="false";
11777
													#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
11778
													#$conf["ping"]="false";
11779
													#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
11780
													#$conf["pong"]="false";
11781
													#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
11782
													#$conf["frames"]=array();
11783
													#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
11784
													#$conf["mask"]="false";
11785
													#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
11786
													#$conf["debug"]="false";
11787
													#參考資料:
11788
													#無.
11789
													#備註:
11790
													#目前$conf["text"]長度超過125會出錯.
11791
													$talkback=webSock::encode($conf["webSock::encode"]);
11792
													unset($conf["webSock::encode"]);
226 liveuser 11793
 
3 liveuser 11794
													#如果執行失敗
11795
													if($talkback["status"]==="false"){
226 liveuser 11796
 
3 liveuser 11797
														#印出結果
11798
														var_dump($talkback);
226 liveuser 11799
 
3 liveuser 11800
														#結束執行
11801
														exit;
226 liveuser 11802
 
3 liveuser 11803
														}#if end
226 liveuser 11804
 
3 liveuser 11805
													#debug
11806
													#var_dump(__LINE__,$talkback);
226 liveuser 11807
 
3 liveuser 11808
													}#if end
226 liveuser 11809
 
3 liveuser 11810
												}#if end
226 liveuser 11811
 
3 liveuser 11812
											}#if end
226 liveuser 11813
 
3 liveuser 11814
										#反之不為 web socket 訊息
11815
										else{
226 liveuser 11816
 
3 liveuser 11817
											#儲存成只有一個訊息
11818
											$talkback["content"][]=$talkback;
226 liveuser 11819
 
3 liveuser 11820
											}#else
226 liveuser 11821
 
3 liveuser 11822
										#針對每個訊息的分段
11823
										foreach($talkback["content"] as $msg){
226 liveuser 11824
 
3 liveuser 11825
											#給對方看的訊息
11826
											$socket_write=socket_write($connections[$targetKey]["connect"], $msg, strlen($msg));
226 liveuser 11827
 
3 liveuser 11828
											#debug
11829
											#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 11830
 
3 liveuser 11831
											}#foreach end
226 liveuser 11832
 
3 liveuser 11833
										#換一個連線
11834
										continue;
226 liveuser 11835
 
3 liveuser 11836
										}#if end
226 liveuser 11837
 
3 liveuser 11838
									}#if end
226 liveuser 11839
 
3 liveuser 11840
								}#if end
226 liveuser 11841
 
3 liveuser 11842
							}#if end
226 liveuser 11843
 
66 liveuser 11844
						*/
226 liveuser 11845
 
66 liveuser 11846
						#如果收到的訊息是 runPhpWhenIdle: 開頭
11847
						if(strpos($buf,"runPhpWhenIdle:")===0){
226 liveuser 11848
 
66 liveuser 11849
							#如果尚未認證
11850
							if($connections[$conIndex]["auth"]==="false"){
226 liveuser 11851
 
66 liveuser 11852
								#設置要回傳的訊息
11853
								$talkback=json_encode("permission denied");
226 liveuser 11854
 
66 liveuser 11855
								#如果是 ws 模式
11856
								if($conf["wsMode"]==="true"){
226 liveuser 11857
 
66 liveuser 11858
									#如果已經 handshake 過
11859
									if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 11860
 
11861
										#如果要 unmask
66 liveuser 11862
										if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 11863
 
66 liveuser 11864
											#函式說明:
226 liveuser 11865
											#加密 handshake 後要傳送的訊息
66 liveuser 11866
											#回傳結果:
11867
											#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11868
											#$result["error"],執行不正常結束的錯訊息陣列.
11869
											#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
11870
											#$result["argu"],陣列,使用的參數.
11871
											#必填參數:
11872
											#$conf["text"],字串,要加密的訊息.
226 liveuser 11873
											$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 11874
											#可省略參數:
11875
											#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
11876
											#$conf["payloadIsBin"]="false";
11877
											#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
11878
											#$conf["ping"]="false";
11879
											#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
11880
											#$conf["pong"]="false";
11881
											#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
11882
											#$conf["frames"]=array();
11883
											#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
11884
											#$conf["mask"]="false";
11885
											#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
11886
											#$conf["debug"]="false";
11887
											#參考資料:
11888
											#無.
11889
											#備註:
11890
											#目前$conf["text"]長度超過125會出錯.
11891
											$talkback=webSock::encode($conf["webSock::encode"]);
11892
											unset($conf["webSock::encode"]);
226 liveuser 11893
 
66 liveuser 11894
											#如果執行失敗
11895
											if($talkback["status"]==="false"){
226 liveuser 11896
 
66 liveuser 11897
												#印出結果
11898
												var_dump($talkback);
226 liveuser 11899
 
66 liveuser 11900
												#結束執行
11901
												exit;
226 liveuser 11902
 
66 liveuser 11903
												}#if end
226 liveuser 11904
 
66 liveuser 11905
											#debug
11906
											#var_dump(__LINE__,$talkback);
226 liveuser 11907
 
66 liveuser 11908
											}#if end
226 liveuser 11909
 
66 liveuser 11910
										}#if end
226 liveuser 11911
 
66 liveuser 11912
									}#if end
226 liveuser 11913
 
66 liveuser 11914
								#反之不為 web socket 訊息
11915
								else{
226 liveuser 11916
 
66 liveuser 11917
									#儲存成只有一個訊息
11918
									$talkback["content"][]=$talkback;
226 liveuser 11919
 
66 liveuser 11920
									}#else
226 liveuser 11921
 
66 liveuser 11922
								#針對每個訊息的分段
11923
								foreach($talkback["content"] as $msg){
226 liveuser 11924
 
66 liveuser 11925
									#回傳訊息
11926
									$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 11927
 
66 liveuser 11928
									#debug
11929
									#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 11930
 
66 liveuser 11931
									}#foreach end
226 liveuser 11932
 
66 liveuser 11933
								#跳到下一輪
11934
								continue;
226 liveuser 11935
 
66 liveuser 11936
								}#if end
226 liveuser 11937
 
66 liveuser 11938
							#剔除開頭的 "runPhpWhenIdle:"
11939
							#函式說明:
11940
							#將字串特定關鍵字與其前面的內容剔除
11941
							#回傳結果:
11942
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
11943
							#$result["error"],錯誤訊息陣列.
11944
							#$result["warning"],警告訊息鎮列.
11945
							#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
11946
							#$result["function"],當前執行的函數名稱.
11947
							#$result["argu"],使用的參數.
11948
							#$result["oriStr"],要處理的原始字串內容.
11949
							#$result["content"],處理好的的字串內容.
11950
							#$result["deleted"],被移除的內容.
11951
							#必填參數:
11952
							#$conf["stringIn"],字串,要處理的字串.
11953
							$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$buf;
11954
							#$conf["keyWord"],字串,特定字串.
11955
							$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="runPhpWhenIdle:";
11956
							#可省略參數:
11957
							#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
11958
							#$conf["recursive"]="true";
11959
							#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
11960
							#$conf["lastResult"]=$delStrBeforeKeyWord;
11961
							#參考資料:
11962
							#無.
11963
							#備註:
11964
							#無.
11965
							$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
11966
							unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 11967
 
66 liveuser 11968
							#如果執行失敗
11969
							if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 11970
 
66 liveuser 11971
								#印出結果
11972
								var_dump($delStrBeforeKeyWord);
226 liveuser 11973
 
66 liveuser 11974
								#結束執行
11975
								exit;
226 liveuser 11976
 
66 liveuser 11977
								}#if end
226 liveuser 11978
 
66 liveuser 11979
							#設置要執行的php程式
11980
							$php2runWhenIdle[]=$delStrBeforeKeyWord["content"];
226 liveuser 11981
 
66 liveuser 11982
							#跳到下一輪
11983
							continue;
226 liveuser 11984
 
66 liveuser 11985
							}#if end
226 liveuser 11986
 
66 liveuser 11987
						/* 舊的寫法
226 liveuser 11988
 
3 liveuser 11989
						#如果收到的是 quit
11990
						if ($buf === 'quit' ) {
226 liveuser 11991
 
3 liveuser 11992
							#設置要回傳的訊息
11993
							$talkback="結束與 server 的連線";
226 liveuser 11994
 
3 liveuser 11995
							#json encode 要回傳的訊息
11996
							$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 11997
 
3 liveuser 11998
							#如果是 ws 模式
11999
							if($conf["wsMode"]==="true"){
226 liveuser 12000
 
3 liveuser 12001
								#如果已經 handshake 過
12002
								if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 12003
 
12004
									#如果要 unmask
3 liveuser 12005
									if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 12006
 
3 liveuser 12007
										#函式說明:
226 liveuser 12008
										#加密 handshake 後要傳送的訊息
3 liveuser 12009
										#回傳結果:
12010
										#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12011
										#$result["error"],執行不正常結束的錯訊息陣列.
12012
										#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
12013
										#$result["argu"],陣列,使用的參數.
12014
										#必填參數:
12015
										#$conf["text"],字串,要加密的訊息.
226 liveuser 12016
										$conf["webSock::encode"]["text"]=$talkback;
3 liveuser 12017
										#可省略參數:
12018
										#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
12019
										#$conf["payloadIsBin"]="false";
12020
										#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
12021
										#$conf["ping"]="false";
12022
										#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
12023
										#$conf["pong"]="false";
12024
										#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
12025
										#$conf["frames"]=array();
12026
										#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
12027
										#$conf["mask"]="false";
12028
										#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
12029
										#$conf["debug"]="false";
12030
										#參考資料:
12031
										#無.
12032
										#備註:
12033
										#目前$conf["text"]長度超過125會出錯.
12034
										$talkback=webSock::encode($conf["webSock::encode"]);
12035
										unset($conf["webSock::encode"]);
226 liveuser 12036
 
3 liveuser 12037
										#如果執行失敗
12038
										if($talkback["status"]==="false"){
226 liveuser 12039
 
3 liveuser 12040
											#印出結果
12041
											var_dump($talkback);
226 liveuser 12042
 
3 liveuser 12043
											#結束執行
12044
											exit;
226 liveuser 12045
 
3 liveuser 12046
											}#if end
226 liveuser 12047
 
3 liveuser 12048
										#debug
12049
										#var_dump(__LINE__,$talkback);
226 liveuser 12050
 
3 liveuser 12051
										}#if end
226 liveuser 12052
 
3 liveuser 12053
									}#if end
226 liveuser 12054
 
3 liveuser 12055
								}#if end
226 liveuser 12056
 
3 liveuser 12057
							#反之不為 web socket 訊息
12058
							else{
226 liveuser 12059
 
3 liveuser 12060
								#儲存成只有一個訊息
12061
								$talkback["content"][]=$talkback;
226 liveuser 12062
 
3 liveuser 12063
								}#else
226 liveuser 12064
 
3 liveuser 12065
							#針對每個訊息的分段
12066
							foreach($talkback["content"] as $msg){
226 liveuser 12067
 
3 liveuser 12068
								#回傳訊息
12069
								$socket_write=socket_write($con["connect"], $msg, strlen($msg));
226 liveuser 12070
 
3 liveuser 12071
								#debug
12072
								#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 12073
 
3 liveuser 12074
								}#foreach end
226 liveuser 12075
 
12076
							#關閉被 client 的連線
3 liveuser 12077
							socket_close($con["connect"]);
226 liveuser 12078
 
3 liveuser 12079
							#清理連線的陣列
12080
							unset($connections[$conIndex]);
226 liveuser 12081
 
3 liveuser 12082
							#跳到下一輪
12083
							continue;
226 liveuser 12084
 
3 liveuser 12085
							}#if end
226 liveuser 12086
 
66 liveuser 12087
						*/
226 liveuser 12088
 
66 liveuser 12089
						/* 舊的寫法
226 liveuser 12090
 
12091
						#如果收到的是 shutdown
3 liveuser 12092
						if ($buf === 'shutdown') {
226 liveuser 12093
 
66 liveuser 12094
							#如果尚未認證
12095
							if($connections[$conIndex]["auth"]==="false"){
226 liveuser 12096
 
66 liveuser 12097
								#設置要回傳的訊息
12098
								$talkback=json_encode("permission denied");
226 liveuser 12099
 
66 liveuser 12100
								#如果是 ws 模式
12101
								if($conf["wsMode"]==="true"){
226 liveuser 12102
 
66 liveuser 12103
									#如果已經 handshake 過
12104
									if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 12105
 
12106
										#如果要 unmask
66 liveuser 12107
										if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 12108
 
66 liveuser 12109
											#函式說明:
226 liveuser 12110
											#加密 handshake 後要傳送的訊息
66 liveuser 12111
											#回傳結果:
12112
											#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12113
											#$result["error"],執行不正常結束的錯訊息陣列.
12114
											#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
12115
											#$result["argu"],陣列,使用的參數.
12116
											#必填參數:
12117
											#$conf["text"],字串,要加密的訊息.
226 liveuser 12118
											$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 12119
											#可省略參數:
12120
											#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
12121
											#$conf["payloadIsBin"]="false";
12122
											#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
12123
											#$conf["ping"]="false";
12124
											#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
12125
											#$conf["pong"]="false";
12126
											#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
12127
											#$conf["frames"]=array();
12128
											#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
12129
											#$conf["mask"]="false";
12130
											#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
12131
											#$conf["debug"]="false";
12132
											#參考資料:
12133
											#無.
12134
											#備註:
12135
											#目前$conf["text"]長度超過125會出錯.
12136
											$talkback=webSock::encode($conf["webSock::encode"]);
12137
											unset($conf["webSock::encode"]);
226 liveuser 12138
 
66 liveuser 12139
											#如果執行失敗
12140
											if($talkback["status"]==="false"){
226 liveuser 12141
 
66 liveuser 12142
												#印出結果
12143
												var_dump($talkback);
226 liveuser 12144
 
66 liveuser 12145
												#結束執行
12146
												exit;
226 liveuser 12147
 
66 liveuser 12148
												}#if end
226 liveuser 12149
 
66 liveuser 12150
											#debug
12151
											#var_dump(__LINE__,$talkback);
226 liveuser 12152
 
66 liveuser 12153
											}#if end
226 liveuser 12154
 
66 liveuser 12155
										}#if end
226 liveuser 12156
 
66 liveuser 12157
									}#if end
226 liveuser 12158
 
66 liveuser 12159
								#反之不為 web socket 訊息
12160
								else{
226 liveuser 12161
 
66 liveuser 12162
									#儲存成只有一個訊息
12163
									$talkback["content"][]=$talkback;
226 liveuser 12164
 
66 liveuser 12165
									}#else
226 liveuser 12166
 
66 liveuser 12167
								#針對每個訊息的分段
12168
								foreach($talkback["content"] as $msg){
226 liveuser 12169
 
66 liveuser 12170
									#回傳訊息
12171
									$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 12172
 
66 liveuser 12173
									#debug
12174
									#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 12175
 
66 liveuser 12176
									}#foreach end
226 liveuser 12177
 
66 liveuser 12178
								#跳到下一輪
12179
								continue;
226 liveuser 12180
 
66 liveuser 12181
								}#if end
226 liveuser 12182
 
3 liveuser 12183
							#設置要回傳的訊息
12184
							$talkback="Server 即將關閉";
226 liveuser 12185
 
3 liveuser 12186
							#json encode 要回傳的訊息
12187
							$talkback=json_encode($talkback);
226 liveuser 12188
 
3 liveuser 12189
							#如果是 ws 模式
12190
							if($conf["wsMode"]==="true"){
226 liveuser 12191
 
3 liveuser 12192
								#如果已經 handshake 過
12193
								if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 12194
 
12195
									#如果要 unmask
3 liveuser 12196
									if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 12197
 
3 liveuser 12198
										#函式說明:
226 liveuser 12199
										#加密 handshake 後要傳送的訊息
3 liveuser 12200
										#回傳結果:
12201
										#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12202
										#$result["error"],執行不正常結束的錯訊息陣列.
12203
										#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
12204
										#$result["argu"],陣列,使用的參數.
12205
										#必填參數:
12206
										#$conf["text"],字串,要加密的訊息.
226 liveuser 12207
										$conf["webSock::encode"]["text"]=$talkback;
3 liveuser 12208
										#可省略參數:
12209
										#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
12210
										#$conf["payloadIsBin"]="false";
12211
										#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
12212
										#$conf["ping"]="false";
12213
										#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
12214
										#$conf["pong"]="false";
12215
										#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
12216
										#$conf["frames"]=array();
12217
										#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
12218
										#$conf["mask"]="false";
12219
										#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
12220
										#$conf["debug"]="false";
12221
										#參考資料:
12222
										#無.
12223
										#備註:
12224
										#無.
12225
										$talkback=webSock::encode($conf["webSock::encode"]);
12226
										unset($conf["webSock::encode"]);
226 liveuser 12227
 
3 liveuser 12228
										#如果執行失敗
12229
										if($talkback["status"]==="false"){
226 liveuser 12230
 
3 liveuser 12231
											#印出結果
12232
											var_dump($talkback);
226 liveuser 12233
 
3 liveuser 12234
											#結束執行
12235
											exit;
226 liveuser 12236
 
3 liveuser 12237
											}#if end
226 liveuser 12238
 
3 liveuser 12239
										#debug
12240
										#var_dump(__LINE__,$talkback);
226 liveuser 12241
 
3 liveuser 12242
										}#if end
226 liveuser 12243
 
3 liveuser 12244
									}#if end
226 liveuser 12245
 
3 liveuser 12246
								}#if end
226 liveuser 12247
 
3 liveuser 12248
							#反之不為 web socket 訊息
12249
							else{
226 liveuser 12250
 
3 liveuser 12251
								#儲存成只有一個訊息
12252
								$talkback["content"][]=$talkback;
226 liveuser 12253
 
3 liveuser 12254
								}#else
226 liveuser 12255
 
3 liveuser 12256
							#針對每個訊息的分段
12257
							foreach($talkback["content"] as $msg){
226 liveuser 12258
 
3 liveuser 12259
								#回傳訊息
12260
								$socket_write=socket_write($con["connect"], $msg, strlen($msg));
226 liveuser 12261
 
3 liveuser 12262
								#debug
12263
								#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 12264
 
3 liveuser 12265
								}#foreach end
226 liveuser 12266
 
3 liveuser 12267
							#關閉用戶的連線
12268
							socket_close($con["connect"]);
226 liveuser 12269
 
3 liveuser 12270
							#跳到最外層,結束webSocket server
12271
							break 2;
226 liveuser 12272
 
3 liveuser 12273
							}#if end
226 liveuser 12274
 
66 liveuser 12275
						*/
226 liveuser 12276
 
66 liveuser 12277
						/* 舊的寫法
226 liveuser 12278
 
66 liveuser 12279
						#如果收到的訊息為"auth:"開頭
12280
						if(strpos($buf,"auth:")){
226 liveuser 12281
 
66 liveuser 12282
							#剔除 "auth:" 前面的內容
12283
							#函式說明:
12284
							#將字串特定關鍵字與其前面的內容剔除
12285
							#回傳結果:
12286
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12287
							#$result["error"],錯誤訊息陣列.
12288
							#$result["warning"],警告訊息鎮列.
12289
							#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
12290
							#$result["function"],當前執行的函數名稱.
12291
							#$result["argu"],使用的參數.
12292
							#$result["oriStr"],要處理的原始字串內容.
12293
							#$result["content"],處理好的的字串內容.
12294
							#$result["deleted"],被移除的內容.
12295
							#必填參數:
12296
							#$conf["stringIn"],字串,要處理的字串.
12297
							$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$buf;
12298
							#$conf["keyWord"],字串,特定字串.
12299
							$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="auth:";
12300
							#可省略參數:
12301
							#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
12302
							#$conf["recursive"]="true";
12303
							#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
12304
							#$conf["lastResult"]=$delStrBeforeKeyWord;
12305
							#參考資料:
12306
							#無.
12307
							#備註:
12308
							#無.
12309
							$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
12310
							unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 12311
 
66 liveuser 12312
							#如果執行失敗
12313
							if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 12314
 
66 liveuser 12315
								#印出結果
12316
								var_dump($delStrBeforeKeyWord);
226 liveuser 12317
 
66 liveuser 12318
								#結束執行
12319
								exit;
226 liveuser 12320
 
66 liveuser 12321
								}#if end
226 liveuser 12322
 
66 liveuser 12323
							#還原編碼
12324
							#$delStrBeforeKeyWord["content"];
226 liveuser 12325
 
66 liveuser 12326
							#gpg解密
12327
							#...
226 liveuser 12328
 
66 liveuser 12329
							#檢查賬號密碼
12330
							#...
226 liveuser 12331
 
66 liveuser 12332
							}#if end
226 liveuser 12333
 
66 liveuser 12334
						*/
226 liveuser 12335
 
66 liveuser 12336
						#以下為其他收到的訊息內容
226 liveuser 12337
 
66 liveuser 12338
						/* 舊的寫法
226 liveuser 12339
 
66 liveuser 12340
						#如果尚未認證
12341
						if($connections[$conIndex]["auth"]==="false"){
226 liveuser 12342
 
66 liveuser 12343
							#設置要回傳的訊息
12344
							$talkback=json_encode("permission denied");
226 liveuser 12345
 
66 liveuser 12346
							#如果是 ws 模式
12347
							if($conf["wsMode"]==="true"){
226 liveuser 12348
 
66 liveuser 12349
								#如果已經 handshake 過
12350
								if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 12351
 
12352
									#如果要 unmask
66 liveuser 12353
									if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 12354
 
66 liveuser 12355
										#函式說明:
226 liveuser 12356
										#加密 handshake 後要傳送的訊息
66 liveuser 12357
										#回傳結果:
12358
										#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12359
										#$result["error"],執行不正常結束的錯訊息陣列.
12360
										#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
12361
										#$result["argu"],陣列,使用的參數.
12362
										#必填參數:
12363
										#$conf["text"],字串,要加密的訊息.
226 liveuser 12364
										$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 12365
										#可省略參數:
12366
										#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
12367
										#$conf["payloadIsBin"]="false";
12368
										#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
12369
										#$conf["ping"]="false";
12370
										#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
12371
										#$conf["pong"]="false";
12372
										#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
12373
										#$conf["frames"]=array();
12374
										#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
12375
										#$conf["mask"]="false";
12376
										#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
12377
										#$conf["debug"]="false";
12378
										#參考資料:
12379
										#無.
12380
										#備註:
12381
										#目前$conf["text"]長度超過125會出錯.
12382
										$talkback=webSock::encode($conf["webSock::encode"]);
12383
										unset($conf["webSock::encode"]);
226 liveuser 12384
 
66 liveuser 12385
										#如果執行失敗
12386
										if($talkback["status"]==="false"){
226 liveuser 12387
 
66 liveuser 12388
											#印出結果
12389
											var_dump($talkback);
226 liveuser 12390
 
66 liveuser 12391
											#結束執行
12392
											exit;
226 liveuser 12393
 
66 liveuser 12394
											}#if end
226 liveuser 12395
 
66 liveuser 12396
										#debug
12397
										#var_dump(__LINE__,$talkback);
226 liveuser 12398
 
66 liveuser 12399
										}#if end
226 liveuser 12400
 
66 liveuser 12401
									}#if end
226 liveuser 12402
 
66 liveuser 12403
								}#if end
226 liveuser 12404
 
66 liveuser 12405
							#反之不為 web socket 訊息
12406
							else{
226 liveuser 12407
 
66 liveuser 12408
								#儲存成只有一個訊息
12409
								$talkback["content"][]=$talkback;
226 liveuser 12410
 
66 liveuser 12411
								}#else
226 liveuser 12412
 
66 liveuser 12413
							#針對每個訊息的分段
12414
							foreach($talkback["content"] as $msg){
226 liveuser 12415
 
66 liveuser 12416
								#回傳訊息
12417
								$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 12418
 
66 liveuser 12419
								#debug
12420
								#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 12421
 
66 liveuser 12422
								}#foreach end
226 liveuser 12423
 
66 liveuser 12424
							#跳到下一輪
12425
							continue;
226 liveuser 12426
 
66 liveuser 12427
							}#if end
226 liveuser 12428
 
66 liveuser 12429
						*/
226 liveuser 12430
 
3 liveuser 12431
						#如果有指定的外掛函式
12432
						if(isset($conf["processFuncs"])){
226 liveuser 12433
 
3 liveuser 12434
							#針對每個用來處理輸入字串的函式
12435
							foreach($conf["processFuncs"] as $proFunc){
226 liveuser 12436
 
3 liveuser 12437
								#debug
12438
								#var_dump(__LINE__,$proFunc);
226 liveuser 12439
 
66 liveuser 12440
								#函式說明:
12441
								#提供webSock::nativeSocketTcpIpServer用於接受檢查權限的功能.
12442
								#回傳結果:
12443
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12444
								#$result["error"],執行不正常結束的錯訊息陣列.
12445
								#$result["argu"],陣列,使用的參數.
12446
								#必填參數:
12447
								#$conf["data"],字串,收到的bin2hex編碼後果gpg加密過後的json格式資料,必填的key有"randomStr","username","password".
12448
								$conf["webSocket::checkAuth"]["data"]=&$buf;
12449
								#$conf["serverSock"],resource,web socket server socket
12450
								$conf["webSocket::checkAuth"]["serverSock"]=&$sock;
12451
								#$conf["clientSock"],$resource,web socket client socket
12452
								$conf["webSocket::checkAuth"]["clientSock"]=&$con["connect"];
12453
								#$conf["clientInfo"],陣列,web socket client info.
12454
								$conf["webSocket::checkAuth"]["clientInfo"]=&$connections[$conIndex];
12455
								#$conf["clientIndex"],整數.web socket client index.
12456
								$conf["webSocket::checkAuth"]["clientIndex"]=&$conIndex;
12457
								#$conf["allConn"],陣列,all web socket client info.
12458
								$conf["webSocket::checkAuth"]["allConn"]=&$connections;
12459
								#$conf["func"],字串,要檢查的是否具備權限的函式.
12460
								$conf["webSocket::checkAuth"]["func"]=$proFunc;
12461
								#可省略參數:
12462
								#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
12463
								#$conf["wsMode"]="true";
12464
								#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
12465
								#$conf["gpgId"]=gnupgId;
12466
								#$conf["falseAllowFuncPlus"],陣列,額外的未認證時可以執行的函式清單.
12467
								#$conf["falseAllowFuncPlus"]=array();
12468
								#$conf["publicAllowFuncPlus"],陣列,額外的認證為public時可以執行的函式清單.
12469
								#$conf["publicAllowFuncPlus"]=array();
12470
								#參考資料:
12471
								#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
12472
								#備註:
12473
								#無.
12474
								$checkAuth=webSocket::checkAuth($conf["webSocket::checkAuth"]);
12475
								unset($conf["webSocket::checkAuth"]);
3 liveuser 12476
 
66 liveuser 12477
								#如果沒有權限
12478
								if($checkAuth["status"]==="false"){
226 liveuser 12479
 
66 liveuser 12480
									#換看下個 $proFunc
12481
									continue;
226 liveuser 12482
 
66 liveuser 12483
									}#if end
12484
 
3 liveuser 12485
								#呼叫函式,參數為輸入的字串data跟client socket, server socket, 每個 socket
12486
								#https://www.php.net/manual/en/function.call-user-func.php
12487
								$param=array("data"=>&$buf,"serverSock"=>&$sock,"clientSock"=>&$con["connect"],"clientInfo"=>&$connections[$conIndex],"clientIndex"=>&$conIndex,"allConn"=>&$connections);
12488
								$params=array();
66 liveuser 12489
								$params[]=&$param;
12490
								$result=call_user_func_array($proFunc,$params);
3 liveuser 12491
 
12492
								#debug
12493
								#var_dump(__LINE__,$result);
12494
 
12495
								#如果有回傳結果
12496
								if($result!==NULL){
226 liveuser 12497
 
3 liveuser 12498
									#如果回傳的形態為陣列
12499
									if(gettype($result)==="array"){
12500
 
12501
										#如果執行出錯
12502
										if($result["status"]==="false"){
12503
 
12504
											#提示錯誤
12505
											echo "run function ".$proFunc." with params:".print_r($params,true)." failed!".PHP_EOL;
226 liveuser 12506
 
3 liveuser 12507
											#提示會往後面執行
12508
											echo "go next function.".PHP_EOL;
226 liveuser 12509
 
3 liveuser 12510
											#跳到下一輪
12511
											#continue;
12512
 
12513
											}#if end
226 liveuser 12514
 
3 liveuser 12515
										#如果結果為跳下一輪
12516
										else if($result["status"]==="continue"){
226 liveuser 12517
 
3 liveuser 12518
											#提示成功
12519
											echo "run function ".$proFunc." with params:".print_r($params,true)." success.".PHP_EOL;
226 liveuser 12520
 
3 liveuser 12521
											#提示會往後面執行
12522
											echo "go next function.".PHP_EOL;
226 liveuser 12523
 
3 liveuser 12524
											#跳下一輪
12525
											#continue;
226 liveuser 12526
 
3 liveuser 12527
											}#if end
226 liveuser 12528
 
3 liveuser 12529
										#如果已經被處理好了且不准移交給後面的處理
12530
										else if($result["status"]==="true"){
226 liveuser 12531
 
3 liveuser 12532
											#提示成功
12533
											echo "run function ".$proFunc." with params:".print_r($params,true)." success.".PHP_EOL;
226 liveuser 12534
 
3 liveuser 12535
											#提示在此打住.
12536
											echo "end process,".PHP_EOL;
226 liveuser 12537
 
3 liveuser 12538
											#後面就不做了
12539
											break;
226 liveuser 12540
 
3 liveuser 12541
											}#if end
226 liveuser 12542
 
3 liveuser 12543
										}#if end
12544
 
12545
									#反之回傳形態錯誤
12546
									else{
226 liveuser 12547
 
3 liveuser 12548
										#提示錯誤
12549
										echo "run function ".$proFunc." with params:".print_r($params,true)." success, but format of return is incorrect!".PHP_EOL;
226 liveuser 12550
 
3 liveuser 12551
										#提示會往後面執行
12552
										echo "go next function.".PHP_EOL;
226 liveuser 12553
 
3 liveuser 12554
										}#else end
12555
 
12556
									}#if end
226 liveuser 12557
 
3 liveuser 12558
								#如果沒有回傳結果
12559
								else{
226 liveuser 12560
 
3 liveuser 12561
									#提示錯誤
12562
									echo "run function ".$proFunc." with params:".print_r($params,true)." success, but there is no return!".PHP_EOL;
226 liveuser 12563
 
3 liveuser 12564
									#跳下一輪
12565
									#continue;
226 liveuser 12566
 
3 liveuser 12567
									}#else end
12568
 
12569
								}#foreach end
226 liveuser 12570
 
3 liveuser 12571
							}#if end
226 liveuser 12572
 
3 liveuser 12573
						#如果有要接收訊息的id
12574
						if(count($connections[$conIndex]["talkTo"])>0){
226 liveuser 12575
 
3 liveuser 12576
							#初始化要傳送給哪些id
12577
							$broadcastId=array();
226 liveuser 12578
 
3 liveuser 12579
							#依據每個連線資訊
12580
							foreach($connections as $index=>$broadcast){
226 liveuser 12581
 
3 liveuser 12582
								#儲存每個
12583
								$broadcastId[$index]=$broadcast["id"];
226 liveuser 12584
 
3 liveuser 12585
								}#foreach end
226 liveuser 12586
 
12587
							#檢查哪些人是要接收到訊息的
3 liveuser 12588
							#涵式說明:
12589
							#檢查多個數值,是否與陣列裏面的某些元素相同。
12590
							#回傳的結果:
12591
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12592
							#$result["function"],當前執行的函數
226 liveuser 12593
							#$result["error"],涵式錯誤訊息,若爲""則表示沒有錯誤
3 liveuser 12594
							#$result["founded"][$i],若爲"false"代表沒有相同的元素;反之"true"代表有相同的元素,$i爲第i+1個$conf["inputElement"]參數判斷後的結果.
12595
							#$result["key"][$i],為找到$conf["inputElement"]第$i+1個元素的值是在$conf["blackBoxElement"]中的哪個元素.
12596
							#必填的參數:
12597
							$conf["search::checkEquality"]["inputElement"]=$connections[$conIndex]["talkTo"];#想要找到的變數/數值.
12598
							$conf["search::checkEquality"]["blackBoxElement"]=$broadcastId;#要從哪些變數/數值去尋找.
12599
							$checkEquality=search::checkEquality($conf["search::checkEquality"]);
12600
							unset($conf["search::checkEquality"]);
226 liveuser 12601
 
3 liveuser 12602
							#如果檢查失敗
12603
							if($checkEquality["status"]==="false"){
226 liveuser 12604
 
3 liveuser 12605
								#設置執行失敗
12606
								$result["status"]="false";
226 liveuser 12607
 
3 liveuser 12608
								#設置執行錯誤訊息
12609
								$result["error"]=$checkEquality;
226 liveuser 12610
 
3 liveuser 12611
								#回傳結果
12612
								return $result;
226 liveuser 12613
 
3 liveuser 12614
								}#if end
226 liveuser 12615
 
3 liveuser 12616
							#針對每個搜尋的結果
12617
							foreach($checkEquality["founded"] as $key=>$found){
226 liveuser 12618
 
3 liveuser 12619
								#如果有找到
12620
								if($found==="true"){
226 liveuser 12621
 
3 liveuser 12622
									#取得要接收訊息的msgSock
12623
									$receiveMsgSock=$connections[$checkEquality["key"][$key]]["connect"];
226 liveuser 12624
 
3 liveuser 12625
									#設置要傳送的訊息
12626
									$talkback = $connections[$conIndex]["id"]." said ".$buf;
226 liveuser 12627
 
3 liveuser 12628
									#json encode 要傳送的訊息
12629
									$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 12630
 
3 liveuser 12631
									#如果是 ws 模式
12632
									if($conf["wsMode"]==="true"){
226 liveuser 12633
 
3 liveuser 12634
										#如果已經 handshake 過
12635
										if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 12636
 
12637
											#如果要 unmask
3 liveuser 12638
											if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 12639
 
3 liveuser 12640
												#加密
12641
												$conf["webSock::encode"]["text"]=$talkback;
12642
												$talkback=webSock::encode($conf["webSock::encode"]);
12643
												unset($conf["webSock::encode"]);
226 liveuser 12644
 
3 liveuser 12645
												}#if end
226 liveuser 12646
 
3 liveuser 12647
											}#if end
226 liveuser 12648
 
3 liveuser 12649
										}#if end
226 liveuser 12650
 
3 liveuser 12651
									#反之不為 web socket 訊息
12652
									else{
226 liveuser 12653
 
3 liveuser 12654
										#儲存成只有一個訊息
12655
										$talkback["content"][]=$talkback;
226 liveuser 12656
 
3 liveuser 12657
										}#else
226 liveuser 12658
 
12659
 
3 liveuser 12660
									#針對每個訊息的分段
12661
									foreach($talkback["content"] as $msg){
226 liveuser 12662
 
3 liveuser 12663
										#回傳訊息
12664
										$socket_write=socket_write($receiveMsgSock, $msg, strlen($msg));
226 liveuser 12665
 
3 liveuser 12666
										#debug
12667
										#var_dump(__LINE__,$receiveMsgSock,socket_strerror(socket_last_error($receiveMsgSock)));
226 liveuser 12668
 
3 liveuser 12669
										}#foreach end
226 liveuser 12670
 
3 liveuser 12671
									}#if end
226 liveuser 12672
 
3 liveuser 12673
								}#foreach end
226 liveuser 12674
 
3 liveuser 12675
							}#if end
226 liveuser 12676
 
3 liveuser 12677
						}#if end
226 liveuser 12678
 
3 liveuser 12679
					}#foreach end
226 liveuser 12680
 
12681
				#do end
3 liveuser 12682
				}while(true);
12683
 
12684
			#提示關閉 server socket
12685
			echo "關閉 server socket".PHP_EOL;
12686
 
12687
			#關閉 socket
12688
			socket_close($sock);
226 liveuser 12689
 
3 liveuser 12690
			#do end
12691
			}while(true);
226 liveuser 12692
 
3 liveuser 12693
		#設置執行正常
12694
		$result["status"]="true";
226 liveuser 12695
 
3 liveuser 12696
		#回傳結果
12697
		return $result;
226 liveuser 12698
 
3 liveuser 12699
		}#function nativeSocketTcpIpServer end
226 liveuser 12700
 
12701
	/*
3 liveuser 12702
	#函式說明:
12703
	#連線到webSocket,會印出建立好的unixDomainSocket位置與名稱.
12704
	#回傳結果:
12705
	#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
12706
	#$result["error"],錯誤訊息陣列.
12707
	#$resutl["function"],當前執行的涵式名稱.
12708
	#$result["content"],取得的回應.
12709
	#$result["argu"],所使用的參數.
12710
	#$result["Sec-WebSocket-Accept"],所得到的Sec-WebSocket-Accept.
12711
	#必填參數:
12712
	#無.
12713
	#可省略參數:
12714
	#$conf["targetServr"],字串,要連線的目標,預設為"localhost".
12715
	#$conf["targetServr"]="";
12716
	#$conf["targetPort"],字串,要連線的目標port.
12717
	#$conf["targetPort"]="";
12718
	#$conf["ssl"],字串,是否要走wss,預設為"false",不走wss;反之為"true".
12719
	#$conf["ssl"]="false";
12720
	#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
12721
	#$conf["debug"]="false";
12722
	#參考資料:
12723
	#https://www.php.net/manual/en/function.stream-socket-client.php
12724
	#https://www.php.net/manual/en/function.stream-context-create.php
12725
	#https://www.php.net/manual/en/context.ssl.php
12726
	#備註:
12727
	#建構中...
12728
	*/
12729
	public static function clientDaemon(&$conf){
226 liveuser 12730
 
3 liveuser 12731
		#初始化要回傳的結果
12732
		$result=array();
12733
 
12734
		#取得當前執行的函數名稱
12735
		$result["function"]=__FUNCTION__;
12736
 
12737
		#涵式說明:
12738
		#判斷當前環境為web還是cmd
12739
		#回傳結果:
12740
		#$result,"web"或"cmd"
12741
		if(csInformation::getEnv()==="web"){
226 liveuser 12742
 
3 liveuser 12743
			#設置執行失敗
12744
			$result["status"]="false";
226 liveuser 12745
 
3 liveuser 12746
			#設置執行錯誤訊息
12747
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 12748
 
3 liveuser 12749
			#回傳結果
12750
			return $result;
226 liveuser 12751
 
3 liveuser 12752
			}#if end
12753
 
12754
		#取得參數
12755
		$result["argu"]=$conf;
12756
 
12757
		#如果 $conf 不為陣列
12758
		if(gettype($conf)!="array"){
226 liveuser 12759
 
3 liveuser 12760
			#設置執行失敗
12761
			$result["status"]="false";
226 liveuser 12762
 
3 liveuser 12763
			#設置執行錯誤訊息
12764
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 12765
 
3 liveuser 12766
			#如果傳入的參數為 null
12767
			if($conf==null){
226 liveuser 12768
 
3 liveuser 12769
				#設置執行錯誤訊息
12770
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 12771
 
3 liveuser 12772
				}#if end
12773
 
12774
			#回傳結果
12775
			return $result;
226 liveuser 12776
 
3 liveuser 12777
			}#if end
226 liveuser 12778
 
3 liveuser 12779
		#檢查參數
12780
		#函式說明:
12781
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
12782
		#回傳結果:
12783
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12784
		#$result["error"],執行不正常結束的錯訊息陣列.
12785
		#$result["simpleError"],簡單表示的錯誤訊息.
12786
		#$result["function"],當前執行的函式名稱.
12787
		#$result["argu"],設置給予的參數.
12788
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
12789
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
12790
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
12791
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
12792
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
12793
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
12794
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
12795
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
12796
		#必填參數:
12797
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
12798
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
12799
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
12800
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
12801
		#可省略參數:
12802
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
12803
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array();
12804
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
12805
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array();
12806
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
12807
		#$conf["canBeEmptyString"]="false";
12808
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
12809
		#$conf["canNotBeEmpty"]=array();
12810
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
12811
		#$conf["canBeEmpty"]=array();
12812
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
12813
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("targetServr","targetPort","ssl","debug");
12814
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
12815
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("targetServr","targetPort","ssl","debug");
12816
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
12817
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","string");
12818
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
12819
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("localhost",null,"false","false");
12820
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
12821
		#$conf["disallowAllSkipableVarIsEmpty"]="";
12822
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
12823
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
12824
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
12825
		#$conf["disallowAllSkipableVarNotExist"]="";
12826
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
12827
		#$conf["arrayCountEqualCheck"][]=array();
12828
		#參考資料:
12829
		#array_keys=>http://php.net/manual/en/function.array-keys.php
12830
		#備註:
12831
		#無.
12832
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
12833
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 12834
 
3 liveuser 12835
		#如果檢查參數失敗
12836
		if($checkArguments["status"]==="false"){
226 liveuser 12837
 
3 liveuser 12838
			#設置執行失敗
12839
			$result["status"]="false";
226 liveuser 12840
 
3 liveuser 12841
			#設置執行錯誤訊息
12842
			$result["error"]=$checkArguments;
226 liveuser 12843
 
3 liveuser 12844
			#回傳結果
12845
			return $result;
226 liveuser 12846
 
3 liveuser 12847
			}#if end
226 liveuser 12848
 
3 liveuser 12849
		#如果檢查參數不通過
12850
		if($checkArguments["passed"]==="false"){
226 liveuser 12851
 
3 liveuser 12852
			#設置執行失敗
12853
			$result["status"]="false";
226 liveuser 12854
 
3 liveuser 12855
			#設置執行錯誤訊息
12856
			$result["error"]=$checkArguments;
226 liveuser 12857
 
3 liveuser 12858
			#回傳結果
12859
			return $result;
226 liveuser 12860
 
3 liveuser 12861
			}#if end
226 liveuser 12862
 
3 liveuser 12863
		#如果targetPort沒有設置
12864
		if(!isset($conf["targetPort"])){
226 liveuser 12865
 
3 liveuser 12866
			#port預設為80
12867
			$conf["targetPort"]="80";
226 liveuser 12868
 
3 liveuser 12869
			#如果有啟用 ssl
12870
			if($conf["ssl"]==="true"){
226 liveuser 12871
 
3 liveuser 12872
				#port預設為443
12873
				$conf["targetPort"]="443";
226 liveuser 12874
 
3 liveuser 12875
				}#if end
226 liveuser 12876
 
3 liveuser 12877
			}#if end
226 liveuser 12878
 
3 liveuser 12879
		#回報任何錯誤
12880
		#error_reporting(E_ALL);
226 liveuser 12881
 
3 liveuser 12882
		#如果要使用 ssl
12883
		if($conf["ssl"]==="true"){
226 liveuser 12884
 
3 liveuser 12885
			#預設的path
12886
			$path="/";
226 liveuser 12887
 
3 liveuser 12888
			#分割出server位置與對應GET的path
12889
			#函式說明:
12890
			#將固定格式的字串分開,並回傳分開的結果.
12891
			#回傳結果:
12892
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12893
			#$result["error"],錯誤訊息陣列
12894
			#$result["function"],當前執行的函數名稱.
12895
			#$result["argu"],使用的參數.
12896
			#$result["oriStr"],要分割的原始字串內容
12897
			#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
12898
			#$result["dataCounts"],爲總共分成幾段
12899
			#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
12900
			#必填參數:
12901
			#$conf["stringIn"],字串,要處理的字串.
12902
			$conf["stringProcess::spiltString"]["stringIn"]=$conf["targetServr"];
12903
			#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
12904
			$conf["stringProcess::spiltString"]["spiltSymbol"]="/";
12905
			#可省略參數:
12906
			#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
12907
			$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
12908
			#參考資料:
12909
			#無.
12910
			#備註:
12911
			#無.
12912
			$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
12913
			unset($conf["stringProcess::spiltString"]);
226 liveuser 12914
 
3 liveuser 12915
			#如果檢查執行失敗
12916
			if($spiltString["status"]==="false"){
226 liveuser 12917
 
3 liveuser 12918
				#設置執行失敗
12919
				$result["status"]="false";
226 liveuser 12920
 
3 liveuser 12921
				#設置執行錯誤訊息
12922
				$result["error"]=$spiltString;
226 liveuser 12923
 
3 liveuser 12924
				#回傳結果
12925
				return $result;
226 liveuser 12926
 
3 liveuser 12927
				}#if end
226 liveuser 12928
 
3 liveuser 12929
			#如果含有 /
12930
			if($spiltString["found"]==="true"){
226 liveuser 12931
 
3 liveuser 12932
				#函式說明:
12933
				#將字串特定關鍵字與其前面的內容剔除
12934
				#回傳結果:
12935
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
12936
				#$result["error"],錯誤訊息陣列.
12937
				#$result["warning"],警告訊息鎮列.
12938
				#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
12939
				#$result["function"],當前執行的函數名稱.
12940
				#$result["argu"],使用的參數.
12941
				#$result["oriStr"],要處理的原始字串內容.
226 liveuser 12942
				#$result["content"],處理好的的字串內容.
3 liveuser 12943
				#必填參數:
12944
				#$conf["stringIn"],字串,要處理的字串.
12945
				$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$conf["targetServr"];
12946
				#$conf["keyWord"],字串,特定字串.
12947
				$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="/";
12948
				#可省略參數:
12949
				#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
12950
				#$conf["recursive"]="true";
12951
				#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
12952
				#$conf["lastResult"]=$delStrBeforeKeyWord;
12953
				#參考資料:
12954
				#無.
12955
				#備註:
12956
				#無.
12957
				$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
12958
				unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 12959
 
3 liveuser 12960
				#如果檢查執行失敗
12961
				if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 12962
 
3 liveuser 12963
					#設置執行失敗
12964
					$result["status"]="false";
226 liveuser 12965
 
3 liveuser 12966
					#設置執行錯誤訊息
12967
					$result["error"]=$delStrBeforeKeyWord;
226 liveuser 12968
 
3 liveuser 12969
					#回傳結果
12970
					return $result;
226 liveuser 12971
 
3 liveuser 12972
					}#if end
226 liveuser 12973
 
3 liveuser 12974
				#如果該存在的 / 不存在
12975
				if($delStrBeforeKeyWord["founded"]==="false"){
226 liveuser 12976
 
3 liveuser 12977
					#設置執行失敗
12978
					$result["status"]="false";
226 liveuser 12979
 
3 liveuser 12980
					#設置執行錯誤訊息
12981
					$result["error"]=$delStrBeforeKeyWord;
226 liveuser 12982
 
3 liveuser 12983
					#回傳結果
12984
					return $result;
226 liveuser 12985
 
3 liveuser 12986
					}#if end
226 liveuser 12987
 
3 liveuser 12988
				#設置 path
12989
				$path="/".$delStrBeforeKeyWord["content"];
226 liveuser 12990
 
3 liveuser 12991
				#如果有切出 path
12992
				if($spiltString["dataCounts"]>=2){
226 liveuser 12993
 
3 liveuser 12994
					#另存peer host name
12995
					$peerHostName=$spiltString["dataArray"][0];
226 liveuser 12996
 
3 liveuser 12997
					#更新 targetServr
12998
					$conf["targetServr"]=$peerHostName;
226 liveuser 12999
 
3 liveuser 13000
					}#if end
226 liveuser 13001
 
3 liveuser 13002
				}#if end
226 liveuser 13003
 
3 liveuser 13004
			#初始化給 stream_context_create 用的參數
13005
			$paramsForStream_context_create=array();
226 liveuser 13006
 
3 liveuser 13007
			#設置為http相關的參數
13008
			#$paramsForStream_context_create["http"]=array();
226 liveuser 13009
 
3 liveuser 13010
			#method為HEAD
13011
			#$paramsForStream_context_create["http"]["method"]="HEAD ".$path;
226 liveuser 13012
 
3 liveuser 13013
			#HTTP/1.1
13014
			#$paramsForStream_context_create["http"]["protocol_version"]="1.1";
226 liveuser 13015
 
3 liveuser 13016
			#初始化header
13017
			#$paramsForStream_context_create["http"]["header"]=array();
226 liveuser 13018
 
3 liveuser 13019
			#設置header Host
13020
			#$paramsForStream_context_create["http"]["header"][]="Host: ".$conf["targetServr"];
226 liveuser 13021
 
3 liveuser 13022
			#設置header Upgrade
13023
			#$paramsForStream_context_create["http"]["header"][]="Upgrade: websocket";
226 liveuser 13024
 
3 liveuser 13025
			#設置header Connection
13026
			#$paramsForStream_context_create["http"]["header"][]="Connection: Upgrade";
226 liveuser 13027
 
3 liveuser 13028
			#設置header Sec-WebSocket-Version
13029
			#$paramsForStream_context_create["http"]["header"][]="Sec-WebSocket-Version: 13";
226 liveuser 13030
 
3 liveuser 13031
			#設置header Sec-WebSocket-Key
13032
			#$paramsForStream_context_create["http"]["header"][]="Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==";
226 liveuser 13033
 
3 liveuser 13034
			#body content
13035
			#$paramsForStream_context_create["http"]["content"]="";
226 liveuser 13036
 
3 liveuser 13037
			#設置為ssl相關的參數
13038
			$paramsForStream_context_create["ssl"]=array();
226 liveuser 13039
 
3 liveuser 13040
			#被連線端的網域名稱
13041
			#$paramsForStream_context_create["ssl"]["peer_name"]=$conf["targetServr"];
226 liveuser 13042
 
3 liveuser 13043
			#verify_peer
13044
			#$paramsForStream_context_create["ssl"]["verify_peer"]=true;
13045
			#$paramsForStream_context_create["ssl"]["verify_peer"]=false;
226 liveuser 13046
 
3 liveuser 13047
			#verify_peer_name
13048
			#$paramsForStream_context_create["ssl"]["verify_peer_name"]=true;
13049
			#$paramsForStream_context_create["ssl"]["verify_peer_name"]=false;
226 liveuser 13050
 
3 liveuser 13051
			#allow_self_signed,允許沒有受到認可的憑證
226 liveuser 13052
			#$paramsForStream_context_create["ssl"]["allow_self_signed"]=false;
13053
 
3 liveuser 13054
			#cafile
13055
			$paramsForStream_context_create["ssl"]["cafile"]="/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem";
226 liveuser 13056
 
3 liveuser 13057
			#capath
13058
			#$paramsForStream_context_create["ssl"]["capath"]="/etc/pki/ca-trust/extracted/pem/directory-hash/";
226 liveuser 13059
 
3 liveuser 13060
			#local_cert
13061
			#$paramsForStream_context_create["ssl"]["local_cert"]="/etc/pki/tls/certs/php-selfsigned-and-key.crt";
226 liveuser 13062
 
3 liveuser 13063
			#local_pk
13064
			#$paramsForStream_context_create["ssl"]["local_pk"]="/etc/pki/tls/private/php-selfsigned.key";
226 liveuser 13065
 
3 liveuser 13066
			#capture_peer_cert
13067
			$paramsForStream_context_create["ssl"]["capture_peer_cert"]=true;
226 liveuser 13068
 
3 liveuser 13069
			#capture_peer_cert_chain
13070
			$paramsForStream_context_create["ssl"]["capture_peer_cert_chain"]=true;
226 liveuser 13071
 
3 liveuser 13072
			#security_level
13073
			#$paramsForStream_context_create["ssl"]["security_level"]=5;
226 liveuser 13074
 
3 liveuser 13075
			#如果要 debug
13076
			if($conf["debug"]==="true"){
226 liveuser 13077
 
3 liveuser 13078
				#debug
13079
				var_dump(__LINE__,$paramsForStream_context_create);
226 liveuser 13080
 
3 liveuser 13081
				}#if end
226 liveuser 13082
 
3 liveuser 13083
			#建立ssl設定
13084
			$stream_context_create=stream_context_create($paramsForStream_context_create);
226 liveuser 13085
 
3 liveuser 13086
			#如果要 debug
13087
			if($conf["debug"]==="true"){
226 liveuser 13088
 
3 liveuser 13089
				#debug
13090
				var_dump(__LINE__,$stream_context_create);
226 liveuser 13091
 
3 liveuser 13092
				}#if end
226 liveuser 13093
 
3 liveuser 13094
			#連線到 $conf["targetServr"].":".$conf["targetPort"] ,若有 error 可從 $error_code,$error_message 取得資訊, timeout 為 30 秒, connection flags 為 STREAM_CLIENT_CONNECT, 連線的屬性記載在 $stream_context_create.
13095
			$stream_socket_client=stream_socket_client("ssl://".$conf["targetServr"].":".$conf["targetPort"],$error_code,$error_message,0,STREAM_CLIENT_CONNECT,$stream_context_create);
13096
 
13097
			#如果連線到 peer 失敗
13098
			if($stream_socket_client===false){
226 liveuser 13099
 
3 liveuser 13100
				#設置執行失敗
13101
				$result["status"]="false";
226 liveuser 13102
 
3 liveuser 13103
				#設置執行錯誤訊息
13104
				$result["error"][]="stream_socket_client() failed.".PHP_EOL."Reason: ".$error_message."(".$error_code.")".PHP_EOL;
226 liveuser 13105
 
3 liveuser 13106
				#回傳結果
13107
				return $result;
226 liveuser 13108
 
3 liveuser 13109
				}#if end
226 liveuser 13110
 
3 liveuser 13111
			#取得連線的資訊
13112
			$result["info"]=stream_get_meta_data($stream_socket_client);
226 liveuser 13113
 
3 liveuser 13114
			#write header - start
226 liveuser 13115
 
3 liveuser 13116
			#initial header
13117
			$header="";
226 liveuser 13118
 
3 liveuser 13119
			#method、path、protocol
13120
			$header=$header."HEAD ".$path." HTTP/1.1"."\r\n";
226 liveuser 13121
 
3 liveuser 13122
			#Host
13123
			$header=$header."Host: ".$conf["targetServr"]."\r\n";
226 liveuser 13124
 
3 liveuser 13125
			#Upgrade
13126
			$header=$header."Upgrade: websocket"."\r\n";
226 liveuser 13127
 
3 liveuser 13128
			#Connection
13129
			$header=$header."Connection: Upgrade"."\r\n";
226 liveuser 13130
 
3 liveuser 13131
			#Sec-WebSocket-Version
13132
			$header=$header."Sec-WebSocket-Version: 13"."\r\n";
226 liveuser 13133
 
3 liveuser 13134
			#Sec-WebSocket-Key
13135
			$header=$header."Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ=="."\r\n";
226 liveuser 13136
 
13137
			#send header
3 liveuser 13138
			fwrite($stream_socket_client,$header."\r\n");
226 liveuser 13139
 
3 liveuser 13140
			#write header - close
226 liveuser 13141
 
3 liveuser 13142
			#GET server reponse
13143
			while(!feof($stream_socket_client)){
226 liveuser 13144
 
3 liveuser 13145
				#讀取內容
13146
				$fgets=fgets($stream_socket_client, 1024);
226 liveuser 13147
 
3 liveuser 13148
				#如果要 debug
13149
				if($conf["debug"]==="true"){
226 liveuser 13150
 
3 liveuser 13151
					#debug
13152
					var_dump(__LINE__,$fgets);
226 liveuser 13153
 
3 liveuser 13154
					}#if end
226 liveuser 13155
 
3 liveuser 13156
				#如果 server 已經回應要用 websocket 協定了
13157
				if(trim($fgets)==="Upgrade: websocket"){
226 liveuser 13158
 
3 liveuser 13159
					#跳出while
13160
					break;
226 liveuser 13161
 
3 liveuser 13162
					}#if end
226 liveuser 13163
 
3 liveuser 13164
				}#if end
226 liveuser 13165
 
3 liveuser 13166
			#將建立的 sock 放到 $master 陣列
13167
			$master[] = $stream_socket_client;
226 liveuser 13168
 
3 liveuser 13169
			#函式說明:
13170
			#取得目前瀏覽的頁面的路徑或執行的php程式路徑.
13171
			#回傳結果:
13172
			#$result["status"],執行是否正常,"true"代表執行成功,"false"代表執行失敗.
13173
			#$result["error"],錯誤訊息.
13174
			#$result["function"],檔前執行的函數名稱.
13175
			#$result["content"],目前瀏覽的頁面的路徑或執行的php程式路徑.
13176
			#$result["serverIp"],取得伺服器ip.
13177
			#$result["scheme"],取得與伺服器連線所使用的通訊協定.
13178
			#必填參數:
13179
			$conf["csInformation::getPathOfThisPhpFile"]["type"]="pathOnly";#想要取得的路徑類型,"full"代表完整路徑,"pathOnly"代表只要路徑,"lastLayer"代表上一層目錄的名稱
13180
			#必填參數:
13181
			#無.
13182
			#可省略參數:
13183
			#無.
13184
			#參考資料:
13185
			#http://blog.longwin.com.tw/2009/01/php-get-directory-file-path-dirname-2008/
13186
			#備註:
13187
			#無.
13188
			$getPathOfThisPhpFile=csInformation::getPathOfThisPhpFile($conf["csInformation::getPathOfThisPhpFile"]);
13189
			unset($conf["csInformation::getPathOfThisPhpFile"]);
226 liveuser 13190
 
3 liveuser 13191
			#如果執行失敗
13192
			if($getPathOfThisPhpFile["status"]=="false"){
226 liveuser 13193
 
3 liveuser 13194
				#設置錯誤識別
13195
				$result["status"]="false";
226 liveuser 13196
 
3 liveuser 13197
				#設置錯誤訊息
13198
				$result["error"]=$getPathOfThisPhpFile;
226 liveuser 13199
 
3 liveuser 13200
				#回傳結果
13201
				return $result;
226 liveuser 13202
 
3 liveuser 13203
				}#if end
226 liveuser 13204
 
3 liveuser 13205
			#函式說明:
13206
			#使用 linux 的 uuid 指令來產生 uuid 字串
13207
			#回傳結果:
13208
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
13209
			#$result["error"],錯誤訊息.
13210
			#$result["function"],當前執行的函式名稱.
13211
			#$result["content"],uuid.
13212
			#必填參數:
13213
			#無.
13214
			#可省略參數:
13215
			#無.
13216
			#參考資料:
13217
			#無.
13218
			#備註:
13219
			#無.
13220
			$uuid=cmd::uuid();
226 liveuser 13221
 
3 liveuser 13222
			#如果執行失敗
13223
			if($uuid["status"]=="false"){
226 liveuser 13224
 
3 liveuser 13225
				#設置錯誤識別
13226
				$result["status"]="false";
226 liveuser 13227
 
3 liveuser 13228
				#設置錯誤訊息
13229
				$result["error"]=$uuid;
226 liveuser 13230
 
3 liveuser 13231
				#回傳結果
13232
				return $result;
226 liveuser 13233
 
3 liveuser 13234
				}#if end
226 liveuser 13235
 
3 liveuser 13236
			#設置存放socket的path
13237
			$socketPath=$getPathOfThisPhpFile["content"]."var/webSock::clientDaemon";
226 liveuser 13238
 
3 liveuser 13239
			#讓存放unix domain socket的路徑存在
13240
			#函式說明:
13241
			#確保路徑存在.
13242
			#回傳結果:
13243
			#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
13244
			#$result["error"],錯誤訊息陣列.
13245
			#$resutl["function"],當前執行的涵式名稱.
13246
			#$result["path"],建立好的路徑字串.
13247
			#$result["fileName"],檔案名稱,若 $conf["haveFileName"] 為 "true" 則會回傳.
13248
			#$result["argu"],使用的參數.
13249
			#必填參數:
13250
			#$conf["path"],要檢查的路徑
13251
			$conf["fileAccess::validatePath"]["path"]=$socketPath;
13252
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
13253
			$conf["fileAccess::validatePath"]["fileArgu"]=__FILE__;
13254
			#可省略參數:
13255
			#$conf["haveFileName"],字串,"true"代表有$conf["path"]檔案名稱,"false"代表$conf["path"]為純路徑,預設為"false".
13256
			$conf["fileAccess::validatePath"]["haveFileName"]="false";
13257
			#$conf["dirPermission"],字串,新建資料夾的權限設定,預設爲0770,亦即擁有者,同群組者可以讀,寫,存取,其他人無法使用.
13258
			#$conf["dirPermission"]="";
13259
			#$conf["web"],是否為檔案系統,"true"為網頁路徑,"false"為網頁系統,預設為"false".
13260
			$conf["fileAccess::validatePath"]["web"]="false";
13261
			#參考資料:
13262
			#無.
13263
			#備註:
13264
			#無.
13265
			$validatePath=fileAccess::validatePath($conf["fileAccess::validatePath"]);
13266
			unset($conf["fileAccess::validatePath"]);
226 liveuser 13267
 
3 liveuser 13268
			#如果執行失敗
13269
			if($validatePath["status"]==="false"){
226 liveuser 13270
 
3 liveuser 13271
				#設置錯誤識別
13272
				$result["status"]="false";
226 liveuser 13273
 
3 liveuser 13274
				#設置錯誤訊息
13275
				$result["error"]=$validatePath;
226 liveuser 13276
 
3 liveuser 13277
				#回傳結果
13278
				return $result;
226 liveuser 13279
 
3 liveuser 13280
				}#if end
226 liveuser 13281
 
3 liveuser 13282
			#變更 working dir
13283
			$chdir=chdir($socketPath);
226 liveuser 13284
 
3 liveuser 13285
			#設置sock檔案名稱
13286
			$socketName=$uuid["content"].".sock";
226 liveuser 13287
 
3 liveuser 13288
			#設置sock檔案位置與名稱
13289
			$socketAddr=$socketPath."/".$socketName;
226 liveuser 13290
 
3 liveuser 13291
			#如果要 debug
13292
			if($conf["debug"]==="true"){
226 liveuser 13293
 
3 liveuser 13294
				#debug
13295
				var_dump(__LINE__,$socketAddr);
226 liveuser 13296
 
3 liveuser 13297
				}#if end
226 liveuser 13298
 
3 liveuser 13299
			#建立 unix domain socket
13300
			$usock=stream_socket_server("unix://".$socketName, $errno, $errstr);
226 liveuser 13301
 
3 liveuser 13302
			#如果建立 unix domain socket 失敗
13303
			if(!$usock){
226 liveuser 13304
 
3 liveuser 13305
				#設置執行失敗
13306
				$result["status"]="false";
226 liveuser 13307
 
3 liveuser 13308
				#設置錯誤訊息
13309
				$result["error"][]=$errstr." (".$errno.")";
226 liveuser 13310
 
3 liveuser 13311
				#設置錯誤訊息
13312
				$result["error"][]="建立 unix domain socket(".$socketAddr.") 失敗";
226 liveuser 13313
 
3 liveuser 13314
				#回傳結果
13315
				return $result;
226 liveuser 13316
 
3 liveuser 13317
				}#if end
226 liveuser 13318
 
3 liveuser 13319
			#印出socket addr
13320
			echo "unixDomainSocket:".$socketAddr;
226 liveuser 13321
 
3 liveuser 13322
			#將建立的 unix domain socket 放到 $master 陣列
13323
			$master[] = $usock;
226 liveuser 13324
 
3 liveuser 13325
			#永久監聽, 不 timeout
13326
			while(true){
226 liveuser 13327
 
3 liveuser 13328
				#設置給 stream_select 監控的 sock 變數
13329
				$read = $write = $except = $master;
226 liveuser 13330
 
3 liveuser 13331
				#等待1秒,看有沒有連線進來讀寫資料
13332
				$mod_fd = stream_select($read, $write, $except, 1);
226 liveuser 13333
 
3 liveuser 13334
				#如果沒有偵測到讀寫動作失敗
13335
				if($mod_fd===FALSE){
226 liveuser 13336
 
3 liveuser 13337
					#關閉 web socket 連線
13338
					@fclose($stream_socket_client);
226 liveuser 13339
 
3 liveuser 13340
					#關閉unix domain socket
13341
					@fclose($usock);
226 liveuser 13342
 
3 liveuser 13343
					#移除unix domain socket
13344
					@unlink($socketAddr);
226 liveuser 13345
 
3 liveuser 13346
					#設置執行失敗
13347
					$result["status"]="false";
226 liveuser 13348
 
3 liveuser 13349
					#設置錯誤訊息
13350
					$result["error"][]="監聽資源異動失敗";
226 liveuser 13351
 
3 liveuser 13352
					#回傳結果
13353
					return $result;
226 liveuser 13354
 
3 liveuser 13355
					}#if end
226 liveuser 13356
 
3 liveuser 13357
				#如果沒有訊息,代表閒置時可以做的事情
13358
				else if($mod_fd===0){
226 liveuser 13359
 
3 liveuser 13360
					#代表沒收到訊息
13361
					echo ".";
226 liveuser 13362
 
3 liveuser 13363
					}#if end
226 liveuser 13364
 
3 liveuser 13365
				#反之有收到來自 web socket server 或 unix socket 的訊息
13366
				else{
226 liveuser 13367
 
3 liveuser 13368
					#針對每個 sock 陣列
13369
					foreach($read as $readStream){
226 liveuser 13370
 
3 liveuser 13371
						#如果是來自 web socket server 的訊息
13372
						if($readStream===$stream_socket_client){
226 liveuser 13373
 
3 liveuser 13374
							#當等待別人連線時,若有人連線進來.
13375
							#$webConn = stream_socket_accept($stream_socket_client);
226 liveuser 13376
 
3 liveuser 13377
							#如果要 debug
13378
							if($conf["debug"]==="true"){
226 liveuser 13379
 
3 liveuser 13380
								#debug
13381
								var_dump(__LINE__,"有收到來自 web socket server 的訊息");
226 liveuser 13382
 
3 liveuser 13383
								}#if end
226 liveuser 13384
 
3 liveuser 13385
							#讀取內容
13386
							$fread=fread($stream_socket_client,1024);
226 liveuser 13387
 
3 liveuser 13388
							#如果要 debug
13389
							if($conf["debug"]==="true"){
226 liveuser 13390
 
3 liveuser 13391
								#debug
13392
								var_dump(__LINE__,strlen($fread),$fread);
226 liveuser 13393
 
3 liveuser 13394
								}#if end
226 liveuser 13395
 
3 liveuser 13396
							#函式說明:
13397
							#將 handshake 後含有 mask bit 的 web socket 訊息進行  mask/unmask.
13398
							#回傳結果:
13399
							#$result["function"],當前函式的名稱.
13400
							#$result["argu"],使用的參數.
13401
							#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
13402
							#$result["content"],unmask後的內容.
13403
							#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame.
13404
							#$result["error"],錯誤訊息陣列.
13405
							#必填參數:
13406
							#$conf["payload"],字串,要解密的訊息.
226 liveuser 13407
							$conf["webSock::unmask"]["payload"]=$fread;
3 liveuser 13408
							#可省略參數:
13409
							#$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
13410
							$conf["webSock::unmask"]["allowUnmask"]="true";
13411
							#$conf["webSock::unmask"]["debug"]="true";
13412
							#參考資料
13413
							#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
13414
							#https://tools.ietf.org/html/rfc6455
13415
							#https://tools.ietf.org/html/rfc5234
13416
							#備註:
13417
							#無.
13418
							$unmask=webSock::unmask($conf["webSock::unmask"]);
13419
							unset($conf["webSock::unmask"]);
226 liveuser 13420
 
3 liveuser 13421
							#debug
13422
							#var_dump(__LINE__,$unmask);
226 liveuser 13423
 
3 liveuser 13424
							#如果出錯
13425
							if($unmask["status"]==="false"){
226 liveuser 13426
 
3 liveuser 13427
								#關閉 web socket 連線
13428
								@fclose($stream_socket_client);
226 liveuser 13429
 
3 liveuser 13430
								#關閉unix domain socket
13431
								@fclose($usock);
226 liveuser 13432
 
3 liveuser 13433
								#移除unix domain socket
13434
								@unlink($socketAddr);
226 liveuser 13435
 
3 liveuser 13436
								#設置執行失敗
13437
								$result["status"]="false";
226 liveuser 13438
 
3 liveuser 13439
								#設置執行錯誤訊息
13440
								$result["error"]=$unmask;
226 liveuser 13441
 
3 liveuser 13442
								#回傳結果
13443
								return $result;
226 liveuser 13444
 
3 liveuser 13445
								}#if end
226 liveuser 13446
 
3 liveuser 13447
							#如果收到文字訊息
13448
							if($unmask["type"]==="text"){
226 liveuser 13449
 
3 liveuser 13450
								#如果有解析出內容
13451
								if(isset($unmask["content"])){
226 liveuser 13452
 
3 liveuser 13453
									#提示收到的訊息
13454
									echo $unmask["content"];
226 liveuser 13455
 
3 liveuser 13456
									#傳遞給unix domain client
13457
									$fwrite=fwrite($unixConn,$unmask["content"]);
226 liveuser 13458
 
3 liveuser 13459
									#如果要 debug
13460
									if($conf["debug"]==="true"){
226 liveuser 13461
 
3 liveuser 13462
										#debug
13463
										var_dump(__LINE__,$fwrite);
226 liveuser 13464
 
3 liveuser 13465
										}#if end
226 liveuser 13466
 
3 liveuser 13467
									#關閉連線
13468
									fclose($unixConn);
226 liveuser 13469
 
3 liveuser 13470
									}#if end
226 liveuser 13471
 
3 liveuser 13472
								}#if end
226 liveuser 13473
 
3 liveuser 13474
							#如果收到ping
13475
							if($unmask["type"]==="ping"){
226 liveuser 13476
 
3 liveuser 13477
								#函式說明:
226 liveuser 13478
								#加密 handshake 後要傳送的 webSocket 訊息
3 liveuser 13479
								#回傳結果:
13480
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
13481
								#$result["error"],執行不正常結束的錯訊息陣列.
13482
								#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
13483
								#$result["argu"],陣列,使用的參數.
13484
								#必填參數:
13485
								#$conf["text"],字串,要加密的訊息.
226 liveuser 13486
								$conf["webSock::encode"]["text"]="";
3 liveuser 13487
								#可省略參數:
13488
								#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
13489
								#$conf["ping"]="true";
13490
								#$conf["pong"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
13491
								$conf["webSock::encode"]["pong"]="true";
13492
								#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
13493
								#$conf["frames"]=array();
13494
								#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
13495
								$conf["webSock::encode"]["mask"]="true";
13496
								#參考資料:
13497
								#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
13498
								#備註:
13499
								#無.
13500
								$encode=webSock::encode($conf["webSock::encode"]);
13501
								unset($conf["webSock::encode"]);
226 liveuser 13502
 
3 liveuser 13503
								#如果要 debug
13504
								if($conf["debug"]==="true"){
226 liveuser 13505
 
3 liveuser 13506
									#debug
13507
									var_dump(__LINE__,$encode);
226 liveuser 13508
 
3 liveuser 13509
									}#if end
226 liveuser 13510
 
3 liveuser 13511
								#如果出錯
13512
								if($encode["status"]==="false"){
226 liveuser 13513
 
3 liveuser 13514
									#設置執行失敗
13515
									$result["status"]="false";
226 liveuser 13516
 
3 liveuser 13517
									#設置執行錯誤訊息
13518
									$result["error"]=$encode;
226 liveuser 13519
 
3 liveuser 13520
									#回傳結果
13521
									return $result;
226 liveuser 13522
 
3 liveuser 13523
									}#if end
226 liveuser 13524
 
3 liveuser 13525
								#如果要 debug
13526
								if($conf["debug"]==="true"){
226 liveuser 13527
 
3 liveuser 13528
									#debug
13529
									var_dump(__LINE__,$encode);
226 liveuser 13530
 
3 liveuser 13531
									}#if end
226 liveuser 13532
 
3 liveuser 13533
								#針對每個 frame
13534
								foreach($encode["content"] as $fNo => $frame){
226 liveuser 13535
 
3 liveuser 13536
									#傳遞給 web socket server
13537
									$fwrite=fwrite($stream_socket_client,$frame);
226 liveuser 13538
 
3 liveuser 13539
									#如果傳遞失敗
13540
									if($fwrite===false){
226 liveuser 13541
 
3 liveuser 13542
										#關閉 web socket 連線
13543
										@fclose($stream_socket_client);
226 liveuser 13544
 
3 liveuser 13545
										#關閉unix domain socket
13546
										@fclose($usock);
226 liveuser 13547
 
3 liveuser 13548
										#移除unix domain socket
13549
										@unlink($socketAddr);
226 liveuser 13550
 
3 liveuser 13551
										#設置執行失敗
13552
										$result["status"]="false";
226 liveuser 13553
 
3 liveuser 13554
										#設置執行錯誤訊息
13555
										$result["error"][]="傳遞第 ".($fNo+1)." 個 frame 時出錯(總共有".count($encode["content"])."個frame)";
226 liveuser 13556
 
3 liveuser 13557
										#回傳結果
13558
										return $result;
226 liveuser 13559
 
3 liveuser 13560
										}#if end
226 liveuser 13561
 
3 liveuser 13562
									}#foreach end
226 liveuser 13563
 
3 liveuser 13564
								}#if end
226 liveuser 13565
 
3 liveuser 13566
							}#if end
226 liveuser 13567
 
3 liveuser 13568
						#反之若為來自 unix domain socket 的訊息
13569
						else if($readStream===$usock){
226 liveuser 13570
 
3 liveuser 13571
							#當等待別人連線時,若有人連線進來.
13572
							$unixConn = stream_socket_accept($usock);
226 liveuser 13573
 
3 liveuser 13574
							#如果要 debug
13575
							if($conf["debug"]==="true"){
226 liveuser 13576
 
3 liveuser 13577
								#debug
13578
								var_dump(__LINE__,"有收到來自 unix domain socket 的訊息");
226 liveuser 13579
 
3 liveuser 13580
								}#if end
226 liveuser 13581
 
3 liveuser 13582
							#讀取內容
13583
							$fgets=trim(fgets($unixConn,1024));
226 liveuser 13584
 
3 liveuser 13585
							#如果要 debug
13586
							if($conf["debug"]==="true"){
226 liveuser 13587
 
3 liveuser 13588
								#debug
13589
								var_dump(__LINE__,strlen($fgets),$fgets);
226 liveuser 13590
 
3 liveuser 13591
								}#if end
226 liveuser 13592
 
3 liveuser 13593
							#轉換成 web socket 的格式
13594
							#函式說明:
226 liveuser 13595
							#加密 handshake 後要傳送的 webSocket 訊息
3 liveuser 13596
							#回傳結果:
13597
							#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
13598
							#$result["error"],執行不正常結束的錯訊息陣列.
13599
							#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
13600
							#$result["argu"],陣列,使用的參數.
13601
							#必填參數:
13602
							#$conf["text"],字串,要加密的訊息.
226 liveuser 13603
							$conf["webSock::encode"]["text"]=$fgets;
3 liveuser 13604
							#可省略參數:
13605
							#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
13606
							#$conf["ping"]="true";
13607
							#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
13608
							#$conf["frames"]=array();
13609
							#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
13610
							$conf["webSock::encode"]["mask"]="true";
13611
							#參考資料:
13612
							#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
13613
							#備註:
13614
							#無.
13615
							$encode=webSock::encode($conf["webSock::encode"]);
13616
							unset($conf["webSock::encode"]);
226 liveuser 13617
 
3 liveuser 13618
							#如果要 debug
13619
							if($conf["debug"]==="true"){
226 liveuser 13620
 
3 liveuser 13621
								#debug
13622
								var_dump(__LINE__,$encode);
226 liveuser 13623
 
3 liveuser 13624
								}#if end
226 liveuser 13625
 
3 liveuser 13626
							#如果出錯
13627
							if($encode["status"]==="false"){
226 liveuser 13628
 
3 liveuser 13629
								#設置執行失敗
13630
								$result["status"]="false";
226 liveuser 13631
 
3 liveuser 13632
								#設置執行錯誤訊息
13633
								$result["error"]=$encode;
226 liveuser 13634
 
3 liveuser 13635
								#回傳結果
13636
								return $result;
226 liveuser 13637
 
3 liveuser 13638
								}#if end
226 liveuser 13639
 
3 liveuser 13640
							#針對每個frame
13641
							foreach($encode["content"] as $fNo => $frame){
226 liveuser 13642
 
3 liveuser 13643
								#傳遞給 web socket server
13644
								$fwrite=fwrite($stream_socket_client,$frame);
226 liveuser 13645
 
3 liveuser 13646
								#如果要 debug
13647
								if($conf["debug"]==="true"){
226 liveuser 13648
 
3 liveuser 13649
									#debug
13650
									var_dump(__LINE__,$fwrite,"傳遞".strlen($frame)."bytes給webSocketServer",$frame);
226 liveuser 13651
 
3 liveuser 13652
									}#if end
226 liveuser 13653
 
3 liveuser 13654
								#如果傳遞失敗
13655
								if($fwrite===false){
226 liveuser 13656
 
3 liveuser 13657
									#關閉 web socket 連線
13658
									@fclose($stream_socket_client);
226 liveuser 13659
 
3 liveuser 13660
									#關閉unix domain socket
13661
									@fclose($usock);
226 liveuser 13662
 
3 liveuser 13663
									#移除unix domain socket
13664
									@unlink($socketAddr);
226 liveuser 13665
 
3 liveuser 13666
									#設置執行失敗
13667
									$result["status"]="false";
226 liveuser 13668
 
3 liveuser 13669
									#設置執行錯誤訊息
13670
									$result["error"][]="傳遞第 ".($fNo+1)." 個 frame 時出錯(總共有".count($encode["content"])."個frame)";
226 liveuser 13671
 
3 liveuser 13672
									#回傳結果
13673
									return $result;
226 liveuser 13674
 
3 liveuser 13675
									}#if end
226 liveuser 13676
 
3 liveuser 13677
								}#foreach end
226 liveuser 13678
 
3 liveuser 13679
							}#if end
226 liveuser 13680
 
3 liveuser 13681
						#例外狀況
13682
						else{
226 liveuser 13683
 
3 liveuser 13684
							#如果要 debug
13685
							if($conf["debug"]==="true"){
226 liveuser 13686
 
3 liveuser 13687
								#debug
13688
								var_dump(__LINE__,$readStream);
226 liveuser 13689
 
3 liveuser 13690
								}#if end
226 liveuser 13691
 
3 liveuser 13692
							#關閉 web socket 連線
13693
							@fclose($stream_socket_client);
226 liveuser 13694
 
3 liveuser 13695
							#關閉unix domain socket
13696
							@fclose($usock);
226 liveuser 13697
 
3 liveuser 13698
							#移除unix domain socket
13699
							@unlink($socketAddr);
226 liveuser 13700
 
3 liveuser 13701
							#顯示 socket 的狀態
13702
							echo "非預期的錯誤,偵測到不應存在資源有異動".PHP_EOL;
226 liveuser 13703
 
3 liveuser 13704
							#結束執行並回傳1,代表異常結束
13705
							exit(1);
226 liveuser 13706
 
3 liveuser 13707
							}#else end
226 liveuser 13708
 
3 liveuser 13709
						}#foreach end
226 liveuser 13710
 
3 liveuser 13711
					}#else
226 liveuser 13712
 
3 liveuser 13713
				#等待1秒
13714
				sleep(1);
226 liveuser 13715
 
3 liveuser 13716
				}#while end
226 liveuser 13717
 
3 liveuser 13718
			#設置執行正常
13719
			$result["status"]="true";
226 liveuser 13720
 
3 liveuser 13721
			#回傳結果
13722
			return $result;
226 liveuser 13723
 
3 liveuser 13724
			}#if end
226 liveuser 13725
 
3 liveuser 13726
		#反之不用
13727
		else{
226 liveuser 13728
 
3 liveuser 13729
			#如果要 debug
13730
			if($conf["debug"]==="true"){
226 liveuser 13731
 
3 liveuser 13732
				#提示用戶端的文字
13733
				echo "TCP/IP Connection".PHP_EOL;
13734
 
13735
				}#if end
13736
 
13737
			/* Get the port for the WWW service. */
13738
			#http://php.net/manual/en/function.getservbyname.php
13739
			#$service_port = getservbyname('www', 'tcp');
226 liveuser 13740
 
3 liveuser 13741
			/* Get the IP address for the target host. */
13742
			#http://php.net/manual/en/function.gethostbyname.php
13743
			$ServerAddress = gethostbyname($conf["targetServr"]);
13744
 
13745
			/* Create a TCP/IP socket. */
13746
			$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
226 liveuser 13747
 
3 liveuser 13748
			#如果建立 socket 失敗
13749
			if ($socket === false) {
226 liveuser 13750
 
3 liveuser 13751
				#設置執行失敗
13752
				$result["status"]="false";
226 liveuser 13753
 
3 liveuser 13754
				#設置執行錯誤訊息
13755
				$result["error"][]="socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
226 liveuser 13756
 
3 liveuser 13757
				#回傳結果
13758
				return $result;
226 liveuser 13759
 
3 liveuser 13760
				}#if end
226 liveuser 13761
 
3 liveuser 13762
			#反之
13763
			else {
226 liveuser 13764
 
3 liveuser 13765
				#如果要 debug
13766
				if($conf["debug"]==="true"){
226 liveuser 13767
 
3 liveuser 13768
					#印出建立成功訊息
13769
					echo "OK.".PHP_EOL;
226 liveuser 13770
 
3 liveuser 13771
					}#if end
226 liveuser 13772
 
3 liveuser 13773
				}#else end
226 liveuser 13774
 
3 liveuser 13775
			#如果要 debug
13776
			if($conf["debug"]==="true"){
226 liveuser 13777
 
3 liveuser 13778
				#提示要連線到哪個位址的哪個port
13779
				echo "Attempting to connect to ".$ServerAddress." on port ".$conf["targetPort"]."...";
226 liveuser 13780
 
3 liveuser 13781
				}#if end
226 liveuser 13782
 
3 liveuser 13783
			#連線到目標 socket
13784
			$socket_connect=socket_connect($socket, $ServerAddress, $conf["targetPort"]);
226 liveuser 13785
 
3 liveuser 13786
			#如果連線到 socket 失敗
13787
			if($socket_connect===false){
226 liveuser 13788
 
3 liveuser 13789
				#設置執行失敗
13790
				$result["status"]="false";
226 liveuser 13791
 
3 liveuser 13792
				#設置執行錯誤訊息
13793
				$result["error"][]="socket_connect() failed.".PHP_EOL."Reason: ($socket_connect) " . socket_strerror(socket_last_error($socket)) . PHP_EOL;
226 liveuser 13794
 
3 liveuser 13795
				#回傳結果
13796
				return $result;
226 liveuser 13797
 
3 liveuser 13798
				}#if end
226 liveuser 13799
 
3 liveuser 13800
			#反之
13801
			else {
226 liveuser 13802
 
3 liveuser 13803
				#如果要 debug
13804
				if($conf["debug"]==="true"){
226 liveuser 13805
 
3 liveuser 13806
					#印出連線成功訊息
13807
					echo "OK.".PHP_EOL;
226 liveuser 13808
 
3 liveuser 13809
					}#if end
226 liveuser 13810
 
3 liveuser 13811
				}#else end
226 liveuser 13812
 
3 liveuser 13813
			}#else end
226 liveuser 13814
 
3 liveuser 13815
		#初始化要傳送的HEAD資訊
13816
		$in="HEAD / HTTP/1.1"."\r\n";
13817
		$in=$in."Host: ".$ServerAddress.":".$conf["targetPort"]."\r\n";
13818
		$in=$in."Upgrade: websocket"."\r\n";
13819
		$in=$in."Connection: Upgrade"."\r\n";
13820
		$in=$in."Sec-WebSocket-Version: 13"."\r\n";
13821
		$in=$in."Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ=="."\r\n";
13822
		$in=$in."\r\n";
226 liveuser 13823
 
3 liveuser 13824
		#初始化回傳的內容
13825
		$out = '';
13826
 
13827
		#如果連線到 socket 失敗
13828
		if($socket_connect===false){
13829
 
13830
			#提示傳送HTTP HEAD中
13831
			echo "Sending HTTP HEAD request...";
226 liveuser 13832
 
3 liveuser 13833
			}#if end
226 liveuser 13834
 
3 liveuser 13835
		#將訊息傳送到socket去
13836
		socket_write($socket, $in, strlen($in));
226 liveuser 13837
 
3 liveuser 13838
		#如果連線到 socket 失敗
13839
		if($socket_connect===false){
226 liveuser 13840
 
3 liveuser 13841
			#提示傳送完畢
13842
			echo "OK.".PHP_EOL;
13843
 
13844
			#提示讀取回應中
13845
			echo "Reading response:".PHP_EOL;
226 liveuser 13846
 
3 liveuser 13847
			}#if end
226 liveuser 13848
 
3 liveuser 13849
		#無窮迴圈
13850
		while(true){
226 liveuser 13851
 
3 liveuser 13852
			#一次讀取2048bytes,判斷有無回應,並取得其內容.
13853
			$out = socket_read($socket, 2048);
226 liveuser 13854
 
3 liveuser 13855
			#如果尚未取得 Sec-WebSocket-Accept
13856
			if(!isset($result["Sec-WebSocket-Accept"])){
226 liveuser 13857
 
3 liveuser 13858
				#如果連線到 socket 失敗
13859
				if($socket_connect===false){
226 liveuser 13860
 
3 liveuser 13861
					#印出收到的內容
13862
					echo $out;
226 liveuser 13863
 
3 liveuser 13864
					}#if end
226 liveuser 13865
 
3 liveuser 13866
				#如果 $out 有資料
13867
				if($out){
226 liveuser 13868
 
3 liveuser 13869
					#如果接收到的是字串,且不為空
13870
					if(gettype($out)==="string" && !empty($out)){
226 liveuser 13871
 
3 liveuser 13872
						#如果有既有的前次回應內容
13873
						if(isset($result["content"])){
226 liveuser 13874
 
3 liveuser 13875
							#儲存回應的內容
13876
							$result["content"]=$result["content"].$out;
226 liveuser 13877
 
3 liveuser 13878
							}#if end
226 liveuser 13879
 
3 liveuser 13880
						#反之
13881
						else{
226 liveuser 13882
 
3 liveuser 13883
							#儲存回應的內容
13884
							$result["content"]=$out;
226 liveuser 13885
 
3 liveuser 13886
							}#else end
226 liveuser 13887
 
3 liveuser 13888
						#涵式說明:
13889
						#將固定格式的字串分開,並回傳分開的結果。
13890
						#回傳結果:
13891
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
13892
						#$result["error"],錯誤訊息陣列
13893
						#$result["function"],當前執行的函數名稱.
13894
						#$result["argu"],使用的參數.
13895
						#$result["oriStr"],要分割的原始字串內容
13896
						#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
13897
						#$result["dataCounts"],爲總共分成幾段
13898
						#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
13899
						#必填的參數:
13900
						#$conf["stringIn"],字串,要處理的字串.
13901
						$conf["stringProcess::spiltString"]["stringIn"]=$out;
13902
						#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
13903
						$conf["stringProcess::spiltString"]["spiltSymbol"]="Sec-WebSocket-Accept: ";
13904
						#可省略參數:
13905
						#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
13906
						$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
13907
						$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
13908
						unset($conf["stringProcess::spiltString"]);
226 liveuser 13909
 
3 liveuser 13910
						#如果執行失敗
13911
						if($spiltString["status"]==="false"){
226 liveuser 13912
 
3 liveuser 13913
							#設置執行失敗
13914
							$result["status"]="false";
226 liveuser 13915
 
3 liveuser 13916
							#設置執行錯誤訊息
13917
							$result["error"]=$spiltString;
226 liveuser 13918
 
3 liveuser 13919
							#回傳結果
13920
							return $result;
226 liveuser 13921
 
3 liveuser 13922
							}#if end
226 liveuser 13923
 
3 liveuser 13924
						#取得Sec-WebSocket-Accept
13925
						$result["Sec-WebSocket-Accept"]=trim($spiltString["dataArray"][1]);
226 liveuser 13926
 
13927
						#初始化要傳遞的內容
3 liveuser 13928
						$in="id?";
226 liveuser 13929
 
3 liveuser 13930
						#初始化傳遞的內容長度
13931
						$len=strlen($in);
226 liveuser 13932
 
3 liveuser 13933
						#設置儲存每個元素為8bit字串的陣列
13934
						$bit8=array();
13935
						$bit8[0]="10000001";
13936
						$bit8[1]="1".sprintf("%07s",base_convert($len,10,2));
226 liveuser 13937
 
3 liveuser 13938
						#mask key
13939
						$bit8[2]="00000000";
13940
						$bit8[3]="00000000";
13941
						$bit8[4]="00000000";
13942
						$bit8[5]="00000000";
226 liveuser 13943
 
3 liveuser 13944
						#mask key
13945
						$mask_key=$bit8[2].$bit8[3].$bit8[4].$bit8[5];
226 liveuser 13946
 
3 liveuser 13947
						#針對每個字,進行mask
13948
						for($i=0;$i<$len;$i++){
226 liveuser 13949
 
3 liveuser 13950
							$j=$i%4;
226 liveuser 13951
 
3 liveuser 13952
							$in[$i]=$in[$i] xor $mask_key[$j];
226 liveuser 13953
 
3 liveuser 13954
							}#for end
226 liveuser 13955
 
3 liveuser 13956
						#如果連線到 socket 失敗
13957
						if($socket_connect===false){
226 liveuser 13958
 
3 liveuser 13959
							#提示傳送資料
13960
							echo "Sending Data...".PHP_EOL;
226 liveuser 13961
 
3 liveuser 13962
							}#if end
226 liveuser 13963
 
3 liveuser 13964
						#data frame
13965
						$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 13966
 
3 liveuser 13967
						#將訊息傳送到socket去
13968
						socket_write($socket, $in, strlen($in));
226 liveuser 13969
 
3 liveuser 13970
						}#if end
226 liveuser 13971
 
13972
					}#if end
13973
 
3 liveuser 13974
				}#if end
226 liveuser 13975
 
3 liveuser 13976
			#反之取得了 Sec-WebSocket-Accept 就結束 HTTP/1.1
13977
			else{
226 liveuser 13978
 
3 liveuser 13979
				#如果連線到 socket 失敗
13980
				if($socket_connect===false){
226 liveuser 13981
 
3 liveuser 13982
					echo "解密前的內容:".PHP_EOL;
226 liveuser 13983
 
3 liveuser 13984
					}#if end
226 liveuser 13985
 
3 liveuser 13986
				#函式說明:
13987
				#將字串中的每個字變成bytes陣列
13988
				#回傳結果:
13989
				#$result...
13990
				#必填參數:
13991
				#$conf["input"],字串,要轉換成bytes陣列的字串
13992
				$conf["stringProcess::str2bytesArray"]["input"]=$out;
13993
				#可省略參數:
13994
				#無
13995
				#建構中...
13996
				$str2bytesArray=stringProcess::str2bytesArray($conf["stringProcess::str2bytesArray"]);
13997
				unset($conf["stringProcess::str2bytesArray"]);
226 liveuser 13998
 
13999
				#針對每個bytes
3 liveuser 14000
				foreach($str2bytesArray["content"] as $byte){
226 liveuser 14001
 
3 liveuser 14002
					#函式說明:
14003
					#將bytes數字轉換為bit字串(0跟1來表述)
14004
					#回傳結果:
14005
					#$result...
14006
					#必填參數:
14007
					#$conf["input"],字串,要轉換成byte的字串
14008
					$conf["stringProcess::str2bytesArray"]["bytes"]=$byte;
14009
					#可省略參數:
14010
					#無
14011
					#建構中...
14012
					$bytes2bitString=stringProcess::bytes2bitString($conf["stringProcess::str2bytesArray"]);
14013
					unset($conf["stringProcess::str2bytesArray"]);
226 liveuser 14014
 
3 liveuser 14015
					#如果連線到 socket 失敗
14016
					if($socket_connect===false){
226 liveuser 14017
 
3 liveuser 14018
						#debug
14019
						var_dump($bytes2bitString["content"]);
226 liveuser 14020
 
3 liveuser 14021
						}#if end
226 liveuser 14022
 
3 liveuser 14023
					}#foreach end
226 liveuser 14024
 
3 liveuser 14025
				#如果連線到 socket 失敗
14026
				if($socket_connect===false){
226 liveuser 14027
 
3 liveuser 14028
					echo "解密後接收的內容:".PHP_EOL;
226 liveuser 14029
 
3 liveuser 14030
					}#if end
226 liveuser 14031
 
3 liveuser 14032
				#函式說明:
14033
				#解密 handshake 後要接收的訊息
14034
				#回傳結果:
14035
				#$result["function"],當前函式的名稱.
14036
				#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
14037
				#$result["content"],unmask後的內容.
14038
				#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame.
14039
				#$result["error"],錯誤訊息陣列.
14040
				#必填參數:
14041
				#$conf["payload"],字串,要解密的訊息.
226 liveuser 14042
				$conf["webSock::unmask"]["payload"]=$out;
3 liveuser 14043
				#可省略參數:
14044
				#$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
14045
				$conf["webSock::unmask"]["allowUnmask"]="true";
14046
				#參考資料
14047
				#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
14048
				#https://tools.ietf.org/html/rfc6455
14049
				#https://tools.ietf.org/html/rfc5234
14050
				#備註:
14051
				#無.
14052
				$unmask=webSock::unmask($conf["webSock::unmask"]);
14053
				unset($conf["webSock::unmask"]);
226 liveuser 14054
 
3 liveuser 14055
				#如果執行失敗
14056
				if($unmask["status"]==="false"){
226 liveuser 14057
 
3 liveuser 14058
					#設置執行失敗
14059
					$result["status"]="false";
226 liveuser 14060
 
3 liveuser 14061
					#設置執行錯誤訊息
14062
					$result["error"]=$unmask;
226 liveuser 14063
 
3 liveuser 14064
					#回傳結果
14065
					return $result;
226 liveuser 14066
 
3 liveuser 14067
					}#if end
226 liveuser 14068
 
3 liveuser 14069
				#記錄接收到的內容
14070
				$received=$unmask["content"];
226 liveuser 14071
 
3 liveuser 14072
				#如果連線到 socket 失敗
226 liveuser 14073
				if($socket_connect===false){
14074
 
3 liveuser 14075
					#debug
14076
					var_dump($received);
226 liveuser 14077
 
3 liveuser 14078
					}#if end
226 liveuser 14079
 
3 liveuser 14080
				}#else end
226 liveuser 14081
 
3 liveuser 14082
			#休息1秒
14083
			sleep(1);
226 liveuser 14084
 
3 liveuser 14085
			}#while end
14086
 
14087
		#如果連線到 socket 失敗
14088
		if($socket_connect===false){
14089
 
14090
			#提示關閉與 socket 的連線
14091
			echo "Closing socket...";
226 liveuser 14092
 
3 liveuser 14093
			}#if end
226 liveuser 14094
 
3 liveuser 14095
		#關閉與 socket 的連線
14096
		socket_close($socket);
226 liveuser 14097
 
3 liveuser 14098
		#如果連線到 socket 失敗
14099
		if($socket_connect===false){
226 liveuser 14100
 
3 liveuser 14101
			#提示關閉連線成功
14102
			echo "OK.".PHP_EOL;
226 liveuser 14103
 
3 liveuser 14104
			}#if end
226 liveuser 14105
 
3 liveuser 14106
		#設置執行正常
14107
		$result["status"]="true";
226 liveuser 14108
 
3 liveuser 14109
		#回傳結果
14110
		return $result;
226 liveuser 14111
 
3 liveuser 14112
		}#function clientDaemon end
226 liveuser 14113
 
14114
	/*
3 liveuser 14115
	#函式說明:
14116
	#webSocket的javaScript用戶端
14117
	#回傳結果:
14118
	#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
14119
	#$result["error"],錯誤訊息陣列.
14120
	#$resutl["function"],當前執行的涵式名稱.
14121
	#$result["argu"],所使用的參數.
14122
	#$result["content"],語法.
14123
	#必填參數:
14124
	#$conf["url"],字串要拜訪的web socket,請省略"ws://".
14125
	$conf["url"]="";
14126
	#可省略參數:
14127
	#$conf["entry"],字串,是否要用加密的wss,預設為"false",代表用ws,若為"true"則為wss.
14128
	#$conf["entry"]="false";
14129
	#$conf["connVar"],字串,用來儲存webSocket連線的物件名稱,預設為"conn".
14130
	#$conf["connVar"]="conn";
14131
	#參考資料:
14132
	#無.
14133
	#備註:
14134
	#無.
14135
	*/
14136
	public static function client(&$conf){
226 liveuser 14137
 
3 liveuser 14138
		#初始化要回傳的結果
14139
		$result=array();
14140
 
14141
		#取得當前執行的函數名稱
14142
		$result["function"]=__FUNCTION__;
14143
 
14144
		#如果沒有參數
14145
		if(func_num_args()==0){
226 liveuser 14146
 
3 liveuser 14147
			#設置執行失敗
14148
			$result["status"]="false";
226 liveuser 14149
 
3 liveuser 14150
			#設置執行錯誤訊息
14151
			$result["error"]="函數".$result["function"]."需要參數";
226 liveuser 14152
 
3 liveuser 14153
			#回傳結果
14154
			return $result;
226 liveuser 14155
 
3 liveuser 14156
			}#if end
14157
 
14158
		#取得參數
14159
		$result["argu"]=$conf;
14160
 
14161
		#如果 $conf 不為陣列
14162
		if(gettype($conf)!=="array"){
226 liveuser 14163
 
3 liveuser 14164
			#設置執行失敗
14165
			$result["status"]="false";
226 liveuser 14166
 
3 liveuser 14167
			#設置執行錯誤訊息
14168
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 14169
 
3 liveuser 14170
			#如果傳入的參數為 null
14171
			if($conf===null){
226 liveuser 14172
 
3 liveuser 14173
				#設置執行錯誤訊息
14174
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 14175
 
3 liveuser 14176
				}#if end
14177
 
14178
			#回傳結果
14179
			return $result;
226 liveuser 14180
 
3 liveuser 14181
			}#if end
226 liveuser 14182
 
3 liveuser 14183
		#檢查參數
14184
		#函式說明:
14185
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
14186
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
14187
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
14188
		#$result["function"],當前執行的函式名稱.
14189
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
14190
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
14191
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
14192
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
14193
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
14194
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
14195
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
14196
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
14197
		#必填寫的參數:
14198
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
14199
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
14200
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
14201
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("url");
14202
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
14203
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
14204
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
14205
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
14206
		#可以省略的參數:
14207
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
14208
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
14209
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
14210
		#$conf["canNotBeEmpty"]=array();
14211
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
14212
		#$conf["canBeEmpty"]=array();
14213
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
14214
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
14215
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
14216
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("entry","connVar");
226 liveuser 14217
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3 liveuser 14218
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
14219
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
14220
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("false","conn");
14221
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
14222
		#$conf["arrayCountEqualCheck"][]=array();
14223
		#參考資料來源:
14224
		#array_keys=>http://php.net/manual/en/function.array-keys.php
14225
		#建議:
14226
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
14227
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
14228
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 14229
 
3 liveuser 14230
		#如果檢查參數失敗
14231
		if($checkArguments["status"]==="false"){
226 liveuser 14232
 
3 liveuser 14233
			#設置執行失敗
14234
			$result["status"]="false";
226 liveuser 14235
 
3 liveuser 14236
			#設置執行錯誤訊息
14237
			$result["error"]=$checkArguments;
226 liveuser 14238
 
3 liveuser 14239
			#回傳結果
14240
			return $result;
226 liveuser 14241
 
3 liveuser 14242
			}#if end
226 liveuser 14243
 
3 liveuser 14244
		#如果參數檢查不通過
14245
		if($checkArguments["passed"]==="false"){
226 liveuser 14246
 
3 liveuser 14247
			#設置執行失敗
14248
			$result["status"]="false";
226 liveuser 14249
 
3 liveuser 14250
			#設置執行錯誤訊息
14251
			$result["error"]=$checkArguments;
226 liveuser 14252
 
3 liveuser 14253
			#回傳結果
14254
			return $result;
226 liveuser 14255
 
14256
			}#if end
14257
 
3 liveuser 14258
		#初始化 web socket 的協定
14259
		$webSockUrl="ws://";
226 liveuser 14260
 
3 liveuser 14261
		#如果要加密
14262
		if($conf["entry"]==="true"){
226 liveuser 14263
 
3 liveuser 14264
			$webSockUrl="wss://";
226 liveuser 14265
 
3 liveuser 14266
			}#if end
226 liveuser 14267
 
3 liveuser 14268
		#設置用戶端連線到webSocket的範例
14269
		$script="<script>
226 liveuser 14270
 
3 liveuser 14271
			//建立 web socket 連線到 ".$webSockUrl.$conf["url"]."
14272
			var ".$conf["connVar"]." = new WebSocket('".$webSockUrl.$conf["url"]."');
226 liveuser 14273
 
3 liveuser 14274
			//當連線成功後
14275
			".$conf["connVar"].".onopen = function(e)
14276
			{
14277
				//印出連線成功訊息到console
14278
				console.log(\"Connection established!\");
14279
			};
14280
 
14281
			//當有收到訊息時
14282
			".$conf["connVar"].".onmessage = function(e) {
226 liveuser 14283
 
3 liveuser 14284
				//將訊息顯現在console
14285
				console.log(e.data);
14286
			};
14287
			</script>";
226 liveuser 14288
 
3 liveuser 14289
		#設置建立webSocket連線的按鈕
14290
		#函式說明:
14291
		#放置按鈕
14292
		#回傳結果:
14293
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
14294
		#$result["function"],當前執行的函數.
14295
		#$result["error"],錯誤訊息陣列.
226 liveuser 14296
		#$result["content"],按鈕語法.
3 liveuser 14297
		#必要的參數:
14298
		$conf["form::button"]["buttonDisplayValue"]="Send Hello!";#爲按鈕上顯示的文字。
14299
		#可省略的參數:
14300
		#$conf["buttonStyleName"]="";#可省略,爲按鈕所要使用的css樣式類別名稱,預設的css樣式爲 __simpleButtonLinkDefaultButtonCssStyle 。
14301
			#其屬性爲   "width","height","font-size","text-align"
14302
			#其屬性值爲 "100%" ,  "50"  ,    "30"   ,   "center"
14303
		$conf["form::button"]["buttonActionScriptFunction"]="conn.send('Hello!');";#可省略,爲按下按鈕時所要執行的javaScript函式或程式,預設不設定。
14304
			#"document.forms.formName.submit()"爲傳送名爲testForm的表單內容
14305
			#"window.print()"爲使用瀏覽器內建工具列印當前網頁
14306
			#若搭配 javaScript 類別的 confirmWindow 函數的回傳結果,則會有確認視窗的效果.
14307
		#$conf["buttonBorder"]="";#可省略,爲IE9內會自動產生外框,此爲外框的厚度,屬性值爲正整數,預設爲0。
14308
		#$conf["disabled"]="true";#可省略,為按鈕的功能是否要取消,若為"true"則代表要取消,若為"false"則代表功能正常,預設為"false".
14309
		#$conf["tableStart"]="true";#爲是否要表格開始。"false"代表否,"true"代表是。預設爲"false"。
14310
		#$conf["tableClass"]="";#表格要套用的css樣式,若省略的話,則預設爲 __defaultTbaleCsssStyle 其屬性爲 table-layout:fixed word-break:break-all width:100% ,須搭配 $conf["tablStart"] 與 $conf["tableEnd"] 使用。
14311
		#$conf["trStart"]="true";#爲是否要以<tr>開頭,"true"表示"是"。也可以看作新的一列開始,預設為"false".
14312
		#$conf["trClass"]="__withoutBorder";#<tr>要套用的css樣式,預設為"__withoutBorder",亦即沒有框線的樣式;"__withBorder"則爲有框線的樣式
14313
		#$conf["tdStart"]="true";#爲是否要以<td>開頭,"true"表示"是"。也可以看成列裏面的元素開始,預設為"false".
14314
		#$conf["tdClass"]="__withoutBorder";#<td>要套用的css樣式,"__withoutBorder"爲沒有框線的樣式;__withBorder爲有框線的樣式
14315
		#$conf["tdEnd"]="true";#爲是否要以</td>結尾,"true"表示"是"。也可以看成列裏面的元素結束,預設為"false".
14316
		#$conf["trEnd"]="true";#爲是否要以</tr>結尾,"true"表示"是"。也可以看作該列結束,預設為"false".
14317
		#$conf["tableEnd"]="true";#爲是否要表格結束。"false"代表否,"true"代表是,預設爲"false"。
14318
		#$conf["formStart"]="true";#爲是否要表單開始,如果爲"true"則代表要表單開始,預設為"false".
14319
		#$conf["action"]="";#爲表單要傳送到哪個頁面,須搭配$conf["formStart"]與$conf["formEnd"]參數使用
14320
		#$conf["target"]="";#為目標表單顯示的方式,若沒設定則預設爲"_self",其他可用的參數爲 "_blank"、"_parent"、"_top",也可以是iframe的名稱。須搭配$conf["formStart"]與$conf["formEnd"]參數使用
14321
		#$conf["formEnd"]="true";#爲是否要表單結束,如果爲"true"則代表要表單結束,預設為"false".
14322
		#$conf["formId"],字串,表單的id.
14323
		#$conf["formId"]="";
14324
		#$conf["buttonId"],字串,按鈕的id.
14325
		#$conf["buttonId"]="";
14326
		#參考資料來源:
14327
		#http://stackoverflow.com/questions/3014649/how-to-disable-html-button-using-javascript
14328
		$button=form::button($conf["form::button"]);
14329
		unset($conf["form::button"]);
226 liveuser 14330
 
3 liveuser 14331
		#如果建立按鈕失敗
14332
		if($button["status"]==="false"){
226 liveuser 14333
 
3 liveuser 14334
			#設置執行失敗
14335
			$result["status"]="false";
226 liveuser 14336
 
3 liveuser 14337
			#設置執行錯誤訊息
14338
			$result["error"]=$button;
226 liveuser 14339
 
3 liveuser 14340
			#回傳結果
14341
			return $result;
226 liveuser 14342
 
14343
			}#if end
14344
 
3 liveuser 14345
		#設置用戶端的html與js語法
14346
		$result["content"]=$button["content"].$script;
226 liveuser 14347
 
3 liveuser 14348
		#設置執行正常
14349
		$result["status"]="true";
226 liveuser 14350
 
3 liveuser 14351
		#回傳結果
14352
		return $result;
226 liveuser 14353
 
3 liveuser 14354
		}#function client end
226 liveuser 14355
 
3 liveuser 14356
	/*
14357
	#函式說明:
14358
	#將 handshake 後含有 mask bit 的 web socket 訊息進行  mask/unmask.
14359
	#回傳結果:
14360
	#$result["function"],當前函式的名稱.
14361
	#$result["argu"],使用的參數.
14362
	#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
14363
	#$result["content"],unmask後的內容.
14364
	#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame.
14365
	#$result["error"],錯誤訊息陣列.
14366
	#必填參數:
14367
	#$conf["payload"],字串,要解密的訊息.
226 liveuser 14368
	$conf["payload"]="";
3 liveuser 14369
	#可省略參數:
14370
	$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
14371
	$conf["allowUnmask"]="false";
14372
	#參考資料
14373
	#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
14374
	#https://tools.ietf.org/html/rfc6455
14375
	#https://tools.ietf.org/html/rfc5234
14376
	#備註:
14377
	#無.
14378
	*/
14379
	public static function mask(&$conf){
226 liveuser 14380
 
3 liveuser 14381
		#改呼叫 webSock::umask
14382
		return webSock::unmask($conf);
226 liveuser 14383
 
3 liveuser 14384
		}#function mask end
226 liveuser 14385
 
3 liveuser 14386
	/*
14387
	#函式說明:
14388
	#將 handshake 後含有 mask bit 的 web socket 訊息進行  mask/unmask.
14389
	#回傳結果:
14390
	#$result["function"],當前函式的名稱.
14391
	#$result["argu"],使用的參數.
14392
	#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
14393
	#$result["content"],unmask後的內容.
14394
	#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame.
14395
	#$result["error"],錯誤訊息陣列.
14396
	#必填參數:
14397
	#$conf["payload"],字串,要解密的訊息.
226 liveuser 14398
	$conf["payload"]="";
3 liveuser 14399
	#可省略參數:
14400
	#$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
14401
	#$conf["allowUnmask"]="false";
14402
	#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
14403
	#$conf["debug"]="false";
14404
	#參考資料
14405
	#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
14406
	#https://tools.ietf.org/html/rfc6455
14407
	#https://tools.ietf.org/html/rfc5234
14408
	#備註:
14409
	#無.
14410
	*/
14411
	public static function unmask(&$conf) {
226 liveuser 14412
 
3 liveuser 14413
		#初始化要回傳的結果
14414
		$result=array();
14415
 
14416
		#取得當前執行的函數名稱
14417
		$result["function"]=__FUNCTION__;
226 liveuser 14418
 
3 liveuser 14419
		#取得參數內容
14420
		$result["argu"]=$conf;
226 liveuser 14421
 
3 liveuser 14422
		#檢查參數
14423
		#函式說明:
14424
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
14425
		#回傳結果:
14426
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
14427
		#$result["error"],執行不正常結束的錯訊息陣列.
14428
		#$result["simpleError"],簡單表示的錯誤訊息.
14429
		#$result["function"],當前執行的函式名稱.
14430
		#$result["argu"],設置給予的參數.
14431
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
14432
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
14433
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
14434
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
14435
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
14436
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
14437
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
14438
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
14439
		#必填參數:
14440
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
14441
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
14442
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
14443
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
14444
		#可省略參數:
14445
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
14446
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("payload");
14447
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
14448
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
14449
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
14450
		#$conf["canBeEmptyString"]="false";
14451
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
14452
		#$conf["canNotBeEmpty"]=array();
14453
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
14454
		#$conf["canBeEmpty"]=array();
14455
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
14456
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("allowUnmask","debug");
14457
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
14458
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("allowUnmask","debug");
14459
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
14460
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
14461
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
14462
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("false","false");
14463
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
14464
		#$conf["variableCheck::checkArguments"]["disallowAllSkipableVarIsEmpty"]="";
14465
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
14466
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
14467
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
14468
		#$conf["disallowAllSkipableVarNotExist"]="";
14469
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
14470
		#$conf["arrayCountEqualCheck"][]=array();
14471
		#參考資料:
14472
		#array_keys=>http://php.net/manual/en/function.array-keys.php
14473
		#備註:
14474
		#無.
14475
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
14476
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 14477
 
3 liveuser 14478
		#如果檢查參數失敗
14479
		if($checkArguments["status"]==="false"){
226 liveuser 14480
 
3 liveuser 14481
			#設置執行不正常
14482
			$result["status"]="false";
226 liveuser 14483
 
3 liveuser 14484
			#設置錯誤訊息
14485
			$result["error"]=$checkArguments;
226 liveuser 14486
 
3 liveuser 14487
			#回傳結果
14488
			return $result;
226 liveuser 14489
 
3 liveuser 14490
			}#if end
226 liveuser 14491
 
3 liveuser 14492
		#如果檢查參數不通過
14493
		if($checkArguments["passed"]==="false"){
226 liveuser 14494
 
3 liveuser 14495
			#設置執行不正常
14496
			$result["status"]="false";
226 liveuser 14497
 
3 liveuser 14498
			#設置錯誤訊息
14499
			$result["error"]=$checkArguments;
226 liveuser 14500
 
3 liveuser 14501
			#回傳結果
14502
			return $result;
226 liveuser 14503
 
3 liveuser 14504
			}#if end
226 liveuser 14505
 
3 liveuser 14506
		#取得變數
14507
		$payload=$conf["payload"];
226 liveuser 14508
 
3 liveuser 14509
		#如果要debug
14510
		if($conf["debug"]==="true"){
226 liveuser 14511
 
3 liveuser 14512
			#debug payload length
14513
			echo __LINE__." strlen(\$payload)=".strlen($payload).PHP_EOL;
226 liveuser 14514
 
3 liveuser 14515
			}#if end
226 liveuser 14516
 
3 liveuser 14517
		#web socket frame 最少為 2bytes
14518
		if(strlen($payload)<2){
226 liveuser 14519
 
3 liveuser 14520
			#函式說明:
14521
			#將字串中的每個字變成hex的字串陣列
14522
			#回傳結果:
14523
			#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
14524
			#$result["function"],當前執行的函式內容.
14525
			#$result["error"],錯誤訊息陣列.
14526
			#$result["content"],hex的字串陣列.
14527
			#必填參數:
14528
			#$conf["input"],字串,要轉換成bytes陣列的字串.
14529
			$conf["stringProcess::str2bytesArray"]["input"]=$payload;
14530
			#可省略參數:
14531
			#無.
14532
			#參考資料:
14533
			#無.
14534
			#備註:
14535
			#無.
14536
			$str2bytesArray=stringProcess::str2bytesArray($conf["stringProcess::str2bytesArray"]);
14537
			unset($conf["stringProcess::str2bytesArray"]);
226 liveuser 14538
 
3 liveuser 14539
			#如果檢查參數失敗
14540
			if($str2bytesArray["status"]==="false"){
226 liveuser 14541
 
3 liveuser 14542
				#設置執行不正常
14543
				$result["status"]="false";
226 liveuser 14544
 
3 liveuser 14545
				#設置錯誤訊息
14546
				$result["error"]=$str2bytesArray;
226 liveuser 14547
 
3 liveuser 14548
				#回傳結果
14549
				return $result;
226 liveuser 14550
 
3 liveuser 14551
				}#if end
226 liveuser 14552
 
3 liveuser 14553
			#設置警告訊息
14554
			$result["warning"][]="web socket frame 最少為 2 bytes,目前收到得為 ".strlen($payload)." bytes";
226 liveuser 14555
 
3 liveuser 14556
			#設置警告訊息
14557
			$result["warning"][]="接收到的 web socket frame 內容";
226 liveuser 14558
 
3 liveuser 14559
			#設置警告訊息
14560
			$result["warning"][]="(ASCII):".$payload;
226 liveuser 14561
 
3 liveuser 14562
			#開始截取輸出
14563
			ob_start();
226 liveuser 14564
 
3 liveuser 14565
			#針對每個bytes
14566
			for($i=0;$i<count($str2bytesArray["content"]);$i++){
226 liveuser 14567
 
3 liveuser 14568
				#印出其內容
14569
				echo "[".$str2bytesArray["content"][$i]."]";
226 liveuser 14570
 
3 liveuser 14571
				#若不是最後一個byte
14572
				if($i===count($str2bytesArray["content"])-1){
226 liveuser 14573
 
3 liveuser 14574
					#空一格
14575
					echo " ";
226 liveuser 14576
 
3 liveuser 14577
					}#if end
226 liveuser 14578
 
3 liveuser 14579
				}#if end
226 liveuser 14580
 
3 liveuser 14581
			#取得用HEX表示的內容
14582
			$hexStr=ob_get_contents();
226 liveuser 14583
 
3 liveuser 14584
			#結束截取輸出
14585
			ob_end_clean();
226 liveuser 14586
 
3 liveuser 14587
			#設置警告訊息
14588
			$result["warning"][]="(HEX):".$hexStr;
226 liveuser 14589
 
3 liveuser 14590
			#設置為非 web socket frame
14591
			$result["type"]="invalid";
226 liveuser 14592
 
3 liveuser 14593
			#設置執行正常
14594
			$result["status"]="true";
226 liveuser 14595
 
3 liveuser 14596
			#回傳結果
14597
			return $result;
226 liveuser 14598
 
3 liveuser 14599
			}#if end
226 liveuser 14600
 
3 liveuser 14601
		#如果要debug
14602
		if($conf["debug"]==="true"){
226 liveuser 14603
 
3 liveuser 14604
			#debug data length
14605
			echo __LINE__." \$length=".(ord($payload[1]) & 127).PHP_EOL;
226 liveuser 14606
 
3 liveuser 14607
			}#if end
226 liveuser 14608
 
3 liveuser 14609
		#取得字串長度
14610
		$psl=strlen($payload);
226 liveuser 14611
 
3 liveuser 14612
		#初始化儲存每個bytes
14613
		$bytes=array();
226 liveuser 14614
 
3 liveuser 14615
		#函式說明:
14616
		#將字串中的每個字變成bytes陣列
14617
		#回傳結果:
14618
		#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
14619
		#$result["function"],當前執行的函式內容.
14620
		#$result["error"],錯誤訊息陣列.
14621
		#$result["content"],hex的字串陣列.
14622
		#必填參數:
14623
		#$conf["input"],字串,要轉換成bytes陣列的字串
14624
		$conf["stringProcess::str2bytesArray"]["input"]=$payload;
14625
		#可省略參數:
14626
		#無
14627
		$str2bytesArray=stringProcess::str2bytesArray($conf["stringProcess::str2bytesArray"]);
14628
		unset($conf["stringProcess::str2bytesArray"]);
226 liveuser 14629
 
3 liveuser 14630
		#如果執行失敗
14631
		if($str2bytesArray["status"]==="false"){
226 liveuser 14632
 
3 liveuser 14633
			#設置執行不正常
14634
			$result["status"]="false";
226 liveuser 14635
 
3 liveuser 14636
			#設置錯誤訊息
14637
			$result["error"]=$str2bytesArray;
226 liveuser 14638
 
3 liveuser 14639
			#回傳結果
14640
			return $result;
226 liveuser 14641
 
3 liveuser 14642
			}#if end
226 liveuser 14643
 
3 liveuser 14644
		#針對每個bytes
14645
		foreach($str2bytesArray["content"] as $bytesNum => $oneByte){
226 liveuser 14646
 
3 liveuser 14647
			#函式說明:
14648
			#將bytes數字轉換為bit陣列(0跟1來表述)
14649
			#回傳結果:
14650
			#$result...
14651
			#必填參數:
14652
			#$conf["input"],字串,要轉換成byte的字串
14653
			$conf["stringProcess::bytes2byte"]["bytes"]=$oneByte;
14654
			#可省略參數:
14655
			#無
14656
			$bytes2byte=stringProcess::bytes2bitString($conf["stringProcess::bytes2byte"]);
14657
			unset($conf["stringProcess::bytes2byte"]);
226 liveuser 14658
 
3 liveuser 14659
			#儲存bytes與其bit
14660
			$bytes[$bytesNum]["content"]=$bytes2byte["content"];
226 liveuser 14661
 
3 liveuser 14662
			}#foreach end
226 liveuser 14663
 
3 liveuser 14664
		#frame-fin 1 bit
14665
		#%x0 ; more frames of this message follow
14666
		#%x1 ; final frame of this message
14667
		$frameFin=$bytes[0]["content"][0];
14668
 
14669
		#如果不是最後一個 frame
14670
		if($frameFin==="0"){
226 liveuser 14671
 
3 liveuser 14672
			#如果要debug
14673
			if($conf["debug"]==="true"){
226 liveuser 14674
 
3 liveuser 14675
				#debug
14676
				echo __LINE__." frame-fin = 0, not supported".PHP_EOL;
226 liveuser 14677
 
3 liveuser 14678
				}#if end
226 liveuser 14679
 
3 liveuser 14680
			#設置警告訊息
14681
			$result["warning"][]="目前不支援大於一個frame的mask/unmask功能";
226 liveuser 14682
 
3 liveuser 14683
			#設置警告訊息
14684
			$result["warning"][]=$bytes;
226 liveuser 14685
 
3 liveuser 14686
			#設置為非 web socket frame
14687
			$result["type"]="invalid";
226 liveuser 14688
 
3 liveuser 14689
			#設置執行正常
14690
			$result["status"]="true";
226 liveuser 14691
 
3 liveuser 14692
			#回傳結果
14693
			return $result;
226 liveuser 14694
 
3 liveuser 14695
			}#if end
226 liveuser 14696
 
3 liveuser 14697
		#反之是最後一個 data frame
14698
		else{
226 liveuser 14699
 
3 liveuser 14700
			#如果要debug
14701
			if($conf["debug"]==="true"){
226 liveuser 14702
 
3 liveuser 14703
				#debug
14704
				echo __LINE__." frame-fin = 1, means this is a last data frame".PHP_EOL;
226 liveuser 14705
 
3 liveuser 14706
				}#if end
226 liveuser 14707
 
3 liveuser 14708
			}#else end
226 liveuser 14709
 
3 liveuser 14710
		#frame-rsv1 1 bit
14711
		#MUST be 0 unless negotiated otherwise
14712
		$frameRsv1=$bytes[0]["content"][1];
226 liveuser 14713
 
3 liveuser 14714
		#frame-rsv2 1 bit
14715
		#MUST be 0 unless negotiated otherwise
14716
		$frameRsv2=$bytes[0]["content"][2];
226 liveuser 14717
 
3 liveuser 14718
		#frame-rsv3 1 bit
14719
		#MUST be 0 unless negotiated otherwise
14720
		$frameRsv3=$bytes[0]["content"][3];
226 liveuser 14721
 
3 liveuser 14722
		#如果bit[1~3]都為0
14723
		if($frameRsv1===$frameRsv2 && $frameRsv2===$frameRsv3 && $frameRsv3==="0"){
226 liveuser 14724
 
3 liveuser 14725
			#如果要debug
14726
			if($conf["debug"]==="true"){
226 liveuser 14727
 
3 liveuser 14728
				#debug
14729
				echo __LINE__." frame-rsv1~3 = 0".PHP_EOL;
226 liveuser 14730
 
3 liveuser 14731
				}#if end
226 liveuser 14732
 
3 liveuser 14733
			}#if end
226 liveuser 14734
 
3 liveuser 14735
		#如果不存在第5個bit
14736
		if(!isset($bytes[0]["content"][4])){
226 liveuser 14737
 
3 liveuser 14738
			#如果要debug
14739
			if($conf["debug"]==="true"){
226 liveuser 14740
 
3 liveuser 14741
				#debug
14742
				echo __LINE__." $bytes[0]['content'][4] not set!".PHP_EOL;
226 liveuser 14743
 
3 liveuser 14744
				}#if end
226 liveuser 14745
 
3 liveuser 14746
			}#if end
226 liveuser 14747
 
3 liveuser 14748
		/*
14749
		frame-opcode 4 bit
14750
		frame-opcode-cont       = %x0 ; frame continuation
14751
 
14752
		frame-opcode-non-control= %x1 ; text frame
14753
					/ %x2 ; binary frame
14754
					/ %x3-7
14755
					; 4 bits in length,
14756
					; reserved for further non-control frames
14757
 
14758
		frame-opcode-control    = %x8 ; connection close
14759
					/ %x9 ; ping
14760
					/ %xA ; pong
14761
					/ %xB-F ; reserved for further control
14762
					; frames
14763
					; 4 bits in length
14764
		*/
14765
		#如果 bytes[0] 長度不足 8
14766
		if(gettype($bytes[0]["content"])==="array"){
226 liveuser 14767
 
3 liveuser 14768
			if(count($bytes[0]["content"])!==8){
226 liveuser 14769
 
3 liveuser 14770
				#$i為4~7
14771
				for($i=4;$i<8;$i++){
226 liveuser 14772
 
3 liveuser 14773
					#如果未設置
14774
					if(!isset($bytes[0]["content"][$i])){
226 liveuser 14775
 
3 liveuser 14776
						#用 "0" 去補
14777
						$bytes[0]["content"][$i]="0";
226 liveuser 14778
 
3 liveuser 14779
						}#if end
226 liveuser 14780
 
3 liveuser 14781
					}#for end
226 liveuser 14782
 
3 liveuser 14783
				}#if end
226 liveuser 14784
 
3 liveuser 14785
			}#if end
226 liveuser 14786
 
3 liveuser 14787
		$frameOpcode=$bytes[0]["content"][4].$bytes[0]["content"][5].$bytes[0]["content"][6].$bytes[0]["content"][7];
226 liveuser 14788
 
3 liveuser 14789
		#如果要debug
14790
		if($conf["debug"]==="true"){
226 liveuser 14791
 
3 liveuser 14792
			#debug
14793
			echo __LINE__." frame-opcode = ".$frameOpcode.PHP_EOL;
226 liveuser 14794
 
3 liveuser 14795
			}#if end
226 liveuser 14796
 
14797
		$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);
14798
 
3 liveuser 14799
		#設置預設訊息類型為 unknow
14800
		$result["type"]="unknow";
226 liveuser 14801
 
3 liveuser 14802
		#如果 Opcode 等於 1
14803
		if($frameOpcodeIntX===1){
226 liveuser 14804
 
3 liveuser 14805
			#如果要debug
14806
			if($conf["debug"]==="true"){
226 liveuser 14807
 
3 liveuser 14808
				#debug
14809
				echo "It is a text frame".PHP_EOL;
226 liveuser 14810
 
3 liveuser 14811
				}#if end
226 liveuser 14812
 
3 liveuser 14813
			#設置該訊息類型為 text
14814
			$result["type"]="text";
226 liveuser 14815
 
3 liveuser 14816
			}#if end
226 liveuser 14817
 
3 liveuser 14818
		#如果 Opcode 等於 9
14819
		else if($frameOpcodeIntX===9){
226 liveuser 14820
 
3 liveuser 14821
			#如果要debug
14822
			if($conf["debug"]==="true"){
226 liveuser 14823
 
3 liveuser 14824
				#debug
14825
				echo "It is a ping frame".PHP_EOL;
226 liveuser 14826
 
3 liveuser 14827
				}#if end
226 liveuser 14828
 
3 liveuser 14829
			#設置該訊息類型為 text
14830
			$result["type"]="ping";
226 liveuser 14831
 
3 liveuser 14832
			}#if end
226 liveuser 14833
 
3 liveuser 14834
		#如果是 pong
14835
		else if($frameOpcodeIntX===10){
226 liveuser 14836
 
3 liveuser 14837
			#如果要debug
14838
			if($conf["debug"]==="true"){
226 liveuser 14839
 
3 liveuser 14840
				#debug
14841
				echo "It is a pong frame".PHP_EOL;
14842
 
14843
				}#if end
14844
 
14845
			#設置該訊息類型為 pong
14846
			$result["type"]="pong";
226 liveuser 14847
 
3 liveuser 14848
			}#if end
226 liveuser 14849
 
3 liveuser 14850
		#frame-masked 1 bit
14851
		#%x0 ;frame is not masked, no frame-masking-key
14852
		#%x1 ;frame is masked, frame-masking-key present 1 bit in lengt
226 liveuser 14853
		$frameMasked=$bytes[1]["content"][0];
14854
 
3 liveuser 14855
		#預設收到的訊息有mask過.
226 liveuser 14856
		$masked=true;
14857
 
14858
		#如果沒有 masked
3 liveuser 14859
		if($frameMasked!=='1'){
226 liveuser 14860
 
14861
			#如果不允許沒有設置 masked bit
3 liveuser 14862
			if($conf["allowUnmask"]!=="true"){
226 liveuser 14863
 
3 liveuser 14864
				#如果要debug
14865
				if($conf["debug"]==="true"){
226 liveuser 14866
 
3 liveuser 14867
					#debug
14868
					echo __LINE__." frame-masked !== 1, differ with https://tools.ietf.org/html/rfc6455#section-5.3".PHP_EOL;
226 liveuser 14869
 
3 liveuser 14870
					}#if end
226 liveuser 14871
 
3 liveuser 14872
				#設置為非 web socket frame
14873
				$result["type"]="invalid";
226 liveuser 14874
 
3 liveuser 14875
				#設置執行正常
14876
				$result["status"]="true";
226 liveuser 14877
 
3 liveuser 14878
				#回傳結果
14879
				return $result;
226 liveuser 14880
 
3 liveuser 14881
				}#if end
226 liveuser 14882
 
3 liveuser 14883
			#設置收到的訊息沒有mask過.
14884
			$masked=false;
226 liveuser 14885
 
3 liveuser 14886
			}#if end
226 liveuser 14887
 
3 liveuser 14888
		#debug
14889
		#echo __LINE__." frame-masked = ".$frameMasked.PHP_EOL;
226 liveuser 14890
 
3 liveuser 14891
		#frame-payload-length 7 bit, 7+16 bits, or 7+64 bits
14892
		/*
14893
		The length of the "Payload data", in bytes: if 0-125, that is the
14894
		payload length.  If 126, the following 2 bytes interpreted as a
14895
		16-bit unsigned integer are the payload length.  If 127, the
14896
		following 8 bytes interpreted as a 64-bit unsigned integer (the
14897
		most significant bit MUST be 0) are the payload length.  Multibyte
14898
		length quantities are expressed in network byte order.  Note that
14899
		in all cases, the minimal number of bytes MUST be used to encode
14900
		the length, for example, the length of a 124-byte-long string
14901
		can't be encoded as the sequence 126, 0, 124.  The payload length
14902
		is the length of the "Extension data" + the length of the
14903
		"Application data".  The length of the "Extension data" may be
14904
		zero, in which case the payload length is the length of the
14905
		"Application data".
14906
		*/
14907
		if(gettype($bytes[1]["content"])==="array"){
226 liveuser 14908
 
14909
			if(count($bytes[1]["content"])!==8){
14910
 
3 liveuser 14911
				#如果要debug
14912
				if($conf["debug"]==="true"){
226 liveuser 14913
 
3 liveuser 14914
					#debug
14915
					echo __LINE__." payloadLengthBit length !== 8".PHP_EOL;
226 liveuser 14916
 
3 liveuser 14917
					}#if end
226 liveuser 14918
 
3 liveuser 14919
				#如果 bit 不存在,用 0 補上
14920
				for($i=1;$i<8;$i++){
226 liveuser 14921
 
3 liveuser 14922
					#如果未設置
14923
					if(!isset($bytes[1]["content"][$i])){
226 liveuser 14924
 
3 liveuser 14925
						#用"0"替代
14926
						$bytes[1]["content"][$i]="0";
226 liveuser 14927
 
3 liveuser 14928
						}#if end
226 liveuser 14929
 
3 liveuser 14930
					}#for end
226 liveuser 14931
 
3 liveuser 14932
				#代表是用戶在連線.
14933
				#return "client connected!";
226 liveuser 14934
 
3 liveuser 14935
				}#if end
226 liveuser 14936
 
3 liveuser 14937
			}#if end
226 liveuser 14938
 
3 liveuser 14939
		$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 14940
 
3 liveuser 14941
		#length from 0~127(0~125)
14942
		$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 14943
 
3 liveuser 14944
		#如果長度小於 126
14945
		if($payloadLength<126){
226 liveuser 14946
 
14947
			#mask bit start bytes index
3 liveuser 14948
			$maskBitStartBytesIndex=2;
226 liveuser 14949
 
3 liveuser 14950
			#如果要debug
14951
			if($conf["debug"]==="true"){
226 liveuser 14952
 
3 liveuser 14953
				#debug
14954
				echo __LINE__." mask bit start bytes index = ".$maskBitStartBytesIndex.PHP_EOL;
226 liveuser 14955
 
3 liveuser 14956
				}#if end
226 liveuser 14957
 
3 liveuser 14958
			}#if end
226 liveuser 14959
 
3 liveuser 14960
		#如果長度是 126
14961
		if($payloadLength===126){
226 liveuser 14962
 
3 liveuser 14963
			$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 14964
 
3 liveuser 14965
			#初始化 payload 長度
14966
			$payloadLength=0;
226 liveuser 14967
 
3 liveuser 14968
			#2次迴圈,兩個bytes
14969
			for($i=0;$i<2;$i++){
226 liveuser 14970
 
3 liveuser 14971
				#8次迴圈,1個byte等於8個bit
14972
				for($j=0;$j<8;$j++){
226 liveuser 14973
 
3 liveuser 14974
					#次方數
14975
					$k=$j+8*$i;
226 liveuser 14976
 
3 liveuser 14977
					#加總 payload 長度
14978
					$payloadLength=$payloadLength+$bytes[3-$i]["content"][7-$j]*pow(2,$k);
226 liveuser 14979
 
3 liveuser 14980
					}#for end
226 liveuser 14981
 
3 liveuser 14982
				}#for end
226 liveuser 14983
 
14984
			#mask bit start bytes index
3 liveuser 14985
			$maskBitStartBytesIndex=4;
226 liveuser 14986
 
3 liveuser 14987
			#如果要debug
14988
			if($conf["debug"]==="true"){
226 liveuser 14989
 
3 liveuser 14990
				#debug
14991
				echo __LINE__." mask bit start bytes index = ".$maskBitStartBytesIndex.PHP_EOL;
226 liveuser 14992
 
3 liveuser 14993
				}#if end
226 liveuser 14994
 
3 liveuser 14995
			}#if end
226 liveuser 14996
 
14997
		#如果長度是 127
3 liveuser 14998
		else if($payloadLength===127){
226 liveuser 14999
 
3 liveuser 15000
			$payloadLengthBit="";
226 liveuser 15001
 
3 liveuser 15002
			#四次迴圈(4個bytes)
15003
			for($i=0;$i<4;$i++){
226 liveuser 15004
 
3 liveuser 15005
				#8次迴圈,1個byte等於8個bit
15006
				for($j=0;$j<8;$j++){
226 liveuser 15007
 
3 liveuser 15008
					$payloadLengthBit=$payloadLengthBit.$bytes[4+$i]["content"][0+$j];
226 liveuser 15009
 
3 liveuser 15010
					}#for end
226 liveuser 15011
 
3 liveuser 15012
				}#for end
226 liveuser 15013
 
3 liveuser 15014
			#初始化 payload 長度
15015
			$payloadLength=0;
226 liveuser 15016
 
3 liveuser 15017
			#四次迴圈(4個bytes)
15018
			for($i=0;$i<4;$i++){
226 liveuser 15019
 
3 liveuser 15020
				#8次迴圈,1個byte等於8個bit
15021
				for($j=0;$j<8;$j++){
226 liveuser 15022
 
3 liveuser 15023
					#次方數
15024
					$k=$j+8*$i;
226 liveuser 15025
 
3 liveuser 15026
					$payloadLength=$payloadLength+$bytes[7-$i]["content"][7-$j]*pow(2,$k);
226 liveuser 15027
 
3 liveuser 15028
					}#for end
226 liveuser 15029
 
3 liveuser 15030
				}#for end
226 liveuser 15031
 
15032
			#mask bit start bytes index
3 liveuser 15033
			$maskBitStartBytesIndex=8;
226 liveuser 15034
 
3 liveuser 15035
			#如果要debug
15036
			if($conf["debug"]==="true"){
226 liveuser 15037
 
3 liveuser 15038
				#debug
15039
				echo __LINE__." mask bit start bytes index = ".$maskBitStartBytesIndex.PHP_EOL;
226 liveuser 15040
 
3 liveuser 15041
				}#if end
226 liveuser 15042
 
15043
			}#if end
15044
 
3 liveuser 15045
		#如果要debug
15046
		if($conf["debug"]==="true"){
226 liveuser 15047
 
3 liveuser 15048
			#debug
15049
			var_dump(__LINE__,$bytes);
226 liveuser 15050
 
3 liveuser 15051
			#debug 提示payload的長度的2進位表示法
226 liveuser 15052
			echo __LINE__." payload data payloadLengthBit is ".$payloadLengthBit.PHP_EOL;
15053
 
3 liveuser 15054
			#debug 提示payload的長度
15055
			echo __LINE__." payload data length is ".$payloadLength." bytes".PHP_EOL;
226 liveuser 15056
 
3 liveuser 15057
			}#if end
226 liveuser 15058
 
3 liveuser 15059
		#如果有mask
15060
		if($masked){
226 liveuser 15061
 
3 liveuser 15062
			#組合 maskBit 字串
15063
			$maskBitStr=
15064
				chr(base_convert($bytes[$maskBitStartBytesIndex]["content"],2,10)).
15065
				chr(base_convert($bytes[$maskBitStartBytesIndex+1]["content"],2,10)).
15066
				chr(base_convert($bytes[$maskBitStartBytesIndex+2]["content"],2,10)).
15067
				chr(base_convert($bytes[$maskBitStartBytesIndex+3]["content"],2,10));
226 liveuser 15068
 
3 liveuser 15069
			#如果要debug
15070
			if($conf["debug"]==="true"){
226 liveuser 15071
 
3 liveuser 15072
				#debug 提示 mask bit 字串
15073
				echo __LINE__." maskBit str is ".$maskBitStr.PHP_EOL;
226 liveuser 15074
 
3 liveuser 15075
				}#if end
226 liveuser 15076
 
3 liveuser 15077
			}#if end
226 liveuser 15078
 
3 liveuser 15079
		#初始化 payload data 字串
15080
		$payloadDataStr="";
226 liveuser 15081
 
3 liveuser 15082
		#如果有mask
15083
		if($masked){
226 liveuser 15084
 
3 liveuser 15085
			#有多長就跑幾次
15086
			for($i=0;$i<$payloadLength;$i++){
226 liveuser 15087
 
3 liveuser 15088
				#串接 masked 的 payload data.
15089
				$payloadDataStr=$payloadDataStr.chr(base_convert($bytes[$maskBitStartBytesIndex+4+$i]["content"],2,10));
226 liveuser 15090
 
3 liveuser 15091
				}#for end
226 liveuser 15092
 
3 liveuser 15093
			#如果要debug
15094
			if($conf["debug"]==="true"){
226 liveuser 15095
 
3 liveuser 15096
				#debug 提示 mask bit 字串
15097
				echo __LINE__." masked payload data str is ".$payloadDataStr.PHP_EOL;
226 liveuser 15098
 
3 liveuser 15099
				}#if end
226 liveuser 15100
 
3 liveuser 15101
			#unmask payload data
15102
			for($i=0;$i<$payloadLength;$i++){
226 liveuser 15103
 
3 liveuser 15104
				$payloadDataStr[$i]=$payloadDataStr[$i]^$maskBitStr[$i%4];
226 liveuser 15105
 
3 liveuser 15106
				}#for end
226 liveuser 15107
 
3 liveuser 15108
			}#if end
226 liveuser 15109
 
3 liveuser 15110
		#反之
15111
		else{
226 liveuser 15112
 
3 liveuser 15113
			#有多長就跑幾次
15114
			for($i=0;$i<$payloadLength;$i++){
226 liveuser 15115
 
3 liveuser 15116
				#串接 masked 的 payload data.
15117
				$payloadDataStr=$payloadDataStr.chr(base_convert($bytes[$maskBitStartBytesIndex+$i]["content"],2,10));
226 liveuser 15118
 
3 liveuser 15119
				}#for end
226 liveuser 15120
 
3 liveuser 15121
			}#else end
226 liveuser 15122
 
3 liveuser 15123
		#取得 umask 後的內容
15124
		$result["content"]=$payloadDataStr;
226 liveuser 15125
 
3 liveuser 15126
		#設置執行正常
15127
		$result["status"]="true";
226 liveuser 15128
 
15129
		#回傳結果
3 liveuser 15130
		return $result;
226 liveuser 15131
 
3 liveuser 15132
		}#function unmask end
15133
 
15134
	/*
15135
	#函式說明:
226 liveuser 15136
	#加密 handshake 後要傳送的 webSocket 訊息
3 liveuser 15137
	#回傳結果:
15138
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
15139
	#$result["error"],執行不正常結束的錯訊息陣列.
15140
	#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
15141
	#$result["argu"],陣列,使用的參數.
15142
	#必填參數:
15143
	#$conf["text"],字串,要加密的訊息.
226 liveuser 15144
	$conf["text"]="";
3 liveuser 15145
	#可省略參數:
15146
	#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
15147
	#$conf["payloadIsBin"]="false";
15148
	#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
15149
	#$conf["ping"]="false";
15150
	#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
15151
	#$conf["pong"]="false";
15152
	#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
15153
	#$conf["frames"]=array();
15154
	#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
15155
	#$conf["mask"]="false";
15156
	#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
15157
	#$conf["debug"]="false";
15158
	#參考資料:
15159
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
15160
	#備註:
15161
	#無.
15162
	*/
15163
	public static function encode(&$conf){
226 liveuser 15164
 
3 liveuser 15165
		#初始化要回傳的結果
15166
		$result=array();
15167
 
15168
		#設置當其函數名稱
15169
		$result["function"]=__FUNCTION__;
226 liveuser 15170
 
3 liveuser 15171
		#初始化分割好的 web socket 封包
15172
		$result["content"]=array();
15173
 
15174
		#如果 $conf 不為陣列
15175
		if(gettype($conf)!="array"){
15176
 
15177
			#設置執行失敗
15178
			$result["status"]="false";
15179
 
15180
			#設置執行錯誤訊息
15181
			$result["error"][]="\$conf變數須為陣列形態";
15182
 
15183
			#如果傳入的參數為 null
15184
			if($conf==null){
15185
 
15186
				#設置執行錯誤訊息
15187
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
15188
 
15189
				}#if end
226 liveuser 15190
 
3 liveuser 15191
			}#if end
226 liveuser 15192
 
3 liveuser 15193
		#設置放置的參數
15194
		$result["argu"]=$conf;
226 liveuser 15195
 
3 liveuser 15196
		#函式說明:
15197
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
15198
		#回傳結果:
15199
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
15200
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
15201
		#$result["simpleError"],簡單表示的錯誤訊息.
15202
		#$result["function"],當前執行的函式名稱.
15203
		#$result["argu"],設置給予的參數.
15204
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
15205
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
15206
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
15207
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
15208
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
15209
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
15210
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
15211
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
15212
		#必填參數:
15213
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
15214
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
15215
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
15216
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
15217
		#可省略參數:
15218
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
15219
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("text");
15220
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
15221
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
15222
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
15223
		#$conf["canBeEmptyString"]="false";
15224
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
15225
		#$conf["canNotBeEmpty"]=array();
15226
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
15227
		#$conf["canBeEmpty"]=array();
15228
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
15229
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("payloadIsBin","ping","pong","mask","debug");
15230
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
15231
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("payloadIsBin","ping","pong","frames","mask","debug");
15232
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
15233
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","array","string","string");
15234
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
15235
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("false","false","false",array(),"false","false");
15236
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
15237
		$conf["variableCheck::checkArguments"]["disallowAllSkipableVarIsEmpty"]="false";
15238
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
15239
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
15240
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
15241
		#$conf["arrayCountEqualCheck"][]=array();
15242
		#參考資料:
15243
		#array_keys=>http://php.net/manual/en/function.array-keys.php
15244
		#備註:
15245
		#無.
15246
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
15247
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 15248
 
3 liveuser 15249
		#如果執行失敗
15250
		if($checkArguments["status"]==="false"){
226 liveuser 15251
 
3 liveuser 15252
			#設置執行失敗
15253
			$result["status"]="false";
15254
 
15255
			#設置執行錯誤訊息
15256
			$result["error"]=$checkArguments;
226 liveuser 15257
 
3 liveuser 15258
			#回傳結果
15259
			return $result;
226 liveuser 15260
 
3 liveuser 15261
			}#if end
226 liveuser 15262
 
3 liveuser 15263
		#如果參數檢查不通過
15264
		if($checkArguments["passed"]==="false"){
226 liveuser 15265
 
3 liveuser 15266
			#設置執行失敗
15267
			$result["status"]="false";
15268
 
15269
			#設置執行錯誤訊息
15270
			$result["error"]=$checkArguments;
226 liveuser 15271
 
3 liveuser 15272
			#回傳結果
15273
			return $result;
226 liveuser 15274
 
3 liveuser 15275
			}#if end
226 liveuser 15276
 
3 liveuser 15277
		#如果是要產生 ping/pong 的訊息
15278
		if($conf["ping"]==="true" || $conf["pong"]==="true"){
226 liveuser 15279
 
3 liveuser 15280
			#強制將payload設置為空
15281
			$conf["text"]="";
226 liveuser 15282
 
3 liveuser 15283
			}#if end
226 liveuser 15284
 
3 liveuser 15285
		#取得payload
15286
		$text=$conf["text"];
226 liveuser 15287
 
3 liveuser 15288
		#取得 payload length
15289
		$length=strlen($text);
226 liveuser 15290
 
3 liveuser 15291
		#如果沒有payload
15292
		if($length===0){
226 liveuser 15293
 
3 liveuser 15294
			#初始化第一個 frame 為 最後一個 frame.
15295
			$header="1000";
226 liveuser 15296
 
3 liveuser 15297
			#如果是ping
15298
			if($conf["ping"]==="true"){
226 liveuser 15299
 
3 liveuser 15300
				#其訊息類別為 ping
15301
				$header=$header."1001";
226 liveuser 15302
 
3 liveuser 15303
				}#if end
226 liveuser 15304
 
3 liveuser 15305
			#如果是pong
15306
			else if($conf["pong"]==="true"){
226 liveuser 15307
 
3 liveuser 15308
				#其訊息類別為 pong
15309
				$header=$header."1010";
226 liveuser 15310
 
3 liveuser 15311
				}#if end
226 liveuser 15312
 
3 liveuser 15313
			#例外狀況
15314
			else{
226 liveuser 15315
 
3 liveuser 15316
				#設置執行失敗
15317
				$result["status"]="false";
15318
 
15319
				#設置執行錯誤訊息
15320
				$result["error"][]="參數 text 為空時,需要 ping or pong 參數擇一";
15321
 
15322
				#設置執行錯誤訊息
15323
				$result["error"][]=$checkArguments;
226 liveuser 15324
 
3 liveuser 15325
				#回傳結果
15326
				return $result;
226 liveuser 15327
 
3 liveuser 15328
				}#else end
226 liveuser 15329
 
3 liveuser 15330
			}#if end
226 liveuser 15331
 
3 liveuser 15332
		#反之有payload
15333
		else{
226 liveuser 15334
 
3 liveuser 15335
			#初始化第一個 frame 為 最後一個 frame.
15336
			$header="1000";
226 liveuser 15337
 
3 liveuser 15338
			#如果 payload 是 2元碼
15339
			if($conf["payloadIsBin"]==="true"){
226 liveuser 15340
 
3 liveuser 15341
				#設置 opecode 為 0010
15342
				$header=$header."0010";
226 liveuser 15343
 
3 liveuser 15344
				}#if end
226 liveuser 15345
 
3 liveuser 15346
			#反之為 text
15347
			else{
226 liveuser 15348
 
3 liveuser 15349
				#設置 opecode 為 0001
15350
				$header=$header."0001";
226 liveuser 15351
 
3 liveuser 15352
				}#else end
226 liveuser 15353
 
3 liveuser 15354
			}#else end
226 liveuser 15355
 
3 liveuser 15356
		#如果 payload 長度大於 125
15357
		while($length > 125){
226 liveuser 15358
 
15359
			#初始化第一個 frame 為 不為最後一個 frame,
3 liveuser 15360
			$header="0000";
226 liveuser 15361
 
3 liveuser 15362
			#如果 payload 是 2元碼
15363
			if($conf["payloadIsBin"]==="true"){
226 liveuser 15364
 
3 liveuser 15365
				#設置 opecode 為 0010
15366
				$header=$header."0010";
226 liveuser 15367
 
3 liveuser 15368
				}#if end
226 liveuser 15369
 
3 liveuser 15370
			#反之為 text
15371
			else{
226 liveuser 15372
 
3 liveuser 15373
				#設置 opecode 為 0001
15374
				$header=$header."0001";
226 liveuser 15375
 
3 liveuser 15376
				}#else end
226 liveuser 15377
 
3 liveuser 15378
			#如果已經有前面的內容了
15379
			if(count($result["content"])>0){
226 liveuser 15380
 
3 liveuser 15381
				#設置為中間的 frame, 其 opcode 為 continue data.
15382
				$header="00000000";
226 liveuser 15383
 
3 liveuser 15384
				}#if end
226 liveuser 15385
 
3 liveuser 15386
			#取得125bytes
15387
			$body=substr($text,0,125);
226 liveuser 15388
 
3 liveuser 15389
			#函式說明:
15390
			#將2進位的8位數字字串,變成bytes字串.
15391
			#回傳結果:
15392
			#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15393
			#$result["function"],當前執行的函式內容.
15394
			#$result["error"],錯誤訊息陣列.
15395
			#$result["content"],bytes字串,亦即其代表的一個字.
15396
			#必填參數:
15397
			#$conf["8bits"],字串,要轉換成byte字串的bit數字字串,小於8位會於前頭補0,若非2進位的bit數字字串,則會報錯.
15398
			$conf["stringProcess::bit2byteStr"]["8bits"]=$header;
15399
			#可省略參數:
15400
			#無.
15401
			#參考資料:
15402
			#無.
15403
			#備註:
15404
			#無.
15405
			$bit2byteStr=stringProcess::bit2byteStr($conf["stringProcess::bit2byteStr"]);
15406
			unset($conf["stringProcess::bit2byteStr"]);
226 liveuser 15407
 
3 liveuser 15408
			#如果執行失敗
15409
			if($bit2byteStr["status"]==="false"){
226 liveuser 15410
 
3 liveuser 15411
				#設置執行失敗
15412
				$result["status"]="false";
15413
 
15414
				#設置執行錯誤訊息
15415
				$result["error"]=$bit2byteStr;
226 liveuser 15416
 
3 liveuser 15417
				#回傳結果
15418
				return $result;
226 liveuser 15419
 
3 liveuser 15420
				}#if end
226 liveuser 15421
 
3 liveuser 15422
			#取得該 byte 字串
15423
			$headerInByte=$bit2byteStr["content"];
226 liveuser 15424
 
3 liveuser 15425
			#預設不用mask
15426
			$maskBitAndLengthIntString=(string)(125);
226 liveuser 15427
 
3 liveuser 15428
			#如果需要mask
15429
			if($conf["mask"]==="true"){
226 liveuser 15430
 
3 liveuser 15431
				$maskBitAndLengthIntString=(string)(125+128);
226 liveuser 15432
 
3 liveuser 15433
				}#if end
226 liveuser 15434
 
3 liveuser 15435
			#函式說明:
15436
			#將2進位的8位數字字串,變成bytes字串.
15437
			#回傳結果:
15438
			#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15439
			#$result["function"],當前執行的函式內容.
15440
			#$result["error"],錯誤訊息陣列.
15441
			#$result["content"],bytes字串,亦即其代表的一個字.
15442
			#必填參數:
15443
			#$conf["8bits"],字串,要轉換成byte字串的bit數字字串,小於8位會於前頭補0,若非2進位的bit數字字串,則會報錯.
15444
			$conf["stringProcess::bit2byteStr"]["8bits"]=base_convert($maskBitAndLengthIntString,10,2);
15445
			#可省略參數:
15446
			#無.
15447
			#參考資料:
15448
			#無.
15449
			#備註:
15450
			#無.
15451
			$bit2byteStr=stringProcess::bit2byteStr($conf["stringProcess::bit2byteStr"]);
15452
			unset($conf["stringProcess::bit2byteStr"]);
226 liveuser 15453
 
3 liveuser 15454
			#如果要 debug
15455
			if($conf["debug"]==="true"){
226 liveuser 15456
 
3 liveuser 15457
				#debug
15458
				var_dump(__LINE__,$bit2byteStr);
226 liveuser 15459
 
3 liveuser 15460
				}#if end
226 liveuser 15461
 
3 liveuser 15462
			#如果執行失敗
15463
			if($bit2byteStr["status"]==="false"){
226 liveuser 15464
 
3 liveuser 15465
				#設置執行失敗
15466
				$result["status"]="false";
15467
 
15468
				#設置執行錯誤訊息
15469
				$result["error"]=$bit2byteStr;
226 liveuser 15470
 
3 liveuser 15471
				#回傳結果
15472
				return $result;
226 liveuser 15473
 
3 liveuser 15474
				}#if end
226 liveuser 15475
 
3 liveuser 15476
			#取得該 byte 字串
15477
			$lengthInByte=$bit2byteStr["content"];
226 liveuser 15478
 
3 liveuser 15479
			#初始化 4 bytes mask key.
15480
			$maskKey4bytes="";
226 liveuser 15481
 
3 liveuser 15482
			#如果需要mask
15483
			if($conf["mask"]==="true"){
226 liveuser 15484
 
3 liveuser 15485
				#函式說明:
15486
				#隨機產生任意byte(s)組成的字串.
15487
				#回傳結果:
15488
				#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15489
				#$result["function"],當前執行的函式內容.
15490
				#$result["error"],錯誤訊息陣列.
15491
				#$result["content"],用字串來表示的byte(s).
15492
				#必填參數:
15493
				#無.
15494
				#可省略參數:
15495
				#$conf["length"],字串,要產生多少bytes的字串,預設為1.
15496
				$conf["stringProcess::randomByte"]["length"]="4";
15497
				#參考資料:
15498
				#無.
15499
				#備註:
15500
				#無.
15501
				$randomByte=stringProcess::randomByte($conf["stringProcess::randomByte"]);
15502
				unset($conf["stringProcess::randomByte"]);
226 liveuser 15503
 
3 liveuser 15504
				#如果執行失敗
15505
				if($randomByte["status"]==="false"){
226 liveuser 15506
 
3 liveuser 15507
					#設置執行失敗
15508
					$result["status"]="false";
15509
 
15510
					#設置執行錯誤訊息
15511
					$result["error"]=$randomByte;
226 liveuser 15512
 
3 liveuser 15513
					#回傳結果
15514
					return $result;
226 liveuser 15515
 
3 liveuser 15516
					}#if end
226 liveuser 15517
 
3 liveuser 15518
				#取得隨機產生的 mask key
15519
				$maskKey4bytes=$randomByte["content"];
226 liveuser 15520
 
3 liveuser 15521
				#函式說明:
15522
				#將 handshake 後含有 mask bit 的 web socket 訊息進行  mask/unmask.
15523
				#回傳結果:
15524
				#$result["function"],當前函式的名稱.
15525
				#$result["argu"],使用的參數.
15526
				#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
15527
				#$result["content"],unmask後的內容.
15528
				#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame.
15529
				#$result["error"],錯誤訊息陣列.
15530
				#必填參數:
15531
				#$conf["payload"],字串,要解密的訊息.
226 liveuser 15532
				$conf["webSock::unmask"]["payload"]=$headerInByte.$lengthInByte.$maskKey4bytes.$body;
3 liveuser 15533
				#可省略參數:
15534
				#$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
15535
				$conf["webSock::unmask"]["allowUnmask"]="true";
15536
				#參考資料
15537
				#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
15538
				#https://tools.ietf.org/html/rfc6455
15539
				#https://tools.ietf.org/html/rfc5234
15540
				#備註:
15541
				#無.
15542
				$unmask=webSock::unmask($conf["webSock::unmask"]);
15543
				unset($conf["webSock::unmask"]);
226 liveuser 15544
 
3 liveuser 15545
				#debug
15546
				#var_dump(__LINE__,$unmask);
226 liveuser 15547
 
3 liveuser 15548
				#如果執行失敗
15549
				if($unmask["status"]==="false"){
226 liveuser 15550
 
3 liveuser 15551
					#設置執行失敗
15552
					$result["status"]="false";
15553
 
15554
					#設置執行錯誤訊息
15555
					$result["error"]=$unmask;
226 liveuser 15556
 
3 liveuser 15557
					#回傳結果
15558
					return $result;
226 liveuser 15559
 
3 liveuser 15560
					}#if end
226 liveuser 15561
 
3 liveuser 15562
				#取得該段的結果
15563
				$result["content"][]=$headerInByte.$lengthInByte.$maskKey4bytes.$unmask["content"];
226 liveuser 15564
 
3 liveuser 15565
				}#if end
226 liveuser 15566
 
3 liveuser 15567
			#反之
15568
			else{
226 liveuser 15569
 
3 liveuser 15570
				#取得該段的結果
15571
				$result["content"][]=$headerInByte.$lengthInByte.$maskKey4bytes.$body;
226 liveuser 15572
 
3 liveuser 15573
				}#else end
226 liveuser 15574
 
3 liveuser 15575
			#取得剩下的內容
15576
			$text=substr($text,125);
226 liveuser 15577
 
3 liveuser 15578
			#取得 payload length
15579
			$length=strlen($text);
226 liveuser 15580
 
3 liveuser 15581
			}#while end
226 liveuser 15582
 
3 liveuser 15583
		#執行到這邊代表剩下的長度用一個 frame 即可表達
226 liveuser 15584
 
3 liveuser 15585
		#如果已經有內容了
15586
		if(count($result["content"])>0){
226 liveuser 15587
 
3 liveuser 15588
			#代表不用表示為 text frame 但要表示為最後一個 frame.
15589
			$header="10000000";
226 liveuser 15590
 
3 liveuser 15591
			}#if end
226 liveuser 15592
 
3 liveuser 15593
		#函式說明:
15594
		#將2進位的8位數字字串,變成bytes字串.
15595
		#回傳結果:
15596
		#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15597
		#$result["function"],當前執行的函式內容.
15598
		#$result["error"],錯誤訊息陣列.
15599
		#$result["content"],bytes字串,亦即其代表的一個字.
15600
		#必填參數:
15601
		#$conf["8bits"],字串,要轉換成byte字串的bit數字字串,小於8位會於前頭補0,若非2進位的bit數字字串,則會報錯.
15602
		$conf["stringProcess::bit2byteStr"]["8bits"]=$header;
15603
		#可省略參數:
15604
		#無.
15605
		#參考資料:
15606
		#無.
15607
		#備註:
15608
		#無.
15609
		$bit2byteStr=stringProcess::bit2byteStr($conf["stringProcess::bit2byteStr"]);
15610
		unset($conf["stringProcess::bit2byteStr"]);
226 liveuser 15611
 
3 liveuser 15612
		#如果執行失敗
15613
		if($bit2byteStr["status"]==="false"){
226 liveuser 15614
 
3 liveuser 15615
			#設置執行失敗
15616
			$result["status"]="false";
15617
 
15618
			#設置執行錯誤訊息
15619
			$result["error"]=$bit2byteStr;
226 liveuser 15620
 
3 liveuser 15621
			#回傳結果
15622
			return $result;
226 liveuser 15623
 
3 liveuser 15624
			}#if end
226 liveuser 15625
 
3 liveuser 15626
		#取得該 byte 字串
15627
		$headerInByte=$bit2byteStr["content"];
226 liveuser 15628
 
3 liveuser 15629
		#如果要 debug
15630
		if($conf["debug"]==="true"){
226 liveuser 15631
 
3 liveuser 15632
			#debug
15633
			var_dump(__LINE__,$length,base_convert($length,10,2));
226 liveuser 15634
 
3 liveuser 15635
			}#if end
226 liveuser 15636
 
3 liveuser 15637
		#如果需要mask
15638
		if($conf["mask"]==="true"){
226 liveuser 15639
 
3 liveuser 15640
			#增加maskbit
15641
			$length=$length+128;
226 liveuser 15642
 
3 liveuser 15643
			}#if end
226 liveuser 15644
 
3 liveuser 15645
		#函式說明:
15646
		#將2進位的8位數字字串,變成bytes字串.
15647
		#回傳結果:
15648
		#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15649
		#$result["function"],當前執行的函式內容.
15650
		#$result["error"],錯誤訊息陣列.
15651
		#$result["content"],bytes字串,亦即其代表的一個字.
15652
		#必填參數:
15653
		#$conf["8bits"],字串,要轉換成byte字串的bit數字字串,小於8位會於前頭補0,若非2進位的bit數字字串,則會報錯.
15654
		$conf["stringProcess::bit2byteStr"]["8bits"]=base_convert($length,10,2);
15655
		#可省略參數:
15656
		#無.
15657
		#參考資料:
15658
		#無.
15659
		#備註:
15660
		#無.
15661
		$bit2byteStr=stringProcess::bit2byteStr($conf["stringProcess::bit2byteStr"]);
15662
		unset($conf["stringProcess::bit2byteStr"]);
226 liveuser 15663
 
3 liveuser 15664
		#如果要 debug
15665
		if($conf["debug"]==="true"){
226 liveuser 15666
 
3 liveuser 15667
			#debug
15668
			var_dump(__LINE__,$bit2byteStr);
226 liveuser 15669
 
3 liveuser 15670
			}#if end
226 liveuser 15671
 
3 liveuser 15672
		#如果執行失敗
15673
		if($bit2byteStr["status"]==="false"){
226 liveuser 15674
 
3 liveuser 15675
			#設置執行失敗
15676
			$result["status"]="false";
15677
 
15678
			#設置執行錯誤訊息
15679
			$result["error"]=$bit2byteStr;
226 liveuser 15680
 
3 liveuser 15681
			#回傳結果
15682
			return $result;
226 liveuser 15683
 
3 liveuser 15684
			}#if end
226 liveuser 15685
 
3 liveuser 15686
		#取得該 byte 字串
15687
		$lengthInByte=$bit2byteStr["content"];
226 liveuser 15688
 
3 liveuser 15689
		#初始化 4 bytes mask key.
15690
		$maskKey4bytes="";
226 liveuser 15691
 
3 liveuser 15692
		#如果需要mask
15693
		if($conf["mask"]==="true"){
226 liveuser 15694
 
3 liveuser 15695
			#函式說明:
15696
			#隨機產生任意byte(s)組成的字串.
15697
			#回傳結果:
15698
			#$result["status"],執行正常與否,"false"代表不正常,"true"代表正常.
15699
			#$result["function"],當前執行的函式內容.
15700
			#$result["error"],錯誤訊息陣列.
15701
			#$result["content"],用字串來表示的byte(s).
15702
			#必填參數:
15703
			#無.
15704
			#可省略參數:
15705
			#$conf["length"],字串,要產生多少bytes的字串,預設為1.
15706
			$conf["stringProcess::randomByte"]["length"]="4";
15707
			#參考資料:
15708
			#無.
15709
			#備註:
15710
			#無.
15711
			$randomByte=stringProcess::randomByte($conf["stringProcess::randomByte"]);
15712
			unset($conf["stringProcess::randomByte"]);
226 liveuser 15713
 
3 liveuser 15714
			#如果執行失敗
15715
			if($randomByte["status"]==="false"){
226 liveuser 15716
 
3 liveuser 15717
				#設置執行失敗
15718
				$result["status"]="false";
15719
 
15720
				#設置執行錯誤訊息
15721
				$result["error"]=$randomByte;
226 liveuser 15722
 
3 liveuser 15723
				#回傳結果
15724
				return $result;
226 liveuser 15725
 
3 liveuser 15726
				}#if end
226 liveuser 15727
 
3 liveuser 15728
			#取得隨機產生的 mask key
15729
			$maskKey4bytes=$randomByte["content"];
226 liveuser 15730
 
3 liveuser 15731
			}#if end
226 liveuser 15732
 
3 liveuser 15733
		#函式說明:
15734
		#將 handshake 後含有 mask bit 的 web socket 訊息進行  mask/unmask.
15735
		#回傳結果:
15736
		#$result["function"],當前函式的名稱.
15737
		#$result["argu"],使用的參數.
15738
		#$result["status"],執行結果狀態,"true"代表正常;"false"代表不正常.
15739
		#$result["content"],unmask後的內容.
15740
		#$result["type"],訊息的類型,"unknow":代表未定義;"text":代表為文字訊息;"pong":代表為pong;"invalid":代表不為web socket frame.
15741
		#$result["error"],錯誤訊息陣列.
15742
		#必填參數:
15743
		#$conf["payload"],字串,要解密的訊息.
226 liveuser 15744
		$conf["webSock::unmask"]["payload"]=$headerInByte.$lengthInByte.$maskKey4bytes.$text;
3 liveuser 15745
		#可省略參數:
15746
		#$conf["allowUnmask"],字串,若發現沒有設置mask bit,也要繼續執行,則為"true";反之為"false".
15747
		$conf["webSock::unmask"]["allowUnmask"]="true";
15748
		#參考資料
15749
		#http://www.inanzzz.com/index.php/post/swf8/converting-string-to-binary-and-binary-to-string-with-php
15750
		#https://tools.ietf.org/html/rfc6455
15751
		#https://tools.ietf.org/html/rfc5234
15752
		#備註:
15753
		#無.
15754
		$unmask=webSock::unmask($conf["webSock::unmask"]);
15755
		unset($conf["webSock::unmask"]);
226 liveuser 15756
 
3 liveuser 15757
		#如果要 debug
15758
		if($conf["debug"]==="true"){
226 liveuser 15759
 
3 liveuser 15760
			#debug
15761
			var_dump(__LINE__,$unmask);
226 liveuser 15762
 
3 liveuser 15763
			}#if end
226 liveuser 15764
 
3 liveuser 15765
		#如果執行失敗
15766
		if($unmask["status"]==="false"){
226 liveuser 15767
 
3 liveuser 15768
			#設置執行失敗
15769
			$result["status"]="false";
15770
 
15771
			#設置執行錯誤訊息
15772
			$result["error"]=$unmask;
226 liveuser 15773
 
3 liveuser 15774
			#回傳結果
15775
			return $result;
226 liveuser 15776
 
3 liveuser 15777
			}#if end
226 liveuser 15778
 
3 liveuser 15779
		#儲存訊息
15780
		$result["content"][]=$headerInByte.$lengthInByte.$maskKey4bytes.$unmask["content"];
226 liveuser 15781
 
3 liveuser 15782
		#設置執行正常
15783
		$result["status"]="true";
226 liveuser 15784
 
3 liveuser 15785
		#回傳結果
15786
		return $result;
226 liveuser 15787
 
3 liveuser 15788
		}#function encode end
226 liveuser 15789
 
3 liveuser 15790
	/*
15791
	函式說明:
15792
	提供webSock::nativeSocketTcpIpServer的processFuncs參數所用的函式,可以接受要求傳遞檔案的內容給用戶.
15793
	#回傳結果:
15794
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
15795
	#$result["error"],執行不正常結束的錯訊息陣列.
15796
	#$result["argu"],陣列,使用的參數.
15797
	#必填參數:
15798
	#$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.
15799
	$conf["data"]="";
15800
	#$conf["serverSock"],resource,web socket server socket
15801
	$conf["serverSock"]=$resource;
15802
	#$conf["clientSock"],$resource,web socket client socket
15803
	$conf["clientSock"]=$resource;
15804
	#$conf["clientInfo"],陣列,web socket client info.
15805
	$conf["clientInfo"]=array();
15806
	#$conf["clientIndex"],整數.web socket client index.
15807
	$conf["clientIndex"];
15808
	#$conf["allConn"],陣列,all web socket client info.
15809
	$conf["allConn"]=array();
15810
	#可省略參數:
15811
	#無.
15812
	#參考資料:
15813
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
15814
	#備註:
15815
	#無.
15816
	*/
15817
	public static function getFileContent(&$conf){
226 liveuser 15818
 
3 liveuser 15819
		#初始化要回傳的結果
15820
		$result=array();
15821
 
15822
		#取得當前執行的函數名稱
15823
		$result["function"]=__FUNCTION__;
15824
 
15825
		#如果沒有參數
15826
		if(func_num_args()==0){
15827
 
15828
			#設置執行失敗
15829
			$result["status"]="false";
15830
 
15831
			#設置執行錯誤訊息
15832
			$result["error"]="函數".$result["function"]."需要參數";
15833
 
15834
			#回傳結果
15835
			return $result;
15836
 
15837
			}#if end
15838
 
15839
		#涵式說明:
15840
		#判斷當前環境為web還是cmd
15841
		#回傳結果:
15842
		#$result,"web"或"cmd"
15843
		if(csInformation::getEnv()==="web"){
15844
 
15845
			#設置執行失敗
15846
			$result["status"]="false";
15847
 
15848
			#設置執行錯誤訊息
15849
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
15850
 
15851
			#回傳結果
15852
			return $result;
15853
 
15854
			}#if end
226 liveuser 15855
 
3 liveuser 15856
		#取得參數
15857
		$result["argu"]=$conf;
15858
 
15859
		#如果 $conf 不為陣列
15860
		if(gettype($conf)!=="array"){
15861
 
15862
			#設置執行失敗
15863
			$result["status"]="false";
15864
 
15865
			#設置執行錯誤訊息
15866
			$result["error"][]="\$conf變數須為陣列形態";
15867
 
15868
			#如果傳入的參數為 null
15869
			if(is_null($conf)){
15870
 
15871
				#設置執行錯誤訊息
15872
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
15873
 
15874
				}#if end
15875
 
15876
			#回傳結果
15877
			return $result;
15878
 
15879
			}#if end
226 liveuser 15880
 
3 liveuser 15881
		#debug
15882
		#var_dump(__FUNCTION__,__LINE__,$conf);
226 liveuser 15883
 
3 liveuser 15884
		#檢查參數
15885
		#函式說明:
15886
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
15887
		#回傳結果:
15888
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
15889
		#$result["error"],執行不正常結束的錯訊息陣列.
15890
		#$result["simpleError"],簡單表示的錯誤訊息.
15891
		#$result["function"],當前執行的函式名稱.
15892
		#$result["argu"],設置給予的參數.
15893
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
15894
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
15895
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
15896
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
15897
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
15898
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
15899
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
15900
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
15901
		#必填參數:
15902
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
15903
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
15904
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
15905
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
15906
		#可省略參數:
15907
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
15908
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientSock","clientInfo","clientIndex","allConn");
15909
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
15910
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","resource","array","integer","array");
15911
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
15912
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
15913
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
15914
		#$conf["canNotBeEmpty"]=array();
15915
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
15916
		#$conf["canBeEmpty"]=array();
15917
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
15918
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("Range","partSize");
15919
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
15920
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("Range","partSize");
15921
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
15922
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","partSize");
15923
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
15924
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null,"1024000");
15925
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
15926
		#$conf["disallowAllSkipableVarIsEmpty"]="";
15927
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
15928
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
15929
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
15930
		#$conf["disallowAllSkipableVarNotExist"]="";
15931
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
15932
		#$conf["arrayCountEqualCheck"][]=array();
15933
		#參考資料:
15934
		#array_keys=>http://php.net/manual/en/function.array-keys.php
15935
		#備註:
15936
		#無.
15937
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
15938
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 15939
 
3 liveuser 15940
		#debug
15941
		#var_dump(__FUNCTION__,__LINE__,$checkArguments);
226 liveuser 15942
 
3 liveuser 15943
		#如果執行失敗
15944
		if($checkArguments["status"]==="false"){
226 liveuser 15945
 
3 liveuser 15946
			#設置錯誤訊息
15947
			$result["error"]=$checkArguments;
226 liveuser 15948
 
3 liveuser 15949
			#var_dump,交給下個 processFuncs 處理
15950
			$result["status"]="false";
226 liveuser 15951
 
3 liveuser 15952
			#回傳結果
15953
			return $result;
226 liveuser 15954
 
3 liveuser 15955
			}#if end
226 liveuser 15956
 
3 liveuser 15957
		#如果檢查不通過
15958
		if($checkArguments["passed"]==="false"){
226 liveuser 15959
 
3 liveuser 15960
			#不處理,略過,交給下個 processFuncs 處理
15961
			$result["status"]="continue";
226 liveuser 15962
 
3 liveuser 15963
			#回傳結果
15964
			return $result;
226 liveuser 15965
 
3 liveuser 15966
			}#if end
226 liveuser 15967
 
3 liveuser 15968
		#檢查收到的訊息是否為json格式
15969
		$revJson=@json_decode($conf["data"]);
15970
 
15971
		#如果不是 json
15972
		if($revJson===null){
226 liveuser 15973
 
3 liveuser 15974
			#不處理,略過,交給下個 processFuncs 處理
15975
			$result["status"]="continue";
226 liveuser 15976
 
3 liveuser 15977
			#回傳結果
15978
			return $result;
226 liveuser 15979
 
3 liveuser 15980
			}#if enf
226 liveuser 15981
 
3 liveuser 15982
		#轉換為陣列
15983
		$revJson=(array)($revJson);
226 liveuser 15984
 
3 liveuser 15985
		#檢查參數
15986
		#函式說明:
15987
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
15988
		#回傳結果:
15989
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
15990
		#$result["error"],執行不正常結束的錯訊息陣列.
15991
		#$result["simpleError"],簡單表示的錯誤訊息.
15992
		#$result["function"],當前執行的函式名稱.
15993
		#$result["argu"],設置給予的參數.
15994
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
15995
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
15996
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
15997
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
15998
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
15999
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
16000
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
16001
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
16002
		#必填參數:
16003
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
16004
		$conf["variableCheck::checkArguments"]["varInput"]=&$revJson;
16005
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
16006
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
16007
		#可省略參數:
16008
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
16009
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("Method","Host","File");
16010
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
16011
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string","string");
16012
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
16013
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
16014
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
16015
		#$conf["canNotBeEmpty"]=array();
16016
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
16017
		#$conf["canBeEmpty"]=array();
16018
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
16019
		$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("id","Range","partSize");
16020
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
16021
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("id","Range","partSize");
16022
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
16023
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string");
16024
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
16025
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null,null,"1024000");
16026
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
16027
		#$conf["disallowAllSkipableVarIsEmpty"]="";
16028
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
16029
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
16030
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
16031
		#$conf["disallowAllSkipableVarNotExist"]="";
16032
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
16033
		#$conf["arrayCountEqualCheck"][]=array();
16034
		#參考資料:
16035
		#array_keys=>http://php.net/manual/en/function.array-keys.php
16036
		#備註:
16037
		#無.
16038
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
16039
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 16040
 
3 liveuser 16041
		#debug
16042
		#var_dump(__FUNCTION__,__LINE__,$checkArguments);
226 liveuser 16043
 
3 liveuser 16044
		#如果執行失敗
16045
		if($checkArguments["status"]==="false"){
226 liveuser 16046
 
3 liveuser 16047
			#設置錯誤訊息
16048
			$result["error"]=$checkArguments;
226 liveuser 16049
 
3 liveuser 16050
			#var_dump,交給下個 processFuncs 處理
16051
			$result["status"]="false";
226 liveuser 16052
 
3 liveuser 16053
			#回傳結果
16054
			return $result;
226 liveuser 16055
 
3 liveuser 16056
			}#if end
226 liveuser 16057
 
3 liveuser 16058
		#如果檢查不通過
16059
		if($checkArguments["passed"]==="false"){
226 liveuser 16060
 
3 liveuser 16061
			#不處理,略過,交給下個 processFuncs 處理
16062
			$result["status"]="continue";
226 liveuser 16063
 
3 liveuser 16064
			#回傳結果
16065
			return $result;
226 liveuser 16066
 
3 liveuser 16067
			}#if end
226 liveuser 16068
 
3 liveuser 16069
		#如果是 GET Method
16070
		if($revJson["Method"]==="GET"){
226 liveuser 16071
 
3 liveuser 16072
			#解析 apache vhost info
16073
			#函式說明:
16074
			#使用 linux 的 httpd 指令來取得 vhost 資訊.
16075
			#回傳結果:
16076
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16077
			#$result["error"],錯誤訊息.
16078
			#$result["function"],當前執行的函式名稱.
16079
			#$result["content"],得到的結果陣列,每個元素可能會含有的key有ServerName、DocumentRoot、ServerAlias,其中DocumentRoot的數值會是用""包起來的路徑.
16080
			#必填參數:
16081
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
16082
			$conf["cmd::httpdGetVhostInfo"]["fileArgu"]=__FILE__;
16083
			#可省略參數:
16084
			#無.
16085
			#參考資料:
16086
			#無
16087
			#備註:
16088
			#無.
16089
			$httpdGetVhostInfo=cmd::httpdGetVhostInfo($conf["cmd::httpdGetVhostInfo"]);
16090
			unset($conf["cmd::httpdGetVhostInfo"]);
226 liveuser 16091
 
3 liveuser 16092
			#debug
16093
			#var_dump(__FUNCTION__,__LINE__,$httpdGetVhostInfo);
226 liveuser 16094
 
3 liveuser 16095
			#如果執行失敗
16096
			if($httpdGetVhostInfo["status"]==="false"){
226 liveuser 16097
 
3 liveuser 16098
				#設置錯誤訊息
16099
				$result["error"]=$httpdGetVhostInfo;
226 liveuser 16100
 
3 liveuser 16101
				#var_dump,交給下個 processFuncs 處理
16102
				$result["status"]="false";
226 liveuser 16103
 
3 liveuser 16104
				#回傳結果
16105
				return $result;
226 liveuser 16106
 
3 liveuser 16107
				}#if end
226 liveuser 16108
 
3 liveuser 16109
			#針對每個結果
16110
			foreach($httpdGetVhostInfo["content"] as $vhost){
226 liveuser 16111
 
3 liveuser 16112
				#如果有 ServerName
16113
				if(isset($vhost["ServerName"])){
226 liveuser 16114
 
3 liveuser 16115
					#如果是要找的 Host
16116
					if($vhost["ServerName"]===$revJson["Host"]){
226 liveuser 16117
 
3 liveuser 16118
						#如果有 DocumentRoot
16119
						if(isset($vhost["DocumentRoot"])){
226 liveuser 16120
 
3 liveuser 16121
							#組合要取得的檔案路徑與名稱
16122
							$file=$vhost["DocumentRoot"]."/".$revJson["File"];
226 liveuser 16123
 
3 liveuser 16124
							#debug
16125
							#var_dump(__LINE__,$file);
226 liveuser 16126
 
3 liveuser 16127
							#如果有 Range 參數
16128
							if(isset($revJson["Range"])){
226 liveuser 16129
 
3 liveuser 16130
								#格式參考
16131
								#bytes=0-499
226 liveuser 16132
 
3 liveuser 16133
								#函式說明:
16134
								#將字串特定關鍵字與其前面的內容剔除
16135
								#回傳結果:
16136
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16137
								#$result["error"],錯誤訊息陣列.
16138
								#$result["warning"],警告訊息鎮列.
16139
								#$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
16140
								#$result["function"],當前執行的函數名稱.
16141
								#$result["argu"],使用的參數.
16142
								#$result["oriStr"],要處理的原始字串內容.
226 liveuser 16143
								#$result["content"],處理好的的字串內容.
3 liveuser 16144
								#必填參數:
16145
								#$conf["stringIn"],字串,要處理的字串.
16146
								$conf["stringProcess::delStrBeforeKeyWord"]["stringIn"]=$revJson["Range"];
16147
								#$conf["keyWord"],字串,特定字串.
16148
								$conf["stringProcess::delStrBeforeKeyWord"]["keyWord"]="bytes=";
16149
								#可省略參數:
16150
								#$conf["recursive"],字串,預設為"false"代表找到一個關鍵字就會停止;"true"代表會即重複執行,知道沒有關鍵字為止.
16151
								#$conf["recursive"]="true";
16152
								#$conf["lastResult"],陣列,本函式前次執行的結果,若沒有找到關鍵字,則會改回傳該內容.
16153
								#$conf["lastResult"]=$delStrBeforeKeyWord;
16154
								#參考資料:
16155
								#無.
16156
								#備註:
16157
								#無.
16158
								$delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf["stringProcess::delStrBeforeKeyWord"]);
16159
								unset($conf["stringProcess::delStrBeforeKeyWord"]);
226 liveuser 16160
 
3 liveuser 16161
								#如果執行失敗
16162
								if($delStrBeforeKeyWord["status"]==="false"){
226 liveuser 16163
 
3 liveuser 16164
									#設置錯誤訊息
16165
									$result["error"]=$delStrBeforeKeyWord;
226 liveuser 16166
 
3 liveuser 16167
									#var_dump,交給下個 processFuncs 處理
16168
									$result["status"]="false";
226 liveuser 16169
 
3 liveuser 16170
									#回傳結果
16171
									return $result;
226 liveuser 16172
 
3 liveuser 16173
									}#if end
226 liveuser 16174
 
3 liveuser 16175
								#如果沒有該有的關鍵字
16176
								if($delStrBeforeKeyWord["founded"]==="false"){
226 liveuser 16177
 
3 liveuser 16178
									#設置錯誤訊息
16179
									$result["error"]=$delStrBeforeKeyWord;
226 liveuser 16180
 
3 liveuser 16181
									#var_dump,交給下個 processFuncs 處理
16182
									$result["status"]="false";
226 liveuser 16183
 
3 liveuser 16184
									#回傳結果
16185
									return $result;
226 liveuser 16186
 
3 liveuser 16187
									}#if end
226 liveuser 16188
 
3 liveuser 16189
								#解析 bytes start and end
16190
								#函式說明:
16191
								#將固定格式的字串分開,並回傳分開的結果.
16192
								#回傳結果:
16193
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16194
								#$result["error"],錯誤訊息陣列
16195
								#$result["function"],當前執行的函數名稱.
16196
								#$result["argu"],使用的參數.
16197
								#$result["oriStr"],要分割的原始字串內容
16198
								#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
16199
								#$result["dataCounts"],爲總共分成幾段
16200
								#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
16201
								#必填參數:
16202
								#$conf["stringIn"],字串,要處理的字串.
16203
								$conf["stringProcess::spiltString"]["stringIn"]=$delStrBeforeKeyWord["content"];
16204
								#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
16205
								$conf["stringProcess::spiltString"]["spiltSymbol"]="-";
16206
								#可省略參數:
16207
								#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
16208
								#$conf["allowEmptyStr"]="false";
16209
								#參考資料:
16210
								#無.
16211
								#備註:
16212
								#無.
16213
								$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
16214
								unset($conf["stringProcess::spiltString"]);
226 liveuser 16215
 
3 liveuser 16216
								#如果執行失敗
16217
								if($spiltString["status"]==="false"){
226 liveuser 16218
 
3 liveuser 16219
									#設置錯誤訊息
16220
									$result["error"]=$spiltString;
226 liveuser 16221
 
3 liveuser 16222
									#var_dump,交給下個 processFuncs 處理
16223
									$result["status"]="false";
226 liveuser 16224
 
3 liveuser 16225
									#回傳結果
16226
									return $result;
226 liveuser 16227
 
3 liveuser 16228
									}#if end
226 liveuser 16229
 
3 liveuser 16230
								#如果沒有應該有的 - 符號
16231
								if($spiltString["found"]==="false"){
226 liveuser 16232
 
3 liveuser 16233
									#設置錯誤訊息
16234
									$result["error"]=$spiltString;
226 liveuser 16235
 
3 liveuser 16236
									#var_dump,交給下個 processFuncs 處理
16237
									$result["status"]="false";
226 liveuser 16238
 
3 liveuser 16239
									#回傳結果
16240
									return $result;
226 liveuser 16241
 
3 liveuser 16242
									}#if end
226 liveuser 16243
 
3 liveuser 16244
								#如果沒有分割成2段
16245
								if($spiltString["dataCounts"]!==2){
226 liveuser 16246
 
3 liveuser 16247
									#設置錯誤訊息
16248
									$result["error"]=$spiltString;
226 liveuser 16249
 
3 liveuser 16250
									#var_dump,交給下個 processFuncs 處理
16251
									$result["status"]="false";
226 liveuser 16252
 
3 liveuser 16253
									#回傳結果
16254
									return $result;
226 liveuser 16255
 
3 liveuser 16256
									}#if end
226 liveuser 16257
 
3 liveuser 16258
								#依照Range來取得檔案內容
16259
								#函式說明:
16260
								#取得檔案的部分內容
16261
								#回傳結果:
16262
								#$result["status"],"true"代表移除成功,"false"代表移除失敗.
16263
								#$result["error"],錯誤訊息陣列.
16264
								#$result["function"],當前執行的函數名稱.
16265
								#$result["cmd"],執行的指令.
16266
								#$result["content"],取得的檔案內容.
16267
								#$result["length"],取得的內容長度.
16268
								#$result["EOF"],識別是否已經到檔案結尾,"true"代表是,"false"代表不是.
16269
								#$result["mimeType"],檔案的 mime type.
16270
								#必填參數:
16271
								#$conf["file"],字串,檔案的路徑與名稱.
16272
								$conf["fileAccess::getFilePart"]["file"]=$file;
16273
								#$conf["fileArgu"],字串,__FILE__的內容.
16274
								$conf["fileAccess::getFilePart"]["fileArgu"]=__FILE__;
16275
								#$conf["bytes"],整數字串,要讀取多少bytes.
16276
								$conf["fileAccess::getFilePart"]["bytes"]=$spiltString["dataArray"][1]-$spiltString["dataArray"][0]+1;
16277
								#$conf["startIndex"],要從哪個bytes位置開始,起始點為0.
16278
								$conf["fileAccess::getFilePart"]["startIndex"]=$spiltString["dataArray"][0];
16279
								#可省略參數:
16280
								#無
16281
								#參考資料:
16282
								#無.
16283
								#備註:
16284
								#無
16285
								$getFilePart=fileAccess::getFilePart($conf["fileAccess::getFilePart"]);
16286
								unset($conf["fileAccess::getFilePart"]);
226 liveuser 16287
 
3 liveuser 16288
								#如果執行失敗
16289
								if($getFilePart["status"]==="false"){
226 liveuser 16290
 
3 liveuser 16291
									#設置錯誤訊息
16292
									$result["error"]=$getFilePart;
226 liveuser 16293
 
3 liveuser 16294
									#var_dump,交給下個 processFuncs 處理
16295
									$result["status"]="false";
226 liveuser 16296
 
3 liveuser 16297
									#回傳結果
16298
									return $result;
226 liveuser 16299
 
3 liveuser 16300
									}#if end
226 liveuser 16301
 
3 liveuser 16302
								#初始化要傳遞的訊息
16303
								$msg=array();
226 liveuser 16304
 
3 liveuser 16305
								#設置為最後一份了
16306
								$msg["LastPart"]="true";
226 liveuser 16307
 
3 liveuser 16308
								#設置資料內容類型為binary
16309
								$msg["dataType"]="binary";
226 liveuser 16310
 
3 liveuser 16311
								#設置內容
16312
								$msg["content"]=$getFilePart["content"];
226 liveuser 16313
 
3 liveuser 16314
								#設置 mimeType
16315
								$msg["mimeType"]=$getFilePart["mimeType"];
226 liveuser 16316
 
3 liveuser 16317
								#如果有設置 id
16318
								if(isset($revJson["id"])){
226 liveuser 16319
 
3 liveuser 16320
									#設置資料的 id
16321
									$msg["id"]=$revJson["id"];
226 liveuser 16322
 
3 liveuser 16323
									}#if end
226 liveuser 16324
 
3 liveuser 16325
								#函式說明:
226 liveuser 16326
								#加密 handshake 後要傳送的訊息
3 liveuser 16327
								#回傳結果:
16328
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16329
								#$result["error"],執行不正常結束的錯訊息陣列.
16330
								#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
16331
								#$result["argu"],陣列,使用的參數.
16332
								#必填參數:
16333
								#$conf["text"],字串,要加密的訊息.
226 liveuser 16334
								$conf["webSock::encode"]["text"]=base64_encode(urlencode(json_encode($msg)));
3 liveuser 16335
								#可省略參數:
16336
								#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
16337
								#$conf["webSock::encode"]["payloadIsBin"]="true";
16338
								#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
16339
								#$conf["ping"]="false";
16340
								#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
16341
								#$conf["pong"]="false";
16342
								#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
16343
								#$conf["frames"]=array();
16344
								#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
16345
								#$conf["webSock::encode"]["mask"]="false";
16346
								#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
16347
								#$conf["debug"]="false";
16348
								#參考資料:
16349
								#無.
16350
								#備註:
16351
								#無.
16352
								$talkback=webSock::encode($conf["webSock::encode"]);
16353
								unset($conf["webSock::encode"]);
226 liveuser 16354
 
3 liveuser 16355
								#如果執行失敗
16356
								if($talkback["status"]==="false"){
226 liveuser 16357
 
3 liveuser 16358
									#印出結果
16359
									var_dump($talkback);
226 liveuser 16360
 
3 liveuser 16361
									#結束執行
16362
									exit;
226 liveuser 16363
 
3 liveuser 16364
									}#if end
226 liveuser 16365
 
3 liveuser 16366
								#針對每個訊息的分段
16367
								foreach($talkback["content"] as $msg){
226 liveuser 16368
 
3 liveuser 16369
									#回傳訊息
16370
									$socket_write=socket_write($conf["clientSock"], $msg, strlen($msg));
226 liveuser 16371
 
3 liveuser 16372
									#如果傳遞訊息給用戶失敗
16373
									if($socket_write===false){
226 liveuser 16374
 
3 liveuser 16375
										#取得錯誤代碼
16376
										$errorCode=socket_last_error($conf["clientSock"]);
226 liveuser 16377
 
3 liveuser 16378
										#設置執行失敗
16379
										$result["status"]="false";
226 liveuser 16380
 
3 liveuser 16381
										#設置錯誤代碼
16382
										$result["error"][]="error code:".$errorCode;
226 liveuser 16383
 
3 liveuser 16384
										#設置錯誤代碼說明
16385
										$result["erorr"][]="error description:".socket_strerror($errorCode);
226 liveuser 16386
 
3 liveuser 16387
										#回傳結果
16388
										return $result;
226 liveuser 16389
 
3 liveuser 16390
										}#if end
226 liveuser 16391
 
3 liveuser 16392
									}#foreach end
226 liveuser 16393
 
3 liveuser 16394
								#設置正常,結束後面函式的執行
16395
								$result["status"]="true";
226 liveuser 16396
 
3 liveuser 16397
								#回傳結果
16398
								return $result;
226 liveuser 16399
 
3 liveuser 16400
								}#if end
226 liveuser 16401
 
3 liveuser 16402
							#反之沒有 Rnage 參數
16403
							else{
226 liveuser 16404
 
3 liveuser 16405
								#執行到這邊代表要取得全部的檔案內容
226 liveuser 16406
 
3 liveuser 16407
								#debug
16408
								#var_dump(__LINE__,"get full file content");
226 liveuser 16409
 
3 liveuser 16410
								#第一部分的編號
16411
								$partNo=0;
226 liveuser 16412
 
3 liveuser 16413
								#無窮迴圈
16414
								while(true){
226 liveuser 16415
 
3 liveuser 16416
									#分段取得檔案
16417
									#函式說明:
16418
									#取得檔案的部分內容
16419
									#回傳結果:
16420
									#$result["status"],"true"代表移除成功,"false"代表移除失敗.
16421
									#$result["error"],錯誤訊息陣列.
16422
									#$result["function"],當前執行的函數名稱.
16423
									#$result["cmd"],執行的指令.
16424
									#$result["content"],取得的檔案內容.
16425
									#$result["length"],取得的內容長度.
16426
									#$result["EOF"],識別是否已經到檔案結尾,"true"代表是,"false"代表不是.
16427
									#$result["mimeType"],檔案的 mime type.
16428
									#必填參數:
16429
									#$conf["file"],字串,檔案的路徑與名稱.
16430
									$conf["fileAccess::getFilePart"]["file"]=$file;
16431
									#$conf["fileArgu"],字串,__FILE__的內容.
16432
									$conf["fileAccess::getFilePart"]["fileArgu"]=__FILE__;
16433
									#$conf["bytes"],整數字串,要讀取多少bytes.
16434
									$conf["fileAccess::getFilePart"]["bytes"]=$revJson["partSize"];
16435
									#$conf["startIndex"],要從哪個bytes位置開始,起始點為0.
16436
									$conf["fileAccess::getFilePart"]["startIndex"]=$partNo*$revJson["partSize"];
16437
									#可省略參數:
16438
									#無
16439
									#參考資料:
16440
									#無.
16441
									#備註:
16442
									#無
16443
									$getFilePart=fileAccess::getFilePart($conf["fileAccess::getFilePart"]);
16444
									unset($conf["fileAccess::getFilePart"]);
226 liveuser 16445
 
3 liveuser 16446
									#debug
16447
									#var_dump(__LINE__,$getFilePart);
226 liveuser 16448
 
3 liveuser 16449
									#如果執行失敗
16450
									if($getFilePart["status"]==="false"){
226 liveuser 16451
 
3 liveuser 16452
										#設置錯誤訊息
16453
										$result["error"]=$getFilePart;
226 liveuser 16454
 
3 liveuser 16455
										#var_dump,交給下個 processFuncs 處理
16456
										$result["status"]="false";
226 liveuser 16457
 
3 liveuser 16458
										#回傳結果
16459
										return $result;
226 liveuser 16460
 
3 liveuser 16461
										}#if end
226 liveuser 16462
 
3 liveuser 16463
									#初始化要傳遞的訊息
16464
									$msg=array();
226 liveuser 16465
 
3 liveuser 16466
									#設置不為最後一份
16467
									$msg["LastPart"]="false";
226 liveuser 16468
 
3 liveuser 16469
									#設置資料內容類型為binary
16470
									$msg["dataType"]="binary";
226 liveuser 16471
 
3 liveuser 16472
									#設置內容
16473
									$msg["content"]=$getFilePart["content"];
226 liveuser 16474
 
3 liveuser 16475
									#設置 mimeType
16476
									$msg["mimeType"]=$getFilePart["mimeType"];
226 liveuser 16477
 
3 liveuser 16478
									#如果有設置 id
16479
									if(isset($revJson["id"])){
226 liveuser 16480
 
3 liveuser 16481
										#設置資料的 id
16482
										$msg["id"]=$revJson["id"];
226 liveuser 16483
 
3 liveuser 16484
										}#if end
226 liveuser 16485
 
3 liveuser 16486
									#如果偵測到檔案結尾
16487
									if($getFilePart["EOF"]==="true"){
226 liveuser 16488
 
3 liveuser 16489
										#設置為最後一份了
16490
										$msg["LastPart"]="true";
226 liveuser 16491
 
3 liveuser 16492
										#如果沒有內容
16493
										if($getFilePart["length"]===0){
226 liveuser 16494
 
3 liveuser 16495
											#檔案區塊數字-1
16496
											$partNo--;
226 liveuser 16497
 
3 liveuser 16498
											}#if end
16499
 
16500
										#傳遞給 client - start
16501
 
16502
										#編碼後的訊息
16503
										$msgEncoded=base64_encode(urlencode(json_encode($msg)));
16504
 
16505
										#debug
16506
										#var_dump(__LINE__,$msg,$msgEncoded);
16507
 
16508
										#函式說明:
226 liveuser 16509
										#加密 handshake 後要傳送的訊息
3 liveuser 16510
										#回傳結果:
16511
										#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16512
										#$result["error"],執行不正常結束的錯訊息陣列.
16513
										#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
16514
										#$result["argu"],陣列,使用的參數.
16515
										#必填參數:
16516
										#$conf["text"],字串,要加密的訊息.
226 liveuser 16517
										$conf["webSock::encode"]["text"]=$msgEncoded;
3 liveuser 16518
										#可省略參數:
16519
										#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
16520
										#$conf["webSock::encode"]["payloadIsBin"]="false";
16521
										#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
16522
										#$conf["ping"]="false";
16523
										#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
16524
										#$conf["pong"]="false";
16525
										#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
16526
										#$conf["frames"]=array();
16527
										#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
16528
										#$conf["webSock::encode"]["mask"]="false";
16529
										#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
16530
										#$conf["debug"]="false";
16531
										#參考資料:
16532
										#無.
16533
										#備註:
16534
										#無.
16535
										$talkback=webSock::encode($conf["webSock::encode"]);
16536
										unset($conf["webSock::encode"]);
226 liveuser 16537
 
3 liveuser 16538
										#debug
16539
										#var_dump(__LINE__,$talkback);
226 liveuser 16540
 
3 liveuser 16541
										#如果執行失敗
16542
										if($talkback["status"]==="false"){
226 liveuser 16543
 
3 liveuser 16544
											#印出結果
16545
											var_dump($talkback);
226 liveuser 16546
 
3 liveuser 16547
											#結束執行
16548
											exit;
226 liveuser 16549
 
3 liveuser 16550
											}#if end
226 liveuser 16551
 
3 liveuser 16552
										#針對每個訊息的分段
16553
										foreach($talkback["content"] as $msg){
226 liveuser 16554
 
3 liveuser 16555
											#回傳訊息
16556
											$socket_write=socket_write($conf["clientSock"], $msg, strlen($msg));
226 liveuser 16557
 
3 liveuser 16558
											#debug
16559
											#var_dump(__LINE__,$socket_write,$msg);
226 liveuser 16560
 
3 liveuser 16561
											#如果傳遞訊息給用戶失敗
16562
											if($socket_write===false){
226 liveuser 16563
 
3 liveuser 16564
												#取得錯誤代碼
16565
												$errorCode=socket_last_error($conf["clientSock"]);
226 liveuser 16566
 
3 liveuser 16567
												#設置執行失敗
16568
												$result["status"]="false";
226 liveuser 16569
 
3 liveuser 16570
												#設置錯誤代碼
16571
												$result["error"][]="error code:".$errorCode;
226 liveuser 16572
 
3 liveuser 16573
												#設置錯誤代碼說明
16574
												$result["erorr"][]="error description:".socket_strerror($errorCode);
226 liveuser 16575
 
3 liveuser 16576
												#回傳結果
16577
												return $result;
226 liveuser 16578
 
3 liveuser 16579
												}#if end
226 liveuser 16580
 
3 liveuser 16581
											}#foreach end
226 liveuser 16582
 
3 liveuser 16583
										#傳遞給 client - end
226 liveuser 16584
 
3 liveuser 16585
										#結束 while
16586
										break;
226 liveuser 16587
 
3 liveuser 16588
										}#if end
226 liveuser 16589
 
3 liveuser 16590
									#傳遞給 client - start
226 liveuser 16591
 
3 liveuser 16592
									#debug
16593
									#var_dump(__LINE__,"start tranfer");
226 liveuser 16594
 
3 liveuser 16595
									#函式說明:
226 liveuser 16596
									#加密 handshake 後要傳送的訊息
3 liveuser 16597
									#回傳結果:
16598
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16599
									#$result["error"],執行不正常結束的錯訊息陣列.
16600
									#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
16601
									#$result["argu"],陣列,使用的參數.
16602
									#必填參數:
16603
									#$conf["text"],字串,要加密的訊息.
226 liveuser 16604
									$conf["webSock::encode"]["text"]=base64_encode(urlencode(json_encode($msg)));
3 liveuser 16605
									#可省略參數:
16606
									#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
16607
									#$conf["webSock::encode"]["payloadIsBin"]="true";
16608
									#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
16609
									#$conf["ping"]="false";
16610
									#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
16611
									#$conf["pong"]="false";
16612
									#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
16613
									#$conf["frames"]=array();
16614
									#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
16615
									#$conf["webSock::encode"]["mask"]="false";
16616
									#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
16617
									#$conf["debug"]="false";
16618
									#參考資料:
16619
									#無.
16620
									#備註:
16621
									#無.
16622
									$talkback=webSock::encode($conf["webSock::encode"]);
16623
									unset($conf["webSock::encode"]);
226 liveuser 16624
 
3 liveuser 16625
									#如果執行失敗
16626
									if($talkback["status"]==="false"){
226 liveuser 16627
 
3 liveuser 16628
										#印出結果
16629
										var_dump($talkback);
226 liveuser 16630
 
3 liveuser 16631
										#結束執行
16632
										exit;
226 liveuser 16633
 
3 liveuser 16634
										}#if end
226 liveuser 16635
 
3 liveuser 16636
									#針對每個訊息的分段
16637
									foreach($talkback["content"] as $msg){
226 liveuser 16638
 
3 liveuser 16639
										#回傳訊息
16640
										$socket_write=socket_write($conf["clientSock"], $msg, strlen($msg));
226 liveuser 16641
 
3 liveuser 16642
										#如果傳遞訊息給用戶失敗
16643
										if($socket_write===false){
226 liveuser 16644
 
3 liveuser 16645
											#取得錯誤代碼
16646
											$errorCode=socket_last_error($conf["clientSock"]);
226 liveuser 16647
 
3 liveuser 16648
											#設置執行失敗
16649
											$result["status"]="false";
226 liveuser 16650
 
3 liveuser 16651
											#設置錯誤代碼
16652
											$result["error"][]="error code:".$errorCode;
226 liveuser 16653
 
3 liveuser 16654
											#設置錯誤代碼說明
16655
											$result["erorr"][]="error description:".socket_strerror($errorCode);
226 liveuser 16656
 
3 liveuser 16657
											#回傳結果
16658
											return $result;
226 liveuser 16659
 
3 liveuser 16660
											}#if end
226 liveuser 16661
 
3 liveuser 16662
										}#foreach end
226 liveuser 16663
 
3 liveuser 16664
									#傳遞給 client - end
226 liveuser 16665
 
3 liveuser 16666
									#檔案區塊數字+1
16667
									$partNo++;
226 liveuser 16668
 
3 liveuser 16669
									}#while end
226 liveuser 16670
 
3 liveuser 16671
								#設置執行正常
16672
								$result["status"]="true";
226 liveuser 16673
 
3 liveuser 16674
								#回傳結果
16675
								return $result;
226 liveuser 16676
 
3 liveuser 16677
								}#else end
226 liveuser 16678
 
3 liveuser 16679
							}#if end
226 liveuser 16680
 
3 liveuser 16681
						}#if end
226 liveuser 16682
 
3 liveuser 16683
					}#if end
226 liveuser 16684
 
3 liveuser 16685
				}#foreach end
226 liveuser 16686
 
3 liveuser 16687
			#設置執行不正常
16688
			$result["status"]="false";
226 liveuser 16689
 
3 liveuser 16690
			#設置執行錯誤
16691
			$result["error"]="no matched ServerName";
226 liveuser 16692
 
3 liveuser 16693
			#debug
66 liveuser 16694
			var_dump(__FUNCTION__,__LINE__,$result);
226 liveuser 16695
 
3 liveuser 16696
			#回傳結果
16697
			return $result;
226 liveuser 16698
 
3 liveuser 16699
			}#if end
226 liveuser 16700
 
3 liveuser 16701
		#設置執行不正常
16702
		$result["status"]="false";
226 liveuser 16703
 
3 liveuser 16704
		#設置執行錯誤
16705
		$result["error"]="Method should be GET";
226 liveuser 16706
 
3 liveuser 16707
		#回傳結果
16708
		return $result;
226 liveuser 16709
 
3 liveuser 16710
		}#function getFileContent end
226 liveuser 16711
 
66 liveuser 16712
	/*
16713
	#函式說明:
16714
	#提供webSock::nativeSocketTcpIpServer用於接受檢查權限的功能.
16715
	#回傳結果:
16716
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16717
	#$result["error"],執行不正常結束的錯訊息陣列.
16718
	#$result["argu"],陣列,使用的參數.
16719
	#必填參數:
16720
	#$conf["data"],字串,收到的bin2hex編碼後果gpg加密過後的json格式資料,必填的key有"randomStr","username","password".
16721
	$conf["data"]="";
16722
	#$conf["serverSock"],resource,web socket server socket
16723
	$conf["serverSock"]=$resource;
16724
	#$conf["clientSock"],$resource,web socket client socket
16725
	$conf["clientSock"]=$resource;
16726
	#$conf["clientInfo"],陣列,web socket client info.
16727
	$conf["clientInfo"]=array();
16728
	#$conf["clientIndex"],整數.web socket client index.
16729
	$conf["clientIndex"];
16730
	#$conf["allConn"],陣列,all web socket client info.
16731
	$conf["allConn"]=array();
16732
	#$conf["func"],字串,要檢查的是否具備權限的函式.
16733
	$conf["func"]="";
16734
	#可省略參數:
16735
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
16736
	#$conf["wsMode"]="true";
16737
	#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
16738
	#$conf["gpgId"]=gnupgId;
16739
	#$conf["falseAllowFuncPlus"],陣列,額外的未認證時可以執行的函式清單.
16740
	#$conf["falseAllowFuncPlus"]=array();
16741
	#$conf["publicAllowFuncPlus"],陣列,額外的認證為public時可以執行的函式清單.
16742
	#$conf["publicAllowFuncPlus"]=array();
16743
	#參考資料:
16744
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
16745
	#備註:
16746
	#無.
16747
	*/
16748
	public static function checkAuth(&$conf){
226 liveuser 16749
 
66 liveuser 16750
		#初始化要回傳的結果
16751
		$result=array();
16752
 
16753
		#取得當前執行的函數名稱
16754
		$result["function"]=__FUNCTION__;
16755
 
16756
		#涵式說明:
16757
		#判斷當前環境為web還是cmd
16758
		#回傳結果:
16759
		#$result,"web"或"cmd"
16760
		if(csInformation::getEnv()==="web"){
226 liveuser 16761
 
66 liveuser 16762
			#設置執行失敗
16763
			$result["status"]="false";
226 liveuser 16764
 
66 liveuser 16765
			#設置執行錯誤訊息
16766
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 16767
 
66 liveuser 16768
			#回傳結果
16769
			return $result;
226 liveuser 16770
 
66 liveuser 16771
			}#if end
16772
 
16773
		#取得參數
16774
		$result["argu"]=$conf;
16775
 
16776
		#如果 $conf 不為陣列
16777
		if(gettype($conf)!="array"){
226 liveuser 16778
 
66 liveuser 16779
			#設置執行失敗
16780
			$result["status"]="false";
226 liveuser 16781
 
66 liveuser 16782
			#設置執行錯誤訊息
16783
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 16784
 
66 liveuser 16785
			#如果傳入的參數為 null
16786
			if($conf==null){
226 liveuser 16787
 
66 liveuser 16788
				#設置執行錯誤訊息
16789
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 16790
 
66 liveuser 16791
				}#if end
16792
 
16793
			#回傳結果
16794
			return $result;
226 liveuser 16795
 
66 liveuser 16796
			}#if end
226 liveuser 16797
 
66 liveuser 16798
		#檢查參數
16799
		#函式說明:
16800
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
16801
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
16802
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
16803
		#$result["function"],當前執行的函式名稱.
16804
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
16805
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
16806
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
16807
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
16808
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
16809
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
16810
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
16811
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
16812
		#必填寫的參數:
16813
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
16814
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
16815
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
16816
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientInfo","clientIndex","allConn","func");
16817
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
16818
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","array","string","array","string");
16819
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
16820
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
16821
		#可以省略的參數:
16822
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
16823
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
16824
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
16825
		#$conf["canNotBeEmpty"]=array();
16826
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
16827
		#$conf["canBeEmpty"]=array();
16828
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
16829
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
16830
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
16831
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode","gpgId","falseAllowFuncPlus","publicAllowFuncPlus");
226 liveuser 16832
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 16833
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","array","array");
16834
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
16835
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",gnupgId,array(),array());
16836
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
16837
		#$conf["arrayCountEqualCheck"][]=array();
16838
		#參考資料來源:
16839
		#array_keys=>http://php.net/manual/en/function.array-keys.php
16840
		#建議:
16841
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
16842
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
16843
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 16844
 
66 liveuser 16845
		#如果檢查參數失敗
16846
		if($checkArguments["status"]==="false"){
226 liveuser 16847
 
66 liveuser 16848
			#設置執行失敗
16849
			$result["status"]="false";
226 liveuser 16850
 
66 liveuser 16851
			#設置執行錯誤訊息
16852
			$result["error"]=$checkArguments;
226 liveuser 16853
 
66 liveuser 16854
			#回傳結果
16855
			return $result;
226 liveuser 16856
 
66 liveuser 16857
			}#if end
226 liveuser 16858
 
66 liveuser 16859
		#如果檢查參數不通過
16860
		if($checkArguments["passed"]==="false"){
226 liveuser 16861
 
66 liveuser 16862
			#設置執行失敗
16863
			$result["status"]="false";
226 liveuser 16864
 
66 liveuser 16865
			#設置執行錯誤訊息
16866
			$result["error"]=$checkArguments;
226 liveuser 16867
 
66 liveuser 16868
			#回傳結果
16869
			return $result;
226 liveuser 16870
 
66 liveuser 16871
			}#if end
16872
 
16873
		#取得收到的訊息
16874
		$receivedData=$conf["data"];
226 liveuser 16875
 
66 liveuser 16876
		#取得 server 的 socket
16877
		$serverSocket=$conf["serverSock"];
226 liveuser 16878
 
66 liveuser 16879
		#取得 client 的 socket
16880
		$clientSocket=$conf["clientSock"];
226 liveuser 16881
 
66 liveuser 16882
		#取得 client 的資訊
16883
		$clientInfo=$conf["clientInfo"];
226 liveuser 16884
 
66 liveuser 16885
		#取得 client 的索引
16886
		$clientIndex=$conf["clientIndex"];
226 liveuser 16887
 
66 liveuser 16888
		#取得 all clients 的資訊
16889
		$allConn=&$conf["allConn"];
226 liveuser 16890
 
66 liveuser 16891
		/* 檢查權限不用看收到的訊息
226 liveuser 16892
 
66 liveuser 16893
		#hex2bin
16894
		#函式說明:
16895
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
16896
		#回傳結果:
226 liveuser 16897
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 16898
		#$result["function"],當前執行的函數名稱.
16899
		#$result["content"],加密後的結果.
16900
		#$result["error"],錯誤訊息陣列.
16901
		#$result["argu"],使用的參數.
16902
		#必填參數:
16903
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
16904
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
16905
		#$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".
16906
		$conf["authenticate::enCodeStr"]["enCodeType"]="hex2bin";
16907
		#可省略參數:
16908
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
16909
		#$conf["sha1Raw"]="false";
16910
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
16911
		#$conf["p_hash"]="";
16912
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
16913
		#$conf["keyForAes256"]="";
16914
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
16915
		#$conf["aes256Encode"]="";
16916
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
16917
		#$conf["qbpwcfDecode"]="false";
16918
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
16919
		#$conf["gpgDecrypt"]="false";
16920
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
16921
		#$conf["gpgId"]="";
16922
		#參考資料:
16923
		#sha1=>http://php.net/manual/en/function.sha1.php
16924
		#md5=>http://php.net/manual/en/function.md5.php
16925
		#password_hash=>http://php.net/manual/en/function.password-hash.php
16926
		#password_verify=>http://php.net/manual/en/function.password-verify.php
16927
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
16928
		#備註:
16929
		#無.
16930
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
16931
		unset($conf["authenticate::enCodeStr"]);
16932
 
16933
		#如果執行失敗
16934
		if($enCodeStr["status"]==="false"){
16935
 
16936
			#設置執行異常
16937
			$result["status"]="false";
16938
 
16939
			#設置執行錯誤
16940
			$result["error"]=$enCodeStr;
16941
 
16942
			#回傳結果
16943
			return $result;
16944
 
16945
			}#if end
16946
 
16947
		#取得hex2bin後的字串
16948
		$receivedData=$enCodeStr["content"];
226 liveuser 16949
 
66 liveuser 16950
		#gpg decrypt
16951
		#函式說明:
16952
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
16953
		#回傳結果:
226 liveuser 16954
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 16955
		#$result["function"],當前執行的函數名稱.
16956
		#$result["content"],加密後的結果.
16957
		#$result["error"],錯誤訊息陣列.
16958
		#$result["argu"],使用的參數.
16959
		#必填參數:
16960
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
16961
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
16962
		#$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".
16963
		$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
16964
		#可省略參數:
16965
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
16966
		#$conf["sha1Raw"]="false";
16967
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
16968
		#$conf["p_hash"]="";
16969
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
16970
		#$conf["keyForAes256"]="";
16971
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
16972
		#$conf["aes256Encode"]="";
16973
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
16974
		#$conf["qbpwcfDecode"]="false";
16975
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
16976
		$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
16977
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
16978
		$conf["authenticate::enCodeStr"]["gpgId"]=$conf["gpgId"];
16979
		#參考資料:
16980
		#sha1=>http://php.net/manual/en/function.sha1.php
16981
		#md5=>http://php.net/manual/en/function.md5.php
16982
		#password_hash=>http://php.net/manual/en/function.password-hash.php
16983
		#password_verify=>http://php.net/manual/en/function.password-verify.php
16984
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
16985
		#備註:
16986
		#無.
16987
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
16988
		unset($conf["authenticate::enCodeStr"]);
16989
 
16990
		#如果執行失敗
16991
		if($enCodeStr["status"]==="false"){
16992
 
16993
			#設置執行異常
16994
			$result["status"]="false";
16995
 
16996
			#設置執行錯誤
16997
			$result["error"]=$enCodeStr;
16998
 
16999
			#回傳結果
17000
			return $result;
17001
 
17002
			}#if end
17003
 
17004
		#取得解密後的字串
17005
		$receivedData=$enCodeStr["content"];
226 liveuser 17006
 
66 liveuser 17007
		#json_decode
17008
		$receivedData=json_decode($receivedData);
226 liveuser 17009
 
66 liveuser 17010
		*/
226 liveuser 17011
 
66 liveuser 17012
		#取得認證狀態
17013
		$authStatus=$conf["clientInfo"][$conf["clientIndex"]]["auth"];
226 liveuser 17014
 
66 liveuser 17015
		#判斷 authStatus
17016
		switch($authStatus){
226 liveuser 17017
 
66 liveuser 17018
			#如果未經過認證
17019
			case "false":
226 liveuser 17020
 
66 liveuser 17021
				#預設可以使用的功能只有"auth"跟"checkAuth"
17022
				$authFunc=array("auth","checkAuth");
226 liveuser 17023
 
66 liveuser 17024
				#如果有 $conf["falseAllowFuncPlus"]
17025
				if(count($conf["falseAllowFuncPlus"])>0){
226 liveuser 17026
 
66 liveuser 17027
					#合併 array
17028
					#函式說明:
17029
					#將多個一維陣列串聯起來,key從0開始排序.
17030
					#回傳的結果:
17031
					#$result["status"],"true"表執行正常,"false"代表執行不正常.
17032
					#$result["error"],錯誤訊息陣列.
17033
					#$result["function"],當前執行的函數.
17034
					#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
17035
					#$result["content"],合併好的一維陣列.
17036
					#必填參數
17037
					#$conf["inputArray"],陣列,要合併的一維陣列變數,例如:=array($array1,$array2);
17038
					$conf["arrays::mergeArray"]["inputArray"]=array($authFunc,$conf["falseAllowFuncPlus"]);
17039
					#可省略參數:
17040
					#$conf["allowRepeat"],字串,預設為"true",允許重複的結果;若為"false"則不會出現重複的元素內容.
17041
					$conf["arrays::mergeArray"]["allowRepeat"]="false";
17042
					#$conf["looseDiff"],字串,預設為"false",代表要嚴謹判斷為有相異,例如陣列中元素的key順序不同(整數)就代表有相異;反之為"true",例如陣列中元素的key順序不同(非整數),但value有相同,則視為無相異.
17043
					$conf["arrays::mergeArray"]["looseDiff"]="true";
17044
					#參考資料:
17045
					#無.
17046
					#備註:
17047
					#無.
17048
					$mergeArray=arrays::mergeArray($conf["arrays::mergeArray"]);
17049
					unset($conf["arrays::mergeArray"]);
226 liveuser 17050
 
66 liveuser 17051
					#如果執行失敗
17052
					if($mergeArray["status"]==="false"){
17053
 
17054
						#設置執行異常
17055
						$result["status"]="false";
17056
 
17057
						#設置執行錯誤
17058
						$result["error"]=$mergeArray;
17059
 
17060
						#回傳結果
17061
						return $result;
17062
 
17063
						}#if end
226 liveuser 17064
 
66 liveuser 17065
					#取得合併好允許使用的清單
17066
					$authFunc=$mergeArray["content"];
226 liveuser 17067
 
66 liveuser 17068
					}#if end
226 liveuser 17069
 
17070
				#如果沒有權限使用
66 liveuser 17071
				if(!in_array($conf["func"],$authFunc)){
226 liveuser 17072
 
66 liveuser 17073
					#設置執行異常
17074
					$result["status"]="false";
17075
 
17076
					#設置執行錯誤
17077
					$result["error"][]="no ".$conf["func"]." permission";
226 liveuser 17078
 
66 liveuser 17079
					#回傳結果
17080
					return $result;
226 liveuser 17081
 
66 liveuser 17082
					}#if end
226 liveuser 17083
 
66 liveuser 17084
				#結束 switch
17085
				break;
226 liveuser 17086
 
66 liveuser 17087
			#如果是"root"賬戶,代表系統管理者,擁有所有權限.
17088
			case "root":
226 liveuser 17089
 
66 liveuser 17090
				#預設可以使用的功能只有"*",代表所有功能都能用.
17091
				$authFunc=array("*");
226 liveuser 17092
 
66 liveuser 17093
				/*	允許使用所有函式
226 liveuser 17094
 
17095
				#如果沒有權限使用
66 liveuser 17096
				if(!in_array($conf["func"],$authFunc)){
226 liveuser 17097
 
66 liveuser 17098
					#設置執行異常
17099
					$result["status"]="false";
17100
 
17101
					#設置執行錯誤
17102
					$result["error"][]="no ".$conf["func"]." permission";
226 liveuser 17103
 
66 liveuser 17104
					#回傳結果
17105
					return $result;
226 liveuser 17106
 
66 liveuser 17107
					}#if end
226 liveuser 17108
 
66 liveuser 17109
				*/
226 liveuser 17110
 
66 liveuser 17111
				#結束 switch
17112
				break;
226 liveuser 17113
 
66 liveuser 17114
			#如果是"public"賬戶,代表具備一般使用權限的公用使用者.
17115
			case "public":
226 liveuser 17116
 
66 liveuser 17117
				#預設可以使用的功能只有"*",代表所有功能都能用.
17118
				$authFunc=array("auth","checkAuth","basic");
226 liveuser 17119
 
66 liveuser 17120
				#如果有 publicAllowFuncPlus
17121
				if(count($conf["publicAllowFuncPlus"])>0){
226 liveuser 17122
 
66 liveuser 17123
					#合併 array
17124
					#函式說明:
17125
					#將多個一維陣列串聯起來,key從0開始排序.
17126
					#回傳的結果:
17127
					#$result["status"],"true"表執行正常,"false"代表執行不正常.
17128
					#$result["error"],錯誤訊息陣列.
17129
					#$result["function"],當前執行的函數.
17130
					#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
17131
					#$result["content"],合併好的一維陣列.
17132
					#必填參數
17133
					#$conf["inputArray"],陣列,要合併的一維陣列變數,例如:=array($array1,$array2);
17134
					$conf["arrays::mergeArray"]["inputArray"]=array($authFunc,$conf["publicAllowFuncPlus"]);
17135
					#可省略參數:
17136
					#$conf["allowRepeat"],字串,預設為"true",允許重複的結果;若為"false"則不會出現重複的元素內容.
17137
					$conf["arrays::mergeArray"]["allowRepeat"]="false";
17138
					#$conf["looseDiff"],字串,預設為"false",代表要嚴謹判斷為有相異,例如陣列中元素的key順序不同(整數)就代表有相異;反之為"true",例如陣列中元素的key順序不同(非整數),但value有相同,則視為無相異.
17139
					$conf["arrays::mergeArray"]["looseDiff"]="true";
17140
					#參考資料:
17141
					#無.
17142
					#備註:
17143
					#無.
17144
					$mergeArray=arrays::mergeArray($conf["arrays::mergeArray"]);
17145
					unset($conf["arrays::mergeArray"]);
226 liveuser 17146
 
66 liveuser 17147
					#如果執行失敗
17148
					if($mergeArray["status"]==="false"){
17149
 
17150
						#設置執行異常
17151
						$result["status"]="false";
17152
 
17153
						#設置執行錯誤
17154
						$result["error"]=$mergeArray;
17155
 
17156
						#回傳結果
17157
						return $result;
17158
 
17159
						}#if end
226 liveuser 17160
 
66 liveuser 17161
					#取得合併好允許使用的清單
17162
					$authFunc=$mergeArray["content"];
226 liveuser 17163
 
66 liveuser 17164
					}#if end
226 liveuser 17165
 
17166
				#如果沒有權限使用
66 liveuser 17167
				if(!in_array($conf["func"],$authFunc)){
226 liveuser 17168
 
66 liveuser 17169
					#設置執行異常
17170
					$result["status"]="false";
17171
 
17172
					#設置執行錯誤
17173
					$result["error"][]="no ".$conf["func"]." permission";
226 liveuser 17174
 
66 liveuser 17175
					#回傳結果
17176
					return $result;
226 liveuser 17177
 
66 liveuser 17178
					}#if end
226 liveuser 17179
 
66 liveuser 17180
				break;
226 liveuser 17181
 
66 liveuser 17182
			#其他結果
17183
			default:
226 liveuser 17184
 
66 liveuser 17185
				#依照指定的資料來源進行權限與可用功能的檢查
17186
				#...
226 liveuser 17187
 
66 liveuser 17188
				#設置執行異常
17189
				$result["status"]="false";
17190
 
17191
				#設置執行錯誤
17192
				$result["error"][]="not supported authStatus(".$authStatus.")";
226 liveuser 17193
 
66 liveuser 17194
				#回傳結果
17195
				return $result;
226 liveuser 17196
 
66 liveuser 17197
			}#switch end
226 liveuser 17198
 
66 liveuser 17199
			#設置執行正常
17200
			$result["status"]="true";
17201
 
17202
			#回傳結果
17203
			return $result;
226 liveuser 17204
 
66 liveuser 17205
		}#function checkAuth end
226 liveuser 17206
 
66 liveuser 17207
	/*
17208
	#函式說明:
17209
	#提供webSock::nativeSocketTcpIpServer用於接受"auth:"開頭的訊息進行認證使用者的功能.
17210
	#回傳結果:
17211
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
17212
	#$result["error"],執行不正常結束的錯訊息陣列.
17213
	#$result["argu"],陣列,使用的參數.
17214
	#必填參數:
17215
	#$conf["data"],字串,收到的bin2hex編碼後果gpg加密過後的json格式資料,必填的key有"randomStr","username","password".
17216
	$conf["data"]="";
17217
	#$conf["serverSock"],resource,web socket server socket
17218
	$conf["serverSock"]=$resource;
17219
	#$conf["clientSock"],$resource,web socket client socket
17220
	$conf["clientSock"]=$resource;
17221
	#$conf["clientInfo"],陣列,web socket client info.
17222
	$conf["clientInfo"]=array();
17223
	#$conf["clientIndex"],整數.web socket client index.
17224
	$conf["clientIndex"];
17225
	#$conf["allConn"],陣列,all web socket client info.
17226
	$conf["allConn"]=array();
17227
	#可省略參數:
17228
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
17229
	#$conf["wsMode"]="true";
17230
	#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
17231
	#$conf["gpgId"]=gnupgId;
17232
	#參考資料:
17233
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
17234
	#備註:
17235
	#無.
17236
	*/
17237
	public static function auth(&$conf){
226 liveuser 17238
 
66 liveuser 17239
		#初始化要回傳的結果
17240
		$result=array();
17241
 
17242
		#取得當前執行的函數名稱
17243
		$result["function"]=__FUNCTION__;
17244
 
17245
		#涵式說明:
17246
		#判斷當前環境為web還是cmd
17247
		#回傳結果:
17248
		#$result,"web"或"cmd"
17249
		if(csInformation::getEnv()==="web"){
226 liveuser 17250
 
66 liveuser 17251
			#設置執行失敗
17252
			$result["status"]="false";
226 liveuser 17253
 
66 liveuser 17254
			#設置執行錯誤訊息
17255
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 17256
 
66 liveuser 17257
			#回傳結果
17258
			return $result;
226 liveuser 17259
 
66 liveuser 17260
			}#if end
17261
 
17262
		#取得參數
17263
		$result["argu"]=$conf;
17264
 
17265
		#如果 $conf 不為陣列
17266
		if(gettype($conf)!="array"){
226 liveuser 17267
 
66 liveuser 17268
			#設置執行失敗
17269
			$result["status"]="false";
226 liveuser 17270
 
66 liveuser 17271
			#設置執行錯誤訊息
17272
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 17273
 
66 liveuser 17274
			#如果傳入的參數為 null
17275
			if($conf==null){
226 liveuser 17276
 
66 liveuser 17277
				#設置執行錯誤訊息
17278
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 17279
 
66 liveuser 17280
				}#if end
17281
 
17282
			#回傳結果
17283
			return $result;
226 liveuser 17284
 
66 liveuser 17285
			}#if end
226 liveuser 17286
 
66 liveuser 17287
		#檢查參數
17288
		#函式說明:
17289
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
17290
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
17291
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
17292
		#$result["function"],當前執行的函式名稱.
17293
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
17294
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
17295
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
17296
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
17297
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
17298
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
17299
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
17300
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
17301
		#必填寫的參數:
17302
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
17303
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
17304
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
17305
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientInfo","clientIndex","allConn");
17306
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
17307
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","array","string","array");
17308
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
17309
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
17310
		#可以省略的參數:
17311
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
17312
		#$conf["canBeEmptyString"]="false";
17313
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
17314
		#$conf["canNotBeEmpty"]=array();
17315
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
17316
		#$conf["canBeEmpty"]=array();
17317
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
17318
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
17319
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
17320
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode","gpgId");
226 liveuser 17321
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 17322
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
17323
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
17324
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",gnupgId);
17325
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
17326
		#$conf["arrayCountEqualCheck"][]=array();
17327
		#參考資料來源:
17328
		#array_keys=>http://php.net/manual/en/function.array-keys.php
17329
		#建議:
17330
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
17331
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
17332
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 17333
 
66 liveuser 17334
		#如果檢查參數失敗
17335
		if($checkArguments["status"]==="false"){
226 liveuser 17336
 
66 liveuser 17337
			#設置執行失敗
17338
			$result["status"]="false";
226 liveuser 17339
 
66 liveuser 17340
			#設置執行錯誤訊息
17341
			$result["error"]=$checkArguments;
226 liveuser 17342
 
66 liveuser 17343
			#回傳結果
17344
			return $result;
226 liveuser 17345
 
66 liveuser 17346
			}#if end
226 liveuser 17347
 
66 liveuser 17348
		#如果檢查參數不通過
17349
		if($checkArguments["passed"]==="false"){
226 liveuser 17350
 
66 liveuser 17351
			#設置執行失敗
17352
			$result["status"]="false";
226 liveuser 17353
 
66 liveuser 17354
			#設置執行錯誤訊息
17355
			$result["error"]=$checkArguments;
226 liveuser 17356
 
66 liveuser 17357
			#回傳結果
17358
			return $result;
226 liveuser 17359
 
66 liveuser 17360
			}#if end
17361
 
17362
		#取得收到的訊息
17363
		$receivedData=$conf["data"];
226 liveuser 17364
 
66 liveuser 17365
		#取得 server 的 socket
17366
		$serverSocket=$conf["serverSock"];
226 liveuser 17367
 
66 liveuser 17368
		#取得 client 的 socket
17369
		$clientSocket=$conf["clientSock"];
226 liveuser 17370
 
66 liveuser 17371
		#取得 client 的資訊
17372
		$clientInfo=$conf["clientInfo"];
226 liveuser 17373
 
66 liveuser 17374
		#取得 client 的索引
17375
		$clientIndex=$conf["clientIndex"];
226 liveuser 17376
 
66 liveuser 17377
		#取得認證狀態
17378
		$authStatus=&$conf["clientInfo"][$conf["clientIndex"]]["auth"];
226 liveuser 17379
 
66 liveuser 17380
		#取得 all clients 的資訊
17381
		$allConn=&$conf["allConn"];
226 liveuser 17382
 
66 liveuser 17383
		#hex2bin
17384
		#函式說明:
17385
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
17386
		#回傳結果:
226 liveuser 17387
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 17388
		#$result["function"],當前執行的函數名稱.
17389
		#$result["content"],加密後的結果.
17390
		#$result["error"],錯誤訊息陣列.
17391
		#$result["argu"],使用的參數.
17392
		#必填參數:
17393
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
17394
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
17395
		#$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".
17396
		$conf["authenticate::enCodeStr"]["enCodeType"]="hex2bin";
17397
		#可省略參數:
17398
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
17399
		#$conf["sha1Raw"]="false";
17400
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
17401
		#$conf["p_hash"]="";
17402
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
17403
		#$conf["keyForAes256"]="";
17404
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
17405
		#$conf["aes256Encode"]="";
17406
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
17407
		#$conf["qbpwcfDecode"]="false";
17408
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
17409
		#$conf["gpgDecrypt"]="false";
17410
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
17411
		#$conf["gpgId"]="";
17412
		#參考資料:
17413
		#sha1=>http://php.net/manual/en/function.sha1.php
17414
		#md5=>http://php.net/manual/en/function.md5.php
17415
		#password_hash=>http://php.net/manual/en/function.password-hash.php
17416
		#password_verify=>http://php.net/manual/en/function.password-verify.php
17417
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
17418
		#備註:
17419
		#無.
17420
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
17421
		unset($conf["authenticate::enCodeStr"]);
17422
 
17423
		#如果執行失敗
17424
		if($enCodeStr["status"]==="false"){
17425
 
17426
			#設置執行異常
17427
			$result["status"]="false";
17428
 
17429
			#設置執行錯誤
17430
			$result["error"]=$enCodeStr;
17431
 
17432
			#回傳結果
17433
			return $result;
17434
 
17435
			}#if end
17436
 
17437
		#取得hex2bin後的字串
17438
		$receivedData=$enCodeStr["content"];
226 liveuser 17439
 
66 liveuser 17440
		#gpg decrypt
17441
		#函式說明:
17442
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
17443
		#回傳結果:
226 liveuser 17444
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 17445
		#$result["function"],當前執行的函數名稱.
17446
		#$result["content"],加密後的結果.
17447
		#$result["error"],錯誤訊息陣列.
17448
		#$result["argu"],使用的參數.
17449
		#必填參數:
17450
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
17451
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
17452
		#$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".
17453
		$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
17454
		#可省略參數:
17455
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
17456
		#$conf["sha1Raw"]="false";
17457
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
17458
		#$conf["p_hash"]="";
17459
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
17460
		#$conf["keyForAes256"]="";
17461
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
17462
		#$conf["aes256Encode"]="";
17463
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
17464
		#$conf["qbpwcfDecode"]="false";
17465
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
17466
		$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
17467
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
17468
		$conf["authenticate::enCodeStr"]["gpgId"]=$conf["gpgId"];
17469
		#參考資料:
17470
		#sha1=>http://php.net/manual/en/function.sha1.php
17471
		#md5=>http://php.net/manual/en/function.md5.php
17472
		#password_hash=>http://php.net/manual/en/function.password-hash.php
17473
		#password_verify=>http://php.net/manual/en/function.password-verify.php
17474
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
17475
		#備註:
17476
		#無.
17477
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
17478
		unset($conf["authenticate::enCodeStr"]);
17479
 
17480
		#如果執行失敗
17481
		if($enCodeStr["status"]==="false"){
17482
 
17483
			#設置執行異常
17484
			$result["status"]="false";
17485
 
17486
			#設置執行錯誤
17487
			$result["error"]=$enCodeStr;
17488
 
17489
			#回傳結果
17490
			return $result;
17491
 
17492
			}#if end
17493
 
17494
		#取得解密後的字串
17495
		$receivedData=$enCodeStr["content"];
226 liveuser 17496
 
66 liveuser 17497
		#json_decode
17498
		$receivedData=json_decode($receivedData);
226 liveuser 17499
 
66 liveuser 17500
		#如果decode後的內容不為物件
17501
		if(gettype($receivedData)!=="Object"){
226 liveuser 17502
 
66 liveuser 17503
			#設置不適用
17504
			$result["status"]="continue";
226 liveuser 17505
 
66 liveuser 17506
			#回傳結果
17507
			return $result;
226 liveuser 17508
 
66 liveuser 17509
			}#if end
226 liveuser 17510
 
66 liveuser 17511
		#檢查物件是否符合格式
17512
		#函式說明:
17513
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容.
17514
		#回傳結果:
17515
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
17516
		#$result["error"],執行不正常結束的錯訊息陣列.
17517
		#$result["simpleError"],簡單表示的錯誤訊息.
17518
		#$result["function"],當前執行的函式名稱.
17519
		#$result["argu"],設置給予的參數.
17520
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
17521
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
17522
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
17523
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
17524
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
17525
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
17526
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
17527
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
17528
		#必填參數:
17529
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
17530
		$conf["variableCheck::checkArguments"]["varInput"]=&$receivedData;
17531
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
17532
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
17533
		#可省略參數:
17534
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
17535
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("user","type","secrect");
17536
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null、any代表不指定變數形態.其中 resource也包含"resource (closed)".
17537
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string","string");
17538
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
17539
		#$conf["canBeEmptyString"]="false";
17540
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
17541
		#$conf["canNotBeEmpty"]=array();
17542
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
17543
		#$conf["canBeEmpty"]=array();
17544
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
17545
		#$conf["skipableVariableCanNotBeEmpty"]=array();
17546
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
17547
		#$conf["skipableVariableName"]=array();
17548
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
17549
		#$conf["skipableVariableType"]=array();
17550
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
17551
		#$conf["skipableVarDefaultValue"]=array("");
17552
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
17553
		#$conf["disallowAllSkipableVarIsEmpty"]="";
17554
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
17555
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
17556
		#$conf["disallowAllSkipableVarNotExist"],字串,是否不允許每個可省略參數都不存在,預設為"false"代表允許,反之為"true".
17557
		#$conf["disallowAllSkipableVarNotExist"]="";
17558
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
17559
		#$conf["arrayCountEqualCheck"][]=array();
17560
		#參考資料:
17561
		#array_keys=>http://php.net/manual/en/function.array-keys.php
17562
		#備註:
17563
		#無.
17564
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
17565
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 17566
 
66 liveuser 17567
		#如果執行異常
17568
		if($checkArguments["status"]==="false"){
226 liveuser 17569
 
66 liveuser 17570
			#設置異常
17571
			$result["status"]="false";
226 liveuser 17572
 
66 liveuser 17573
			#設置錯誤訊息
17574
			$result["error"]=$checkArguments;
226 liveuser 17575
 
66 liveuser 17576
			#回傳結果
17577
			return $result;
226 liveuser 17578
 
66 liveuser 17579
			}#if end
226 liveuser 17580
 
66 liveuser 17581
		#如果參數不合法
17582
		if($checkArguments["passed"]==="false"){
226 liveuser 17583
 
66 liveuser 17584
			#設置不適用
17585
			$result["status"]="continue";
226 liveuser 17586
 
66 liveuser 17587
			#回傳結果
17588
			return $result;
226 liveuser 17589
 
66 liveuser 17590
			}#if end
226 liveuser 17591
 
66 liveuser 17592
		#取得使用者名稱
17593
		$user=$receivedData->user;
226 liveuser 17594
 
66 liveuser 17595
		#取得密碼或金鑰內容
17596
		$secrect=$receivedData->secrect;
226 liveuser 17597
 
66 liveuser 17598
		#依照驗證方式
17599
		switch($receivedData->type){
226 liveuser 17600
 
66 liveuser 17601
			#若是密碼認證
17602
			case "password":
226 liveuser 17603
 
66 liveuser 17604
				#測試 $user 與 password 的組合是否能夠認證.
17605
				#函式說明:
17606
				#驗證Linux使用者的密碼是否正確.
17607
				#回傳結果:
226 liveuser 17608
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 17609
				#$result["function"],當前執行的函數名稱.
17610
				#$result["error"],錯誤訊息陣列.
17611
				#$result["warninig"],警告訊息陣列.
17612
				#$result["valid"],是否為存在的使用者且密碼正確.
17613
				#必填參數:
17614
				#$conf["username"],字串,要驗證的使用者名稱.
17615
				$conf["authenticate::validUser"]["username"]=$user;
17616
				#$conf["password"],字串,用於驗證使用者的密碼.
17617
				$conf["authenticate::validUser"]["password"]=$secrect;
17618
				#$conf["fileArgu"],字串,變數__FILE__的內容.
17619
				$conf["authenticate::validUser"]["fileArgu"]=__FILE__;
17620
				#可省略參數:
17621
				#無.
17622
				#參考資料:
17623
				#無.
17624
				#備註:
17625
				#僅能在命令列環境下運行.
17626
				$validUser=authenticate::validUser($conf["authenticate::validUser"]);
17627
				unset($conf["authenticate::validUser"]);
226 liveuser 17628
 
66 liveuser 17629
				#如果執行異常
17630
				if($validUser["status"]==="false"){
226 liveuser 17631
 
66 liveuser 17632
					#設置異常
17633
					$result["status"]="false";
226 liveuser 17634
 
66 liveuser 17635
					#設置錯誤訊息
17636
					$result["error"]=$validUser;
226 liveuser 17637
 
66 liveuser 17638
					#回傳結果
17639
					return $result;
226 liveuser 17640
 
66 liveuser 17641
					}#if end
226 liveuser 17642
 
66 liveuser 17643
				#如果認證失敗
17644
				if($validUser["valid"]==="false"){
226 liveuser 17645
 
66 liveuser 17646
					#記錄該 client 認證失敗的事件
17647
					$allConn[$clientIndex]["authFailed"][]=array("time"=>time(),"user"=>$user);
226 liveuser 17648
 
66 liveuser 17649
					#針對每次認證失敗的記錄
17650
					for($i=0;$i<count($allConn[$clientIndex]["authFailed"]);$i++){
226 liveuser 17651
 
66 liveuser 17652
						#如果有下一個事件
17653
						if(isset($allConn[$clientIndex]["authFailed"][$i+1])){
226 liveuser 17654
 
66 liveuser 17655
							#如果本次跟下次事件的時間間隔小於60秒
17656
							if($allConn[$clientIndex]["authFailed"][$i+1]["time"] - $allConn[$clientIndex]["authFailed"][$i]["time"] > 60){
226 liveuser 17657
 
66 liveuser 17658
								#移除本次記錄
17659
								array_shift($allConn[$clientIndex]["authFailed"]);
226 liveuser 17660
 
66 liveuser 17661
								#新記錄的索引減少了1,因此更新$i
17662
								$i--;
226 liveuser 17663
 
66 liveuser 17664
								}#if end
226 liveuser 17665
 
66 liveuser 17666
							}#if end
226 liveuser 17667
 
66 liveuser 17668
						}#foreach end
226 liveuser 17669
 
66 liveuser 17670
					#如果總事件次數大於3
17671
					if(count($allConn[$clientIndex]["authFailed"])>3){
226 liveuser 17672
 
66 liveuser 17673
						#設置異常
17674
						$result["status"]="false";
226 liveuser 17675
 
66 liveuser 17676
						#設置錯誤訊息
17677
						$result["error"]=$allConn[$clientIndex]["authFailed"];
226 liveuser 17678
 
66 liveuser 17679
						#回傳結果
17680
						return $result;
226 liveuser 17681
 
66 liveuser 17682
						}#if end
226 liveuser 17683
 
66 liveuser 17684
					#設置正常
17685
					$result["status"]="true";
226 liveuser 17686
 
66 liveuser 17687
					#回傳結果
17688
					return $result;
226 liveuser 17689
 
66 liveuser 17690
					}#if end
226 liveuser 17691
 
66 liveuser 17692
				#執行到這邊代表使用者認證通過
226 liveuser 17693
 
66 liveuser 17694
				#依照 user 取得其所屬 group
17695
				#函式說明:
17696
				#id指令來取得目標賬號的群組資訊
17697
				#回傳結果:
17698
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
17699
				#$reuslt["error"],執行不正常結束的錯訊息陣列.
17700
				#$result["function"],當前執行的函式名稱.
17701
				#$result["content"],呼叫完WebService所得回傳結果.
17702
				#$result["content"]["groupId"],群組的id.
17703
				#$result["content"]["belongGroupName"],陣列,隸屬的群組名稱陣列.
17704
				#$result["content"]["belongGroupId"],陣列,隸屬的群組id.
17705
				#必填參數:
17706
				#$conf["user"],字串,要取得群組資訊的目標使用者名稱.
17707
				$conf["authenticate::getUserGroup"]["user"]=$user;
17708
				#可省略參數:
17709
				#無.
17710
				#參考資料:
17711
				#無.
17712
				#備註:
17713
				#無.
17714
				$getUserGroup=authenticate::getUserGroup($conf["authenticate::getUserGroup"]);
17715
				unset($conf["authenticate::getUserGroup"]);
226 liveuser 17716
 
66 liveuser 17717
				#如果執行異常
17718
				if($getUserGroup["status"]==="false"){
226 liveuser 17719
 
66 liveuser 17720
					#設置異常
17721
					$result["status"]="false";
226 liveuser 17722
 
66 liveuser 17723
					#設置錯誤訊息
17724
					$result["error"]=$getUserGroup;
226 liveuser 17725
 
66 liveuser 17726
					#回傳結果
17727
					return $result;
226 liveuser 17728
 
66 liveuser 17729
					}#if end
226 liveuser 17730
 
66 liveuser 17731
				#設置預設的權限為 "false"
17732
				$authStatus="false";
226 liveuser 17733
 
66 liveuser 17734
				#針對每個取得的群組名稱
17735
				foreach($getUserGroup["content"]["belongGroupName"] as $groupName){
226 liveuser 17736
 
66 liveuser 17737
					#如果是 root
17738
					if($groupName==="root"){
226 liveuser 17739
 
66 liveuser 17740
						#設置得到的權限
17741
						$authStatus=$groupName;
226 liveuser 17742
 
66 liveuser 17743
						#結束 foreach
17744
						break;
226 liveuser 17745
 
66 liveuser 17746
						}#if end
226 liveuser 17747
 
66 liveuser 17748
					#反之如果是公開的使用者
17749
					else if($groupName==="public"){
226 liveuser 17750
 
66 liveuser 17751
						#設置得到的權限
17752
						$authStatus=$groupName;
226 liveuser 17753
 
66 liveuser 17754
						}#if end
226 liveuser 17755
 
66 liveuser 17756
					#其他群組名稱
17757
					else{
226 liveuser 17758
 
66 liveuser 17759
						#跳過
17760
						continue;
226 liveuser 17761
 
66 liveuser 17762
						}#else end
226 liveuser 17763
 
66 liveuser 17764
					}#foreach end
226 liveuser 17765
 
66 liveuser 17766
				#設置正常
17767
				$result["status"]="true";
226 liveuser 17768
 
66 liveuser 17769
				#回傳結果
17770
				return $result;
226 liveuser 17771
 
66 liveuser 17772
				#跳出 switch
17773
				break;
226 liveuser 17774
 
66 liveuser 17775
			#若是金鑰認證
17776
			case "key":
226 liveuser 17777
 
66 liveuser 17778
				#測試 $user 與 key 的組合是否能夠認證.
17779
				#函式說明:
17780
				#驗證Linux使用者的密碼或ssh private key是否正確.
17781
				#回傳結果:
226 liveuser 17782
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 17783
				#$result["function"],當前執行的函數名稱.
17784
				#$result["error"],錯誤訊息陣列.
17785
				#$result["warninig"],警告訊息陣列.
17786
				#$result["valid"],是否為存在的使用者且密碼正確.
17787
				#必填參數:
17788
				#$conf["username"],字串,要驗證的使用者名稱.
17789
				$conf["authenticate::validUser"]["username"]=$user;
17790
				#$conf["password"],字串,用於驗證使用者的密碼.
17791
				$conf["authenticate::validUser"]["password"]=$secrect;
17792
				#$conf["fileArgu"],字串,變數__FILE__的內容.
17793
				$conf["authenticate::validUser"]["fileArgu"]=__FILE__;
17794
				#可省略參數:
17795
				#$conf["sshPrivateKey"],字串,"true"代表password為ssh private key的內容;反之預設為密碼,設置為"false".
17796
				$conf["authenticate::validUser"]["sshPrivateKey"]="true";
17797
				#參考資料:
17798
				#無.
17799
				#備註:
17800
				#僅能在命令列環境下運.
17801
				#目前僅支援驗證執行php端的使用者.
17802
				$validUser=authenticate::validUser($conf["authenticate::validUser"]);
17803
				unset($conf["authenticate::validUser"]);
226 liveuser 17804
 
66 liveuser 17805
				#如果執行異常
17806
				if($validUser["status"]==="false"){
226 liveuser 17807
 
66 liveuser 17808
					#設置異常
17809
					$result["status"]="false";
226 liveuser 17810
 
66 liveuser 17811
					#設置錯誤訊息
17812
					$result["error"]=$validUser;
226 liveuser 17813
 
66 liveuser 17814
					#回傳結果
17815
					return $result;
226 liveuser 17816
 
66 liveuser 17817
					}#if end
226 liveuser 17818
 
66 liveuser 17819
				#如果認證失敗
17820
				if($validUser["valid"]==="false"){
226 liveuser 17821
 
66 liveuser 17822
					#記錄該 client 認證失敗的事件
17823
					$allConn[$clientIndex]["authFailed"][]=array("time"=>time(),"user"=>$user);
226 liveuser 17824
 
66 liveuser 17825
					#針對每次認證失敗的記錄
17826
					for($i=0;$i<count($allConn[$clientIndex]["authFailed"]);$i++){
226 liveuser 17827
 
66 liveuser 17828
						#如果有下一個事件
17829
						if(isset($allConn[$clientIndex]["authFailed"][$i+1])){
226 liveuser 17830
 
66 liveuser 17831
							#如果本次跟下次事件的時間間隔小於60秒
17832
							if($allConn[$clientIndex]["authFailed"][$i+1]["time"] - $allConn[$clientIndex]["authFailed"][$i]["time"] > 60){
226 liveuser 17833
 
66 liveuser 17834
								#移除本次記錄
17835
								array_shift($allConn[$clientIndex]["authFailed"]);
226 liveuser 17836
 
66 liveuser 17837
								#新記錄的索引減少了1,因此更新$i
17838
								$i--;
226 liveuser 17839
 
66 liveuser 17840
								}#if end
226 liveuser 17841
 
66 liveuser 17842
							}#if end
226 liveuser 17843
 
66 liveuser 17844
						}#foreach end
226 liveuser 17845
 
66 liveuser 17846
					#如果總事件次數大於3
17847
					if(count($allConn[$clientIndex]["authFailed"])>3){
226 liveuser 17848
 
66 liveuser 17849
						#設置異常
17850
						$result["status"]="false";
226 liveuser 17851
 
66 liveuser 17852
						#設置錯誤訊息
17853
						$result["error"]=$allConn[$clientIndex]["authFailed"];
226 liveuser 17854
 
66 liveuser 17855
						#回傳結果
17856
						return $result;
226 liveuser 17857
 
66 liveuser 17858
						}#if end
226 liveuser 17859
 
66 liveuser 17860
					#設置正常
17861
					$result["status"]="true";
226 liveuser 17862
 
66 liveuser 17863
					#回傳結果
17864
					return $result;
226 liveuser 17865
 
66 liveuser 17866
					}#if end
226 liveuser 17867
 
66 liveuser 17868
				#執行到這邊代表使用者認證通過
226 liveuser 17869
 
66 liveuser 17870
				#依照 user 取得其所屬 group
17871
				#函式說明:
17872
				#id指令來取得目標賬號的群組資訊
17873
				#回傳結果:
17874
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
17875
				#$reuslt["error"],執行不正常結束的錯訊息陣列.
17876
				#$result["function"],當前執行的函式名稱.
17877
				#$result["content"],呼叫完WebService所得回傳結果.
17878
				#$result["content"]["groupId"],群組的id.
17879
				#$result["content"]["belongGroupName"],陣列,隸屬的群組名稱陣列.
17880
				#$result["content"]["belongGroupId"],陣列,隸屬的群組id.
17881
				#必填參數:
17882
				#$conf["user"],字串,要取得群組資訊的目標使用者名稱.
17883
				$conf["authenticate::getUserGroup"]["user"]=$user;
17884
				#可省略參數:
17885
				#無.
17886
				#參考資料:
17887
				#無.
17888
				#備註:
17889
				#無.
17890
				$getUserGroup=authenticate::getUserGroup($conf["authenticate::getUserGroup"]);
17891
				unset($conf["authenticate::getUserGroup"]);
226 liveuser 17892
 
66 liveuser 17893
				#如果執行異常
17894
				if($getUserGroup["status"]==="false"){
226 liveuser 17895
 
66 liveuser 17896
					#設置異常
17897
					$result["status"]="false";
226 liveuser 17898
 
66 liveuser 17899
					#設置錯誤訊息
17900
					$result["error"]=$getUserGroup;
226 liveuser 17901
 
66 liveuser 17902
					#回傳結果
17903
					return $result;
226 liveuser 17904
 
66 liveuser 17905
					}#if end
226 liveuser 17906
 
66 liveuser 17907
				#設置預設的權限為 "false"
17908
				$authStatus="false";
226 liveuser 17909
 
66 liveuser 17910
				#針對每個取得的群組名稱
17911
				foreach($getUserGroup["content"]["belongGroupName"] as $groupName){
226 liveuser 17912
 
66 liveuser 17913
					#如果是 root
17914
					if($groupName==="root"){
226 liveuser 17915
 
66 liveuser 17916
						#設置得到的權限
17917
						$authStatus=$groupName;
226 liveuser 17918
 
66 liveuser 17919
						#結束 foreach
17920
						break;
226 liveuser 17921
 
66 liveuser 17922
						}#if end
226 liveuser 17923
 
66 liveuser 17924
					#反之如果是公開的使用者
17925
					else if($groupName==="public"){
226 liveuser 17926
 
66 liveuser 17927
						#設置得到的權限
17928
						$authStatus=$groupName;
226 liveuser 17929
 
66 liveuser 17930
						}#if end
226 liveuser 17931
 
66 liveuser 17932
					#其他群組名稱
17933
					else{
226 liveuser 17934
 
66 liveuser 17935
						#跳過
17936
						continue;
226 liveuser 17937
 
66 liveuser 17938
						}#else end
226 liveuser 17939
 
66 liveuser 17940
					}#foreach end
226 liveuser 17941
 
66 liveuser 17942
				#設置正常
17943
				$result["status"]="true";
226 liveuser 17944
 
66 liveuser 17945
				#回傳結果
17946
				return $result;
226 liveuser 17947
 
66 liveuser 17948
				#跳出 switch
17949
				break;
226 liveuser 17950
 
66 liveuser 17951
			#其他類型
17952
			default:
226 liveuser 17953
 
66 liveuser 17954
				#設置不適用
17955
				$result["status"]="continue";
226 liveuser 17956
 
66 liveuser 17957
				#回傳結果
17958
				return $result;
226 liveuser 17959
 
66 liveuser 17960
			}#switch end
226 liveuser 17961
 
66 liveuser 17962
		#執行到這邊代表異常
17963
 
17964
		#設置異常
17965
		$result["status"]="false";
17966
 
17967
		#回傳結果
17968
		return $result;
226 liveuser 17969
 
66 liveuser 17970
		}#function auth end
226 liveuser 17971
 
66 liveuser 17972
	/*
17973
	#函式說明:
17974
	#提供webSock::nativeSocketTcpIpServer使用基本功能(basic).
17975
	#回傳結果:
17976
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
17977
	#$result["error"],執行不正常結束的錯訊息陣列.
17978
	#$result["argu"],陣列,使用的參數.
17979
	#必填參數:
17980
	#$conf["data"],字串,收到的bin2hex編碼後再gpg加密過後的json格式資料.
17981
	$conf["data"]="";
17982
	#$conf["serverSock"],resource,web socket server socket
17983
	$conf["serverSock"]=$resource;
17984
	#$conf["clientSock"],$resource,web socket client socket
17985
	$conf["clientSock"]=$resource;
17986
	#$conf["clientInfo"],陣列,web socket client info.
17987
	$conf["clientInfo"]=array();
17988
	#$conf["clientIndex"],整數.web socket client index.
17989
	$conf["clientIndex"];
17990
	#$conf["allConn"],陣列,all web socket client info.
17991
	$conf["allConn"]=array();
17992
	#可省略參數:
17993
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
17994
	#$conf["wsMode"]="true";
17995
	#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
17996
	#$conf["gpgId"]=gnupgId;
17997
	#參考資料:
17998
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
17999
	#備註:
18000
	#收到用戶的"id?"訊息,會回傳用戶的id.
18001
	#收到用戶的"ids?"訊息,會回傳非自己的所有用戶id.
18002
	#收到用戶的"talkTo?"訊息,會回傳目前在跟誰談話.
18003
	#收到用戶的"talkTo:client-id"訊息,會建立與id對應的用戶對話,此後傳遞的訊息均會給對方.
18004
	#結束連線的訊息"quit".
18005
	*/
18006
	public static function basic(&$conf){
226 liveuser 18007
 
66 liveuser 18008
		#初始化要回傳的結果
18009
		$result=array();
18010
 
18011
		#取得當前執行的函數名稱
18012
		$result["function"]=__FUNCTION__;
18013
 
18014
		#涵式說明:
18015
		#判斷當前環境為web還是cmd
18016
		#回傳結果:
18017
		#$result,"web"或"cmd"
18018
		if(csInformation::getEnv()==="web"){
226 liveuser 18019
 
66 liveuser 18020
			#設置執行失敗
18021
			$result["status"]="false";
226 liveuser 18022
 
66 liveuser 18023
			#設置執行錯誤訊息
18024
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 18025
 
66 liveuser 18026
			#回傳結果
18027
			return $result;
226 liveuser 18028
 
66 liveuser 18029
			}#if end
18030
 
18031
		#取得參數
18032
		$result["argu"]=$conf;
18033
 
18034
		#如果 $conf 不為陣列
18035
		if(gettype($conf)!="array"){
226 liveuser 18036
 
66 liveuser 18037
			#設置執行失敗
18038
			$result["status"]="false";
226 liveuser 18039
 
66 liveuser 18040
			#設置執行錯誤訊息
18041
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 18042
 
66 liveuser 18043
			#如果傳入的參數為 null
18044
			if($conf==null){
226 liveuser 18045
 
66 liveuser 18046
				#設置執行錯誤訊息
18047
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 18048
 
66 liveuser 18049
				}#if end
18050
 
18051
			#回傳結果
18052
			return $result;
226 liveuser 18053
 
66 liveuser 18054
			}#if end
226 liveuser 18055
 
66 liveuser 18056
		#檢查參數
18057
		#函式說明:
18058
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
18059
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18060
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
18061
		#$result["function"],當前執行的函式名稱.
18062
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
18063
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
18064
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
18065
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
18066
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
18067
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
18068
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
18069
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
18070
		#必填寫的參數:
18071
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
18072
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
18073
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
18074
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientInfo","clientIndex","allConn");
18075
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
18076
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","array","string","array");
18077
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
18078
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
18079
		#可以省略的參數:
18080
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
18081
		#$conf["canBeEmptyString"]="false";
18082
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
18083
		#$conf["canNotBeEmpty"]=array();
18084
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
18085
		#$conf["canBeEmpty"]=array();
18086
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
18087
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
18088
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
18089
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode","gpgId");
226 liveuser 18090
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 18091
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
18092
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
18093
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",gnupgId);
18094
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
18095
		#$conf["arrayCountEqualCheck"][]=array();
18096
		#參考資料來源:
18097
		#array_keys=>http://php.net/manual/en/function.array-keys.php
18098
		#建議:
18099
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
18100
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
18101
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 18102
 
66 liveuser 18103
		#如果檢查參數失敗
18104
		if($checkArguments["status"]==="false"){
226 liveuser 18105
 
66 liveuser 18106
			#設置執行失敗
18107
			$result["status"]="false";
226 liveuser 18108
 
66 liveuser 18109
			#設置執行錯誤訊息
18110
			$result["error"]=$checkArguments;
226 liveuser 18111
 
66 liveuser 18112
			#回傳結果
18113
			return $result;
226 liveuser 18114
 
66 liveuser 18115
			}#if end
226 liveuser 18116
 
66 liveuser 18117
		#如果檢查參數不通過
18118
		if($checkArguments["passed"]==="false"){
226 liveuser 18119
 
66 liveuser 18120
			#設置執行失敗
18121
			$result["status"]="false";
226 liveuser 18122
 
66 liveuser 18123
			#設置執行錯誤訊息
18124
			$result["error"]=$checkArguments;
226 liveuser 18125
 
66 liveuser 18126
			#回傳結果
18127
			return $result;
226 liveuser 18128
 
66 liveuser 18129
			}#if end
18130
 
18131
		#取得收到的訊息
18132
		$receivedData=$conf["data"];
226 liveuser 18133
 
66 liveuser 18134
		#取得 server 的 socket
18135
		$serverSocket=$conf["serverSock"];
226 liveuser 18136
 
66 liveuser 18137
		#取得 client 的 socket
18138
		$clientSocket=$conf["clientSock"];
226 liveuser 18139
 
66 liveuser 18140
		#取得 client 的資訊
18141
		$clientInfo=$conf["clientInfo"];
226 liveuser 18142
 
66 liveuser 18143
		#取得 client 的索引
18144
		$clientIndex=$conf["clientIndex"];
226 liveuser 18145
 
66 liveuser 18146
		#取得 all clients 的資訊
18147
		$allConn=&$conf["allConn"];
226 liveuser 18148
 
66 liveuser 18149
		#hex2bin
18150
		#函式說明:
18151
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
18152
		#回傳結果:
226 liveuser 18153
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 18154
		#$result["function"],當前執行的函數名稱.
18155
		#$result["content"],加密後的結果.
18156
		#$result["error"],錯誤訊息陣列.
18157
		#$result["argu"],使用的參數.
18158
		#必填參數:
18159
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
18160
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
18161
		#$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".
18162
		$conf["authenticate::enCodeStr"]["enCodeType"]="hex2bin";
18163
		#可省略參數:
18164
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
18165
		#$conf["sha1Raw"]="false";
18166
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
18167
		#$conf["p_hash"]="";
18168
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
18169
		#$conf["keyForAes256"]="";
18170
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
18171
		#$conf["aes256Encode"]="";
18172
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
18173
		#$conf["qbpwcfDecode"]="false";
18174
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
18175
		#$conf["gpgDecrypt"]="false";
18176
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
18177
		#$conf["gpgId"]="";
18178
		#參考資料:
18179
		#sha1=>http://php.net/manual/en/function.sha1.php
18180
		#md5=>http://php.net/manual/en/function.md5.php
18181
		#password_hash=>http://php.net/manual/en/function.password-hash.php
18182
		#password_verify=>http://php.net/manual/en/function.password-verify.php
18183
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
18184
		#備註:
18185
		#無.
18186
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
18187
		unset($conf["authenticate::enCodeStr"]);
18188
 
18189
		#如果執行失敗
18190
		if($enCodeStr["status"]==="false"){
18191
 
18192
			#設置執行異常
18193
			$result["status"]="false";
18194
 
18195
			#設置執行錯誤
18196
			$result["error"]=$enCodeStr;
18197
 
18198
			#回傳結果
18199
			return $result;
18200
 
18201
			}#if end
18202
 
18203
		#取得hex2bin後的字串
18204
		$receivedData=$enCodeStr["content"];
226 liveuser 18205
 
66 liveuser 18206
		#gpg decrypt
18207
		#函式說明:
18208
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
18209
		#回傳結果:
226 liveuser 18210
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 18211
		#$result["function"],當前執行的函數名稱.
18212
		#$result["content"],加密後的結果.
18213
		#$result["error"],錯誤訊息陣列.
18214
		#$result["argu"],使用的參數.
18215
		#必填參數:
18216
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
18217
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
18218
		#$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".
18219
		$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
18220
		#可省略參數:
18221
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
18222
		#$conf["sha1Raw"]="false";
18223
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
18224
		#$conf["p_hash"]="";
18225
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
18226
		#$conf["keyForAes256"]="";
18227
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
18228
		#$conf["aes256Encode"]="";
18229
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
18230
		#$conf["qbpwcfDecode"]="false";
18231
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
18232
		$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
18233
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
18234
		$conf["authenticate::enCodeStr"]["gpgId"]=$conf["gpgId"];
18235
		#參考資料:
18236
		#sha1=>http://php.net/manual/en/function.sha1.php
18237
		#md5=>http://php.net/manual/en/function.md5.php
18238
		#password_hash=>http://php.net/manual/en/function.password-hash.php
18239
		#password_verify=>http://php.net/manual/en/function.password-verify.php
18240
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
18241
		#備註:
18242
		#無.
18243
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
18244
		unset($conf["authenticate::enCodeStr"]);
18245
 
18246
		#如果執行失敗
18247
		if($enCodeStr["status"]==="false"){
18248
 
18249
			#設置執行異常
18250
			$result["status"]="false";
18251
 
18252
			#設置執行錯誤
18253
			$result["error"]=$enCodeStr;
18254
 
18255
			#回傳結果
18256
			return $result;
18257
 
18258
			}#if end
18259
 
18260
		#取得解密後的字串
18261
		$receivedData=$enCodeStr["content"];
226 liveuser 18262
 
66 liveuser 18263
		#json_decode
18264
		$receivedData=json_decode($receivedData);
226 liveuser 18265
 
66 liveuser 18266
		#如果收到的是 id?
18267
		if($receivedData==="id?"){
226 liveuser 18268
 
66 liveuser 18269
			#如果尚未認證
18270
			if($connections[$conIndex]["auth"]==="false"){
226 liveuser 18271
 
66 liveuser 18272
				#設置要回傳的訊息
18273
				$talkback="permission denied";
226 liveuser 18274
 
66 liveuser 18275
				}#if end
226 liveuser 18276
 
66 liveuser 18277
			else{
226 liveuser 18278
 
66 liveuser 18279
				#設置要回傳的訊息
18280
				$talkback=$connections[$conIndex]["id"];
226 liveuser 18281
 
66 liveuser 18282
				}#else end
18283
 
18284
			#debug
18285
			#var_dump(__LINE__,$talkback);
18286
 
18287
			#json encode 要回傳的訊息
18288
			$talkback=json_encode($talkback);
226 liveuser 18289
 
66 liveuser 18290
			#debug
18291
			#var_dump(__LINE__,$talkback);
226 liveuser 18292
 
66 liveuser 18293
			#如果是 ws 模式
18294
			if($conf["wsMode"]==="true"){
226 liveuser 18295
 
66 liveuser 18296
				#如果已經 handshake 過
18297
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18298
 
18299
					#如果要 unmask
66 liveuser 18300
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18301
 
66 liveuser 18302
						#函式說明:
226 liveuser 18303
						#加密 handshake 後要傳送的訊息
66 liveuser 18304
						#回傳結果:
18305
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18306
						#$result["error"],執行不正常結束的錯訊息陣列.
18307
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18308
						#$result["argu"],陣列,使用的參數.
18309
						#必填參數:
18310
						#$conf["text"],字串,要加密的訊息.
226 liveuser 18311
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18312
						#可省略參數:
18313
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18314
						#$conf["payloadIsBin"]="false";
18315
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18316
						#$conf["ping"]="false";
18317
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18318
						#$conf["pong"]="false";
18319
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18320
						#$conf["frames"]=array();
18321
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18322
						#$conf["mask"]="false";
18323
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18324
						#$conf["debug"]="false";
18325
						#參考資料:
18326
						#無.
18327
						#備註:
18328
						#目前$conf["text"]長度超過125會出錯.
18329
						$talkback=webSock::encode($conf["webSock::encode"]);
18330
						unset($conf["webSock::encode"]);
226 liveuser 18331
 
66 liveuser 18332
						#如果執行失敗
18333
						if($talkback["status"]==="false"){
226 liveuser 18334
 
66 liveuser 18335
							#印出結果
18336
							var_dump($talkback);
226 liveuser 18337
 
66 liveuser 18338
							#結束執行
18339
							exit;
226 liveuser 18340
 
66 liveuser 18341
							}#if end
226 liveuser 18342
 
66 liveuser 18343
						#debug
18344
						#var_dump(__LINE__,$talkback);
226 liveuser 18345
 
66 liveuser 18346
						}#if end
226 liveuser 18347
 
66 liveuser 18348
					}#if end
226 liveuser 18349
 
66 liveuser 18350
				}#if end
226 liveuser 18351
 
66 liveuser 18352
			#反之不為 web socket 訊息
18353
			else{
226 liveuser 18354
 
66 liveuser 18355
				#儲存成只有一個訊息
18356
				$talkback["content"][]=$talkback;
226 liveuser 18357
 
66 liveuser 18358
				}#else
226 liveuser 18359
 
66 liveuser 18360
			#針對每個訊息的分段
18361
			foreach($talkback["content"] as $msg){
226 liveuser 18362
 
66 liveuser 18363
				#debug
18364
				var_dump(__LINE__,$msg);
226 liveuser 18365
 
66 liveuser 18366
				#回傳訊息
18367
				$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 18368
 
66 liveuser 18369
				#debug
18370
				var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 18371
 
66 liveuser 18372
				}#foreach end
226 liveuser 18373
 
66 liveuser 18374
			#設置執行正常
18375
			$result["status"]="true";
226 liveuser 18376
 
66 liveuser 18377
			#回傳結果
18378
			return $result;
226 liveuser 18379
 
66 liveuser 18380
			}#if end
226 liveuser 18381
 
66 liveuser 18382
		#反之如果收到的是 "quit"
18383
		else if($receivedData==="quit"){
226 liveuser 18384
 
66 liveuser 18385
			#設置要回傳的訊息
18386
			$talkback="結束與 server 的連線";
226 liveuser 18387
 
66 liveuser 18388
			#json encode 要回傳的訊息
18389
			$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 18390
 
66 liveuser 18391
			#如果是 ws 模式
18392
			if($conf["wsMode"]==="true"){
226 liveuser 18393
 
66 liveuser 18394
				#如果已經 handshake 過
18395
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18396
 
18397
					#如果要 unmask
66 liveuser 18398
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18399
 
66 liveuser 18400
						#函式說明:
226 liveuser 18401
						#加密 handshake 後要傳送的訊息
66 liveuser 18402
						#回傳結果:
18403
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18404
						#$result["error"],執行不正常結束的錯訊息陣列.
18405
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18406
						#$result["argu"],陣列,使用的參數.
18407
						#必填參數:
18408
						#$conf["text"],字串,要加密的訊息.
226 liveuser 18409
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18410
						#可省略參數:
18411
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18412
						#$conf["payloadIsBin"]="false";
18413
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18414
						#$conf["ping"]="false";
18415
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18416
						#$conf["pong"]="false";
18417
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18418
						#$conf["frames"]=array();
18419
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18420
						#$conf["mask"]="false";
18421
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18422
						#$conf["debug"]="false";
18423
						#參考資料:
18424
						#無.
18425
						#備註:
18426
						#目前$conf["text"]長度超過125會出錯.
18427
						$talkback=webSock::encode($conf["webSock::encode"]);
18428
						unset($conf["webSock::encode"]);
226 liveuser 18429
 
66 liveuser 18430
						#如果執行失敗
18431
						if($talkback["status"]==="false"){
226 liveuser 18432
 
66 liveuser 18433
							#印出結果
18434
							var_dump($talkback);
226 liveuser 18435
 
66 liveuser 18436
							#結束執行
18437
							exit;
226 liveuser 18438
 
66 liveuser 18439
							}#if end
226 liveuser 18440
 
66 liveuser 18441
						#debug
18442
						#var_dump(__LINE__,$talkback);
226 liveuser 18443
 
66 liveuser 18444
						}#if end
226 liveuser 18445
 
66 liveuser 18446
					}#if end
226 liveuser 18447
 
66 liveuser 18448
				}#if end
226 liveuser 18449
 
66 liveuser 18450
			#反之不為 web socket 訊息
18451
			else{
226 liveuser 18452
 
66 liveuser 18453
				#儲存成只有一個訊息
18454
				$talkback["content"][]=$talkback;
226 liveuser 18455
 
66 liveuser 18456
				}#else
226 liveuser 18457
 
66 liveuser 18458
			#針對每個訊息的分段
18459
			foreach($talkback["content"] as $msg){
226 liveuser 18460
 
66 liveuser 18461
				#回傳訊息
18462
				$socket_write=socket_write($con["connect"], $msg, strlen($msg));
226 liveuser 18463
 
66 liveuser 18464
				#debug
18465
				#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 18466
 
66 liveuser 18467
				}#foreach end
226 liveuser 18468
 
18469
			#關閉被 client 的連線
66 liveuser 18470
			socket_close($con["connect"]);
226 liveuser 18471
 
66 liveuser 18472
			#清理連線的陣列
18473
			unset($connections[$conIndex]);
226 liveuser 18474
 
66 liveuser 18475
			#設置執行正常
18476
			$result["status"]="true";
226 liveuser 18477
 
66 liveuser 18478
			#回傳結果
18479
			return $result;
226 liveuser 18480
 
66 liveuser 18481
			}#if end
226 liveuser 18482
 
66 liveuser 18483
		#反之是如果收到的是 ids?
18484
		else if($receivedData === 'ids?'){
226 liveuser 18485
 
66 liveuser 18486
			#如果尚未認證
18487
			if($connections[$conIndex]["auth"]==="false"){
226 liveuser 18488
 
66 liveuser 18489
				#設置要回傳的訊息
18490
				$talkback=json_encode("permission denied");
226 liveuser 18491
 
66 liveuser 18492
				}#if end
226 liveuser 18493
 
66 liveuser 18494
			#反之
18495
			else{
226 liveuser 18496
 
66 liveuser 18497
				#設置要回傳的訊息
18498
				$talkback=array();
226 liveuser 18499
 
66 liveuser 18500
				#針對每個連線
18501
				foreach($connections as $conIndex_ids => $con_ids){
18502
 
18503
					#如果不是自己
18504
					if($con_ids["connect"]!==$connections[$conIndex]["connect"]){
226 liveuser 18505
 
66 liveuser 18506
						#記錄其他人的id
18507
						$talkback[]=$con_ids["id"];
226 liveuser 18508
 
66 liveuser 18509
						}#if end
226 liveuser 18510
 
66 liveuser 18511
					}#foreach end
226 liveuser 18512
 
66 liveuser 18513
				#json encode要回傳的id陣列
18514
				$talkback=json_encode($talkback);
226 liveuser 18515
 
66 liveuser 18516
				}#else end
226 liveuser 18517
 
66 liveuser 18518
			#如果是 ws 模式
18519
			if($conf["wsMode"]==="true"){
226 liveuser 18520
 
66 liveuser 18521
				#如果已經 handshake 過
18522
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18523
 
66 liveuser 18524
					#如果要 unmask
18525
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18526
 
66 liveuser 18527
						#函式說明:
226 liveuser 18528
						#加密 handshake 後要傳送的訊息
66 liveuser 18529
						#回傳結果:
18530
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18531
						#$result["error"],執行不正常結束的錯訊息陣列.
18532
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18533
						#$result["argu"],陣列,使用的參數.
18534
						#必填參數:
18535
						#$conf["text"],字串,要加密的訊息.
226 liveuser 18536
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18537
						#可省略參數:
18538
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18539
						#$conf["payloadIsBin"]="false";
18540
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18541
						#$conf["ping"]="false";
18542
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18543
						#$conf["pong"]="false";
18544
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18545
						#$conf["frames"]=array();
18546
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18547
						#$conf["mask"]="false";
18548
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18549
						#$conf["debug"]="false";
18550
						#參考資料:
18551
						#無.
18552
						#備註:
18553
						#目前$conf["text"]長度超過125會出錯.
18554
						$talkback=webSock::encode($conf["webSock::encode"]);
18555
						unset($conf["webSock::encode"]);
226 liveuser 18556
 
66 liveuser 18557
						#如果執行失敗
18558
						if($talkback["status"]==="false"){
226 liveuser 18559
 
66 liveuser 18560
							#印出結果
18561
							var_dump($talkback);
226 liveuser 18562
 
66 liveuser 18563
							#結束執行
18564
							exit;
226 liveuser 18565
 
66 liveuser 18566
							}#if end
226 liveuser 18567
 
66 liveuser 18568
						#debug
18569
						#var_dump(__LINE__,$talkback);
226 liveuser 18570
 
66 liveuser 18571
						}#if end
226 liveuser 18572
 
66 liveuser 18573
					}#if end
226 liveuser 18574
 
66 liveuser 18575
				}#if end
226 liveuser 18576
 
66 liveuser 18577
			#反之不為 web socket 訊息
18578
			else{
226 liveuser 18579
 
66 liveuser 18580
				#儲存成只有一個訊息
18581
				$talkback["content"][]=$talkback;
226 liveuser 18582
 
66 liveuser 18583
				}#else
226 liveuser 18584
 
66 liveuser 18585
			#針對每個訊息的分段
18586
			foreach($talkback["content"] as $msg){
226 liveuser 18587
 
66 liveuser 18588
				#回傳訊息
18589
				$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 18590
 
66 liveuser 18591
				#debug
18592
				var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 18593
 
66 liveuser 18594
				}#foreach end
226 liveuser 18595
 
66 liveuser 18596
			#設置執行正常
18597
			$result["status"]="true";
226 liveuser 18598
 
66 liveuser 18599
			#回傳結果
18600
			return $result;
226 liveuser 18601
 
66 liveuser 18602
			}#if end
226 liveuser 18603
 
66 liveuser 18604
		#反之如果收到 "talkTo?"
18605
		else if($receivedData==="talkTo?"){
226 liveuser 18606
 
66 liveuser 18607
			#如果尚未認證
18608
			if($connections[$conIndex]["auth"]==="false"){
226 liveuser 18609
 
66 liveuser 18610
				#設置要回傳的訊息
18611
				$talkback=json_encode("permission denied");
226 liveuser 18612
 
66 liveuser 18613
				}#if end
226 liveuser 18614
 
66 liveuser 18615
			#反之
18616
			else{
226 liveuser 18617
 
66 liveuser 18618
				#初始化要講話的id陣列
18619
				$talkback=array();
226 liveuser 18620
 
66 liveuser 18621
				#有幾個要講話的人就執行幾次
18622
				foreach($connections[$conIndex]["talkTo"] as $to){
226 liveuser 18623
 
66 liveuser 18624
					#串街要講話的人
18625
					$talkback[]=$to;
226 liveuser 18626
 
66 liveuser 18627
					}#foreach end
226 liveuser 18628
 
66 liveuser 18629
				#設置要回傳的訊息
18630
				$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 18631
 
66 liveuser 18632
				}#else end
226 liveuser 18633
 
66 liveuser 18634
			#如果是 ws 模式
18635
			if($conf["wsMode"]==="true"){
226 liveuser 18636
 
66 liveuser 18637
				#如果已經 handshake 過
18638
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18639
 
18640
					#如果要 unmask
66 liveuser 18641
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18642
 
66 liveuser 18643
						#函式說明:
226 liveuser 18644
						#加密 handshake 後要傳送的訊息
66 liveuser 18645
						#回傳結果:
18646
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18647
						#$result["error"],執行不正常結束的錯訊息陣列.
18648
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18649
						#$result["argu"],陣列,使用的參數.
18650
						#必填參數:
18651
						#$conf["text"],字串,要加密的訊息.
226 liveuser 18652
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18653
						#可省略參數:
18654
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18655
						#$conf["payloadIsBin"]="false";
18656
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18657
						#$conf["ping"]="false";
18658
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18659
						#$conf["pong"]="false";
18660
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18661
						#$conf["frames"]=array();
18662
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18663
						#$conf["mask"]="false";
18664
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18665
						#$conf["debug"]="false";
18666
						#參考資料:
18667
						#無.
18668
						#備註:
18669
						#目前$conf["text"]長度超過125會出錯.
18670
						$talkback=webSock::encode($conf["webSock::encode"]);
18671
						unset($conf["webSock::encode"]);
226 liveuser 18672
 
66 liveuser 18673
						#如果執行失敗
18674
						if($talkback["status"]==="false"){
226 liveuser 18675
 
66 liveuser 18676
							#印出結果
18677
							var_dump($talkback);
226 liveuser 18678
 
66 liveuser 18679
							#結束執行
18680
							exit;
226 liveuser 18681
 
66 liveuser 18682
							}#if end
226 liveuser 18683
 
66 liveuser 18684
						#debug
18685
						#var_dump(__LINE__,$talkback);
226 liveuser 18686
 
66 liveuser 18687
						}#if end
226 liveuser 18688
 
66 liveuser 18689
					}#if end
226 liveuser 18690
 
66 liveuser 18691
				}#if end
226 liveuser 18692
 
66 liveuser 18693
			#反之不為 web socket 訊息
18694
			else{
226 liveuser 18695
 
66 liveuser 18696
				#儲存成只有一個訊息
18697
				$talkback["content"][]=$talkback;
226 liveuser 18698
 
66 liveuser 18699
				}#else
226 liveuser 18700
 
66 liveuser 18701
			#針對每個訊息的分段
18702
			foreach($talkback["content"] as $msg){
226 liveuser 18703
 
66 liveuser 18704
				#回傳訊息
18705
				$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 18706
 
66 liveuser 18707
				#debug
18708
				#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 18709
 
66 liveuser 18710
				}#foreach end
226 liveuser 18711
 
66 liveuser 18712
			#設置執行正常
18713
			$result["status"]="true";
226 liveuser 18714
 
66 liveuser 18715
			#回傳結果
18716
			return $result;
226 liveuser 18717
 
66 liveuser 18718
			}#if end
226 liveuser 18719
 
66 liveuser 18720
		#如果收到的訊息長度大於 "talkTo:"
18721
		if(strlen($receivedData)>strlen("talkTo:")){
226 liveuser 18722
 
66 liveuser 18723
			#如果收到開頭為 "talkTo:"
18724
			#涵式說明:
18725
			#取得符合特定字首與字尾的字串
18726
			#回傳的結果:
18727
			#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
18728
			#$result["function"],當前執行的函數名稱.
18729
			#$result["error"],錯誤訊息陣列.
18730
			#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
18731
			#$result["returnString"],爲符合字首條件的字串內容。
18732
			#必填參數:
18733
			#$conf["checkString"],字串,要檢查的字串.
18734
			$conf["search::getMeetConditionsString"]["checkString"]=$receivedData;
18735
			#可省略參數:
18736
			#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
18737
			$conf["search::getMeetConditionsString"]["frontWord"]="talkTo:";
18738
			#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
18739
			#$conf["tailWord"]="";
18740
			#參考資料:
18741
			#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
18742
			$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
18743
			unset($conf["search::getMeetConditionsString"]);
226 liveuser 18744
 
66 liveuser 18745
			#如果選找前置字串 "talkTo:" 失敗
18746
			if($getMeetConditionsString["status"]==="false"){
226 liveuser 18747
 
66 liveuser 18748
				#設置執行失敗
18749
				$result["status"]="false";
226 liveuser 18750
 
66 liveuser 18751
				#設置執行錯誤訊息
18752
				$result["error"]=$getMeetConditionsString;
226 liveuser 18753
 
66 liveuser 18754
				#回傳結果
18755
				return $result;
226 liveuser 18756
 
66 liveuser 18757
				}#if end
226 liveuser 18758
 
66 liveuser 18759
			#如果存在 "talkTo:" 前置字串
18760
			if($getMeetConditionsString["founded"]==="true"){
226 liveuser 18761
 
66 liveuser 18762
				#如果尚未認證
18763
				if($connections[$conIndex]["auth"]==="false"){
226 liveuser 18764
 
66 liveuser 18765
					#設置要回傳的訊息
18766
					$talkback=json_encode("permission denied");
226 liveuser 18767
 
66 liveuser 18768
					#如果是 ws 模式
18769
					if($conf["wsMode"]==="true"){
226 liveuser 18770
 
66 liveuser 18771
						#如果已經 handshake 過
18772
						if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18773
 
18774
							#如果要 unmask
66 liveuser 18775
							if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18776
 
66 liveuser 18777
								#函式說明:
226 liveuser 18778
								#加密 handshake 後要傳送的訊息
66 liveuser 18779
								#回傳結果:
18780
								#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18781
								#$result["error"],執行不正常結束的錯訊息陣列.
18782
								#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18783
								#$result["argu"],陣列,使用的參數.
18784
								#必填參數:
18785
								#$conf["text"],字串,要加密的訊息.
226 liveuser 18786
								$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18787
								#可省略參數:
18788
								#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18789
								#$conf["payloadIsBin"]="false";
18790
								#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18791
								#$conf["ping"]="false";
18792
								#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18793
								#$conf["pong"]="false";
18794
								#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18795
								#$conf["frames"]=array();
18796
								#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18797
								#$conf["mask"]="false";
18798
								#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18799
								#$conf["debug"]="false";
18800
								#參考資料:
18801
								#無.
18802
								#備註:
18803
								#目前$conf["text"]長度超過125會出錯.
18804
								$talkback=webSock::encode($conf["webSock::encode"]);
18805
								unset($conf["webSock::encode"]);
226 liveuser 18806
 
66 liveuser 18807
								#如果執行失敗
18808
								if($talkback["status"]==="false"){
226 liveuser 18809
 
66 liveuser 18810
									#印出結果
18811
									var_dump($talkback);
226 liveuser 18812
 
66 liveuser 18813
									#結束執行
18814
									exit;
226 liveuser 18815
 
66 liveuser 18816
									}#if end
226 liveuser 18817
 
66 liveuser 18818
								#debug
18819
								#var_dump(__LINE__,$talkback);
226 liveuser 18820
 
66 liveuser 18821
								}#if end
226 liveuser 18822
 
66 liveuser 18823
							}#if end
226 liveuser 18824
 
66 liveuser 18825
						}#if end
226 liveuser 18826
 
66 liveuser 18827
					#反之不為 web socket 訊息
18828
					else{
226 liveuser 18829
 
66 liveuser 18830
						#儲存成只有一個訊息
18831
						$talkback["content"][]=$talkback;
226 liveuser 18832
 
66 liveuser 18833
						}#else
226 liveuser 18834
 
66 liveuser 18835
					#針對每個訊息的分段
18836
					foreach($talkback["content"] as $msg){
226 liveuser 18837
 
66 liveuser 18838
						#回傳訊息
18839
						$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 18840
 
66 liveuser 18841
						#debug
18842
						#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 18843
 
66 liveuser 18844
						}#foreach end
226 liveuser 18845
 
66 liveuser 18846
					#設置執行正常
18847
					$result["status"]="true";
226 liveuser 18848
 
66 liveuser 18849
					#回傳結果
18850
					return $result;
226 liveuser 18851
 
66 liveuser 18852
					}#if end
226 liveuser 18853
 
66 liveuser 18854
				#用 "talkTo:" 分割收到的訊息
18855
				#涵式說明:
18856
				#將固定格式的字串分開,並回傳分開的結果。
18857
				#回傳結果:
18858
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18859
				#$result["error"],錯誤訊息陣列
18860
				#$result["function"],當前執行的函數名稱.
18861
				#$result["oriStr"],要分割的原始字串內容
18862
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
18863
				#$result["dataCounts"],爲總共分成幾段
18864
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
18865
				#必填的參數:
18866
				$conf["stringProcess::spiltString"]["stringIn"]=$receivedData;#要處理的字串。
18867
				$conf["stringProcess::spiltString"]["spiltSymbol"]="talkTo:";#爲以哪個符號作爲分割
18868
				#可省略參數:
18869
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
18870
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
18871
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
18872
				unset($conf["stringProcess::spiltString"]);
226 liveuser 18873
 
66 liveuser 18874
				#如果分割字串失敗
18875
				if($spiltString["status"]==="false"){
226 liveuser 18876
 
66 liveuser 18877
					#設置執行失敗
18878
					$result["status"]="false";
226 liveuser 18879
 
66 liveuser 18880
					#設置執行錯誤訊息
18881
					$result["error"]=$spiltString;
226 liveuser 18882
 
66 liveuser 18883
					#回傳結果
18884
					return $result;
226 liveuser 18885
 
66 liveuser 18886
					}#if end
226 liveuser 18887
 
66 liveuser 18888
				#如果剛好分割出一筆資料
18889
				if($spiltString["dataCounts"]===1){
226 liveuser 18890
 
66 liveuser 18891
					#取得自己的id
18892
					$myId=$connections[$conIndex]["id"];
226 liveuser 18893
 
66 liveuser 18894
					#取得講話對象的id
18895
					$toId=$spiltString["dataArray"][0];
226 liveuser 18896
 
66 liveuser 18897
					#設置對象不存在的識別
18898
					$targetExist=false;
226 liveuser 18899
 
66 liveuser 18900
					#設置通話對象的key
18901
					$targetKey="";
226 liveuser 18902
 
66 liveuser 18903
					#取得除了自己的id以外的所有連線
18904
					foreach($connections as $index=>$talkInfo){
226 liveuser 18905
 
66 liveuser 18906
						#除了自己的id
18907
						if($talkInfo["id"]!==$myId){
226 liveuser 18908
 
66 liveuser 18909
							#如果存在要對話的對象
18910
							if($talkInfo["id"]===$toId){
226 liveuser 18911
 
66 liveuser 18912
								#設置對象存在的識別
18913
								$targetExist=true;
226 liveuser 18914
 
66 liveuser 18915
								#通話對象的key
18916
								$targetKey=$index;
226 liveuser 18917
 
66 liveuser 18918
								}#if end
226 liveuser 18919
 
66 liveuser 18920
							}#if end
226 liveuser 18921
 
66 liveuser 18922
						}#for each end
18923
 
18924
					#如果通話對象存在
18925
					if($targetExist){
226 liveuser 18926
 
66 liveuser 18927
						#保存自己的通話對象
18928
						$connections[$conIndex]["talkTo"][]=$toId;
226 liveuser 18929
 
66 liveuser 18930
						#設置要給自己看的訊息
18931
						$talkback="您與 ".$toId." 展開對話";
226 liveuser 18932
 
66 liveuser 18933
						#json encode 要給自己看的訊息
18934
						$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 18935
 
66 liveuser 18936
						#如果是 ws 模式
18937
						if($conf["wsMode"]==="true"){
226 liveuser 18938
 
66 liveuser 18939
							#如果已經 handshake 過
18940
							if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 18941
 
18942
								#如果要 unmask
66 liveuser 18943
								if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 18944
 
66 liveuser 18945
									#函式說明:
226 liveuser 18946
									#加密 handshake 後要傳送的訊息
66 liveuser 18947
									#回傳結果:
18948
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
18949
									#$result["error"],執行不正常結束的錯訊息陣列.
18950
									#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
18951
									#$result["argu"],陣列,使用的參數.
18952
									#必填參數:
18953
									#$conf["text"],字串,要加密的訊息.
226 liveuser 18954
									$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 18955
									#可省略參數:
18956
									#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
18957
									#$conf["payloadIsBin"]="false";
18958
									#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
18959
									#$conf["ping"]="false";
18960
									#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
18961
									#$conf["pong"]="false";
18962
									#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
18963
									#$conf["frames"]=array();
18964
									#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
18965
									#$conf["mask"]="false";
18966
									#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
18967
									#$conf["debug"]="false";
18968
									#參考資料:
18969
									#無.
18970
									#備註:
18971
									#目前$conf["text"]長度超過125會出錯.
18972
									$talkback=webSock::encode($conf["webSock::encode"]);
18973
									unset($conf["webSock::encode"]);
226 liveuser 18974
 
66 liveuser 18975
									#如果執行失敗
18976
									if($talkback["status"]==="false"){
226 liveuser 18977
 
66 liveuser 18978
										#印出結果
18979
										var_dump($talkback);
226 liveuser 18980
 
66 liveuser 18981
										#結束執行
18982
										exit;
226 liveuser 18983
 
66 liveuser 18984
										}#if end
226 liveuser 18985
 
66 liveuser 18986
									#debug
18987
									#var_dump(__LINE__,$talkback);
226 liveuser 18988
 
66 liveuser 18989
									}#if end
226 liveuser 18990
 
66 liveuser 18991
								}#if end
226 liveuser 18992
 
66 liveuser 18993
							}#if end
226 liveuser 18994
 
66 liveuser 18995
						#反之不為 web socket 訊息
18996
						else{
226 liveuser 18997
 
66 liveuser 18998
							#儲存成只有一個訊息
18999
							$talkback["content"][]=$talkback;
226 liveuser 19000
 
66 liveuser 19001
							}#else
226 liveuser 19002
 
66 liveuser 19003
						#針對每個訊息的分段
19004
						foreach($talkback["content"] as $msg){
226 liveuser 19005
 
66 liveuser 19006
							#回傳訊息
19007
							$socket_write=socket_write($connections[$conIndex]["connect"], $msg, strlen($msg));
226 liveuser 19008
 
66 liveuser 19009
							#debug
19010
							#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 19011
 
66 liveuser 19012
							}#foreach end
226 liveuser 19013
 
66 liveuser 19014
						#讓對方可以跟自己對話
19015
						$connections[$targetKey]["talkTo"][]=$myId;
226 liveuser 19016
 
66 liveuser 19017
						#設置要給對方看的訊息
19018
						$talkback=$connections[$conIndex]["id"]." 與您展開對話";
226 liveuser 19019
 
66 liveuser 19020
						#json encode 設置要給對方看的訊息
19021
						$talkback=json_encode($talkback);
226 liveuser 19022
 
66 liveuser 19023
						#如果是 ws 模式
19024
						if($conf["wsMode"]==="true"){
226 liveuser 19025
 
66 liveuser 19026
							#如果已經 handshake 過
19027
							if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 19028
 
19029
								#如果要 unmask
66 liveuser 19030
								if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 19031
 
66 liveuser 19032
									#函式說明:
226 liveuser 19033
									#加密 handshake 後要傳送的訊息
66 liveuser 19034
									#回傳結果:
19035
									#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
19036
									#$result["error"],執行不正常結束的錯訊息陣列.
19037
									#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
19038
									#$result["argu"],陣列,使用的參數.
19039
									#必填參數:
19040
									#$conf["text"],字串,要加密的訊息.
226 liveuser 19041
									$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 19042
									#可省略參數:
19043
									#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
19044
									#$conf["payloadIsBin"]="false";
19045
									#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
19046
									#$conf["ping"]="false";
19047
									#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
19048
									#$conf["pong"]="false";
19049
									#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
19050
									#$conf["frames"]=array();
19051
									#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
19052
									#$conf["mask"]="false";
19053
									#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
19054
									#$conf["debug"]="false";
19055
									#參考資料:
19056
									#無.
19057
									#備註:
19058
									#目前$conf["text"]長度超過125會出錯.
19059
									$talkback=webSock::encode($conf["webSock::encode"]);
19060
									unset($conf["webSock::encode"]);
226 liveuser 19061
 
66 liveuser 19062
									#如果執行失敗
19063
									if($talkback["status"]==="false"){
226 liveuser 19064
 
66 liveuser 19065
										#印出結果
19066
										var_dump($talkback);
226 liveuser 19067
 
66 liveuser 19068
										#結束執行
19069
										exit;
226 liveuser 19070
 
66 liveuser 19071
										}#if end
226 liveuser 19072
 
66 liveuser 19073
									#debug
19074
									#var_dump(__LINE__,$talkback);
226 liveuser 19075
 
66 liveuser 19076
									}#if end
226 liveuser 19077
 
66 liveuser 19078
								}#if end
226 liveuser 19079
 
66 liveuser 19080
							}#if end
226 liveuser 19081
 
66 liveuser 19082
						#反之不為 web socket 訊息
19083
						else{
226 liveuser 19084
 
66 liveuser 19085
							#儲存成只有一個訊息
19086
							$talkback["content"][]=$talkback;
226 liveuser 19087
 
66 liveuser 19088
							}#else
226 liveuser 19089
 
66 liveuser 19090
						#針對每個訊息的分段
19091
						foreach($talkback["content"] as $msg){
226 liveuser 19092
 
66 liveuser 19093
							#給對方看的訊息
19094
							$socket_write=socket_write($connections[$targetKey]["connect"], $msg, strlen($msg));
226 liveuser 19095
 
66 liveuser 19096
							#debug
19097
							#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 19098
 
66 liveuser 19099
							}#foreach end
226 liveuser 19100
 
66 liveuser 19101
						#設置執行正常
19102
						$result["status"]="true";
226 liveuser 19103
 
66 liveuser 19104
						#回傳結果
19105
						return $result;
226 liveuser 19106
 
66 liveuser 19107
						}#if end
226 liveuser 19108
 
66 liveuser 19109
					}#if end
226 liveuser 19110
 
66 liveuser 19111
				}#if end
226 liveuser 19112
 
66 liveuser 19113
			}#if end
226 liveuser 19114
 
66 liveuser 19115
		#不是支援的訊息
19116
		$result["status"]="continue";
226 liveuser 19117
 
66 liveuser 19118
		#回傳結果
19119
		return $result;
226 liveuser 19120
 
66 liveuser 19121
		}#function basic end
226 liveuser 19122
 
66 liveuser 19123
	/*
19124
	#函式說明:
19125
	#提供webSock::nativeSocketTcpIpServer使用系統功能(system).
19126
	#回傳結果:
19127
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
19128
	#$result["error"],執行不正常結束的錯訊息陣列.
19129
	#$result["argu"],陣列,使用的參數.
19130
	#必填參數:
19131
	#$conf["data"],字串,收到的bin2hex編碼後再gpg加密過後的json格式資料,必填的key有"randomStr","username","password".
19132
	$conf["data"]="";
19133
	#$conf["serverSock"],resource,web socket server socket
19134
	$conf["serverSock"]=$resource;
19135
	#$conf["clientSock"],$resource,web socket client socket
19136
	$conf["clientSock"]=$resource;
19137
	#$conf["clientInfo"],陣列,web socket client info.
19138
	$conf["clientInfo"]=array();
19139
	#$conf["clientIndex"],整數.web socket client index.
19140
	$conf["clientIndex"];
19141
	#$conf["allConn"],陣列,all web socket client info.
19142
	$conf["allConn"]=array();
19143
	#可省略參數:
19144
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
19145
	#$conf["wsMode"]="true";
19146
	#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
19147
	#$conf["gpgId"]=gnupgId;
19148
	#參考資料:
19149
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
19150
	#備註:
19151
	#收到用戶的"shutdown"訊息,會重新啟動webSocket server.
19152
	#無.
19153
	*/
19154
	public static function system(&$conf){
226 liveuser 19155
 
66 liveuser 19156
		#初始化要回傳的結果
19157
		$result=array();
19158
 
19159
		#取得當前執行的函數名稱
19160
		$result["function"]=__FUNCTION__;
19161
 
19162
		#涵式說明:
19163
		#判斷當前環境為web還是cmd
19164
		#回傳結果:
19165
		#$result,"web"或"cmd"
19166
		if(csInformation::getEnv()==="web"){
226 liveuser 19167
 
66 liveuser 19168
			#設置執行失敗
19169
			$result["status"]="false";
226 liveuser 19170
 
66 liveuser 19171
			#設置執行錯誤訊息
19172
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 19173
 
66 liveuser 19174
			#回傳結果
19175
			return $result;
226 liveuser 19176
 
66 liveuser 19177
			}#if end
19178
 
19179
		#取得參數
19180
		$result["argu"]=$conf;
19181
 
19182
		#如果 $conf 不為陣列
19183
		if(gettype($conf)!="array"){
226 liveuser 19184
 
66 liveuser 19185
			#設置執行失敗
19186
			$result["status"]="false";
226 liveuser 19187
 
66 liveuser 19188
			#設置執行錯誤訊息
19189
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 19190
 
66 liveuser 19191
			#如果傳入的參數為 null
19192
			if($conf==null){
226 liveuser 19193
 
66 liveuser 19194
				#設置執行錯誤訊息
19195
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 19196
 
66 liveuser 19197
				}#if end
19198
 
19199
			#回傳結果
19200
			return $result;
226 liveuser 19201
 
66 liveuser 19202
			}#if end
226 liveuser 19203
 
66 liveuser 19204
		#檢查參數
19205
		#函式說明:
19206
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
19207
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
19208
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
19209
		#$result["function"],當前執行的函式名稱.
19210
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
19211
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
19212
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
19213
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
19214
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
19215
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
19216
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
19217
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
19218
		#必填寫的參數:
19219
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
19220
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
19221
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
19222
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientInfo","clientIndex","allConn");
19223
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
19224
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","array","string","array");
19225
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
19226
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
19227
		#可以省略的參數:
19228
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
19229
		#$conf["canBeEmptyString"]="false";
19230
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
19231
		#$conf["canNotBeEmpty"]=array();
19232
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
19233
		#$conf["canBeEmpty"]=array();
19234
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
19235
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
19236
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
19237
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode","gpgId");
226 liveuser 19238
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 19239
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
19240
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
19241
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",gnupgId);
19242
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
19243
		#$conf["arrayCountEqualCheck"][]=array();
19244
		#參考資料來源:
19245
		#array_keys=>http://php.net/manual/en/function.array-keys.php
19246
		#建議:
19247
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
19248
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
19249
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 19250
 
66 liveuser 19251
		#如果檢查參數失敗
19252
		if($checkArguments["status"]==="false"){
226 liveuser 19253
 
66 liveuser 19254
			#設置執行失敗
19255
			$result["status"]="false";
226 liveuser 19256
 
66 liveuser 19257
			#設置執行錯誤訊息
19258
			$result["error"]=$checkArguments;
226 liveuser 19259
 
66 liveuser 19260
			#回傳結果
19261
			return $result;
226 liveuser 19262
 
66 liveuser 19263
			}#if end
226 liveuser 19264
 
66 liveuser 19265
		#如果檢查參數不通過
19266
		if($checkArguments["passed"]==="false"){
226 liveuser 19267
 
66 liveuser 19268
			#設置執行失敗
19269
			$result["status"]="false";
226 liveuser 19270
 
66 liveuser 19271
			#設置執行錯誤訊息
19272
			$result["error"]=$checkArguments;
226 liveuser 19273
 
66 liveuser 19274
			#回傳結果
19275
			return $result;
226 liveuser 19276
 
66 liveuser 19277
			}#if end
19278
 
19279
		#取得收到的訊息
19280
		$receivedData=$conf["data"];
226 liveuser 19281
 
66 liveuser 19282
		#取得 server 的 socket
19283
		$serverSocket=$conf["serverSock"];
226 liveuser 19284
 
66 liveuser 19285
		#取得 client 的 socket
19286
		$clientSocket=$conf["clientSock"];
226 liveuser 19287
 
66 liveuser 19288
		#取得 client 的資訊
19289
		$clientInfo=$conf["clientInfo"];
226 liveuser 19290
 
66 liveuser 19291
		#取得 client 的索引
19292
		$clientIndex=$conf["clientIndex"];
226 liveuser 19293
 
66 liveuser 19294
		#取得 all clients 的資訊
19295
		$allConn=&$conf["allConn"];
226 liveuser 19296
 
66 liveuser 19297
		#hex2bin
19298
		#函式說明:
19299
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
19300
		#回傳結果:
226 liveuser 19301
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 19302
		#$result["function"],當前執行的函數名稱.
19303
		#$result["content"],加密後的結果.
19304
		#$result["error"],錯誤訊息陣列.
19305
		#$result["argu"],使用的參數.
19306
		#必填參數:
19307
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
19308
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
19309
		#$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".
19310
		$conf["authenticate::enCodeStr"]["enCodeType"]="hex2bin";
19311
		#可省略參數:
19312
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
19313
		#$conf["sha1Raw"]="false";
19314
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
19315
		#$conf["p_hash"]="";
19316
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
19317
		#$conf["keyForAes256"]="";
19318
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
19319
		#$conf["aes256Encode"]="";
19320
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
19321
		#$conf["qbpwcfDecode"]="false";
19322
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
19323
		#$conf["gpgDecrypt"]="false";
19324
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
19325
		#$conf["gpgId"]="";
19326
		#參考資料:
19327
		#sha1=>http://php.net/manual/en/function.sha1.php
19328
		#md5=>http://php.net/manual/en/function.md5.php
19329
		#password_hash=>http://php.net/manual/en/function.password-hash.php
19330
		#password_verify=>http://php.net/manual/en/function.password-verify.php
19331
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
19332
		#備註:
19333
		#無.
19334
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
19335
		unset($conf["authenticate::enCodeStr"]);
19336
 
19337
		#如果執行失敗
19338
		if($enCodeStr["status"]==="false"){
19339
 
19340
			#設置執行異常
19341
			$result["status"]="false";
19342
 
19343
			#設置執行錯誤
19344
			$result["error"]=$enCodeStr;
19345
 
19346
			#回傳結果
19347
			return $result;
19348
 
19349
			}#if end
19350
 
19351
		#取得hex2bin後的字串
19352
		$receivedData=$enCodeStr["content"];
226 liveuser 19353
 
66 liveuser 19354
		#gpg decrypt
19355
		#函式說明:
19356
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
19357
		#回傳結果:
226 liveuser 19358
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 19359
		#$result["function"],當前執行的函數名稱.
19360
		#$result["content"],加密後的結果.
19361
		#$result["error"],錯誤訊息陣列.
19362
		#$result["argu"],使用的參數.
19363
		#必填參數:
19364
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
19365
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
19366
		#$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".
19367
		$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
19368
		#可省略參數:
19369
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
19370
		#$conf["sha1Raw"]="false";
19371
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
19372
		#$conf["p_hash"]="";
19373
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
19374
		#$conf["keyForAes256"]="";
19375
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
19376
		#$conf["aes256Encode"]="";
19377
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
19378
		#$conf["qbpwcfDecode"]="false";
19379
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
19380
		$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
19381
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
19382
		$conf["authenticate::enCodeStr"]["gpgId"]=$conf["gpgId"];
19383
		#參考資料:
19384
		#sha1=>http://php.net/manual/en/function.sha1.php
19385
		#md5=>http://php.net/manual/en/function.md5.php
19386
		#password_hash=>http://php.net/manual/en/function.password-hash.php
19387
		#password_verify=>http://php.net/manual/en/function.password-verify.php
19388
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
19389
		#備註:
19390
		#無.
19391
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
19392
		unset($conf["authenticate::enCodeStr"]);
19393
 
19394
		#如果執行失敗
19395
		if($enCodeStr["status"]==="false"){
19396
 
19397
			#設置執行異常
19398
			$result["status"]="false";
19399
 
19400
			#設置執行錯誤
19401
			$result["error"]=$enCodeStr;
19402
 
19403
			#回傳結果
19404
			return $result;
19405
 
19406
			}#if end
19407
 
19408
		#取得解密後的字串
19409
		$receivedData=$enCodeStr["content"];
226 liveuser 19410
 
66 liveuser 19411
		#json_decode
19412
		$receivedData=json_decode($receivedData);
226 liveuser 19413
 
66 liveuser 19414
		#如果收到 "shutdown"
19415
		if($receivedData==="shutdown"){
226 liveuser 19416
 
66 liveuser 19417
			#設置要回傳的訊息
19418
			$talkback="Server 即將關閉";
226 liveuser 19419
 
66 liveuser 19420
			#json encode 要回傳的訊息
19421
			$talkback=json_encode($talkback);
226 liveuser 19422
 
66 liveuser 19423
			#如果是 ws 模式
19424
			if($conf["wsMode"]==="true"){
226 liveuser 19425
 
66 liveuser 19426
				#如果已經 handshake 過
19427
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 19428
 
19429
					#如果要 unmask
66 liveuser 19430
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 19431
 
66 liveuser 19432
						#函式說明:
226 liveuser 19433
						#加密 handshake 後要傳送的訊息
66 liveuser 19434
						#回傳結果:
19435
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
19436
						#$result["error"],執行不正常結束的錯訊息陣列.
19437
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
19438
						#$result["argu"],陣列,使用的參數.
19439
						#必填參數:
19440
						#$conf["text"],字串,要加密的訊息.
226 liveuser 19441
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 19442
						#可省略參數:
19443
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
19444
						#$conf["payloadIsBin"]="false";
19445
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
19446
						#$conf["ping"]="false";
19447
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
19448
						#$conf["pong"]="false";
19449
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
19450
						#$conf["frames"]=array();
19451
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
19452
						#$conf["mask"]="false";
19453
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
19454
						#$conf["debug"]="false";
19455
						#參考資料:
19456
						#無.
19457
						#備註:
19458
						#無.
19459
						$talkback=webSock::encode($conf["webSock::encode"]);
19460
						unset($conf["webSock::encode"]);
226 liveuser 19461
 
66 liveuser 19462
						#如果執行失敗
19463
						if($talkback["status"]==="false"){
226 liveuser 19464
 
66 liveuser 19465
							#印出結果
19466
							var_dump($talkback);
226 liveuser 19467
 
66 liveuser 19468
							#結束執行
19469
							exit;
226 liveuser 19470
 
66 liveuser 19471
							}#if end
226 liveuser 19472
 
66 liveuser 19473
						#debug
19474
						#var_dump(__LINE__,$talkback);
226 liveuser 19475
 
66 liveuser 19476
						}#if end
226 liveuser 19477
 
66 liveuser 19478
					}#if end
226 liveuser 19479
 
66 liveuser 19480
				}#if end
226 liveuser 19481
 
66 liveuser 19482
			#反之不為 web socket 訊息
19483
			else{
226 liveuser 19484
 
66 liveuser 19485
				#儲存成只有一個訊息
19486
				$talkback["content"][]=$talkback;
226 liveuser 19487
 
66 liveuser 19488
				}#else
226 liveuser 19489
 
66 liveuser 19490
			#針對每個訊息的分段
19491
			foreach($talkback["content"] as $msg){
226 liveuser 19492
 
66 liveuser 19493
				#回傳訊息
19494
				$socket_write=socket_write($con["connect"], $msg, strlen($msg));
226 liveuser 19495
 
66 liveuser 19496
				#debug
19497
				#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 19498
 
66 liveuser 19499
				}#foreach end
226 liveuser 19500
 
66 liveuser 19501
			#關閉用戶的連線
19502
			socket_close($con["connect"]);
226 liveuser 19503
 
66 liveuser 19504
			}#if end
226 liveuser 19505
 
66 liveuser 19506
		#關閉 server socket
19507
		socket_close($serverSocket);
226 liveuser 19508
 
66 liveuser 19509
		#設置執行正常
19510
		$result["status"]="true";
226 liveuser 19511
 
66 liveuser 19512
		#回傳結果
19513
		return $result;
226 liveuser 19514
 
66 liveuser 19515
		}#function system end
226 liveuser 19516
 
66 liveuser 19517
	/*
19518
	#函式說明:
19519
	#提供webSock::nativeSocketTcpIpServer使用系統功能(system).
19520
	#回傳結果:
19521
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常,"continue"代表不適用.
19522
	#$result["error"],執行不正常結束的錯訊息陣列.
19523
	#$result["argu"],陣列,使用的參數.
19524
	#必填參數:
19525
	#$conf["data"],字串,收到的bin2hex編碼後再gpg加密過後的json格式資料.
19526
	$conf["data"]="";
19527
	#$conf["serverSock"],resource,web socket server socket
19528
	$conf["serverSock"]=$resource;
19529
	#$conf["clientSock"],$resource,web socket client socket
19530
	$conf["clientSock"]=$resource;
19531
	#$conf["clientInfo"],陣列,web socket client info.
19532
	$conf["clientInfo"]=array();
19533
	#$conf["clientIndex"],整數.web socket client index.
19534
	$conf["clientIndex"];
19535
	#$conf["allConn"],陣列,all web socket client info.
19536
	$conf["allConn"]=array();
19537
	#可省略參數:
19538
	#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
19539
	#$conf["wsMode"]="true";
19540
	#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
19541
	#$conf["gpgId"]=gnupgId;
19542
	#參考資料:
19543
	#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
19544
	#備註:
19545
	#收到用戶的"quit"訊息,會結束與用戶的連線.
19546
	*/
19547
	public static function noAuth(&$conf){
226 liveuser 19548
 
66 liveuser 19549
		#初始化要回傳的結果
19550
		$result=array();
19551
 
19552
		#取得當前執行的函數名稱
19553
		$result["function"]=__FUNCTION__;
19554
 
19555
		#涵式說明:
19556
		#判斷當前環境為web還是cmd
19557
		#回傳結果:
19558
		#$result,"web"或"cmd"
19559
		if(csInformation::getEnv()==="web"){
226 liveuser 19560
 
66 liveuser 19561
			#設置執行失敗
19562
			$result["status"]="false";
226 liveuser 19563
 
66 liveuser 19564
			#設置執行錯誤訊息
19565
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 19566
 
66 liveuser 19567
			#回傳結果
19568
			return $result;
226 liveuser 19569
 
66 liveuser 19570
			}#if end
19571
 
19572
		#取得參數
19573
		$result["argu"]=$conf;
19574
 
19575
		#如果 $conf 不為陣列
19576
		if(gettype($conf)!="array"){
226 liveuser 19577
 
66 liveuser 19578
			#設置執行失敗
19579
			$result["status"]="false";
226 liveuser 19580
 
66 liveuser 19581
			#設置執行錯誤訊息
19582
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 19583
 
66 liveuser 19584
			#如果傳入的參數為 null
19585
			if($conf==null){
226 liveuser 19586
 
66 liveuser 19587
				#設置執行錯誤訊息
19588
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 19589
 
66 liveuser 19590
				}#if end
19591
 
19592
			#回傳結果
19593
			return $result;
226 liveuser 19594
 
66 liveuser 19595
			}#if end
226 liveuser 19596
 
66 liveuser 19597
		#檢查參數
19598
		#函式說明:
19599
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
19600
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
19601
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
19602
		#$result["function"],當前執行的函式名稱.
19603
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
19604
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
19605
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
19606
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
19607
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
19608
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
19609
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
19610
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
19611
		#必填寫的參數:
19612
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
19613
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
19614
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
19615
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientInfo","clientIndex","allConn");
19616
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
19617
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","array","string","array");
19618
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
19619
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
19620
		#可以省略的參數:
19621
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
19622
		#$conf["canBeEmptyString"]="false";
19623
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
19624
		#$conf["canNotBeEmpty"]=array();
19625
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
19626
		#$conf["canBeEmpty"]=array();
19627
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
19628
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array("wsMode");
19629
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
19630
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("wsMode","gpgId");
226 liveuser 19631
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 19632
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string");
19633
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
19634
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("true",gnupgId);
19635
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
19636
		#$conf["arrayCountEqualCheck"][]=array();
19637
		#參考資料來源:
19638
		#array_keys=>http://php.net/manual/en/function.array-keys.php
19639
		#建議:
19640
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
19641
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
19642
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 19643
 
66 liveuser 19644
		#如果檢查參數失敗
19645
		if($checkArguments["status"]==="false"){
226 liveuser 19646
 
66 liveuser 19647
			#設置執行失敗
19648
			$result["status"]="false";
226 liveuser 19649
 
66 liveuser 19650
			#設置執行錯誤訊息
19651
			$result["error"]=$checkArguments;
226 liveuser 19652
 
66 liveuser 19653
			#回傳結果
19654
			return $result;
226 liveuser 19655
 
66 liveuser 19656
			}#if end
226 liveuser 19657
 
66 liveuser 19658
		#如果檢查參數不通過
19659
		if($checkArguments["passed"]==="false"){
226 liveuser 19660
 
66 liveuser 19661
			#設置執行失敗
19662
			$result["status"]="false";
226 liveuser 19663
 
66 liveuser 19664
			#設置執行錯誤訊息
19665
			$result["error"]=$checkArguments;
226 liveuser 19666
 
66 liveuser 19667
			#回傳結果
19668
			return $result;
226 liveuser 19669
 
66 liveuser 19670
			}#if end
19671
 
19672
		#取得收到的訊息
19673
		$receivedData=$conf["data"];
226 liveuser 19674
 
66 liveuser 19675
		#取得 server 的 socket
19676
		$serverSocket=$conf["serverSock"];
226 liveuser 19677
 
66 liveuser 19678
		#取得 client 的 socket
19679
		$clientSocket=$conf["clientSock"];
226 liveuser 19680
 
66 liveuser 19681
		#取得 client 的資訊
19682
		$clientInfo=$conf["clientInfo"];
226 liveuser 19683
 
66 liveuser 19684
		#取得 client 的索引
19685
		$clientIndex=$conf["clientIndex"];
226 liveuser 19686
 
66 liveuser 19687
		#取得 all clients 的資訊
19688
		$allConn=&$conf["allConn"];
226 liveuser 19689
 
66 liveuser 19690
		#hex2bin
19691
		#函式說明:
19692
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
19693
		#回傳結果:
226 liveuser 19694
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 19695
		#$result["function"],當前執行的函數名稱.
19696
		#$result["content"],加密後的結果.
19697
		#$result["error"],錯誤訊息陣列.
19698
		#$result["argu"],使用的參數.
19699
		#必填參數:
19700
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
19701
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
19702
		#$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".
19703
		$conf["authenticate::enCodeStr"]["enCodeType"]="hex2bin";
19704
		#可省略參數:
19705
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
19706
		#$conf["sha1Raw"]="false";
19707
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
19708
		#$conf["p_hash"]="";
19709
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
19710
		#$conf["keyForAes256"]="";
19711
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
19712
		#$conf["aes256Encode"]="";
19713
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
19714
		#$conf["qbpwcfDecode"]="false";
19715
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
19716
		#$conf["gpgDecrypt"]="false";
19717
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
19718
		#$conf["gpgId"]="";
19719
		#參考資料:
19720
		#sha1=>http://php.net/manual/en/function.sha1.php
19721
		#md5=>http://php.net/manual/en/function.md5.php
19722
		#password_hash=>http://php.net/manual/en/function.password-hash.php
19723
		#password_verify=>http://php.net/manual/en/function.password-verify.php
19724
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
19725
		#備註:
19726
		#無.
19727
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
19728
		unset($conf["authenticate::enCodeStr"]);
19729
 
19730
		#如果執行失敗
19731
		if($enCodeStr["status"]==="false"){
19732
 
19733
			#設置執行異常
19734
			$result["status"]="false";
19735
 
19736
			#設置執行錯誤
19737
			$result["error"]=$enCodeStr;
19738
 
19739
			#回傳結果
19740
			return $result;
19741
 
19742
			}#if end
19743
 
19744
		#取得hex2bin後的字串
19745
		$receivedData=$enCodeStr["content"];
226 liveuser 19746
 
66 liveuser 19747
		#gpg decrypt
19748
		#函式說明:
19749
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
19750
		#回傳結果:
226 liveuser 19751
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 19752
		#$result["function"],當前執行的函數名稱.
19753
		#$result["content"],加密後的結果.
19754
		#$result["error"],錯誤訊息陣列.
19755
		#$result["argu"],使用的參數.
19756
		#必填參數:
19757
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
19758
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
19759
		#$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".
19760
		$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
19761
		#可省略參數:
19762
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
19763
		#$conf["sha1Raw"]="false";
19764
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
19765
		#$conf["p_hash"]="";
19766
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
19767
		#$conf["keyForAes256"]="";
19768
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
19769
		#$conf["aes256Encode"]="";
19770
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
19771
		#$conf["qbpwcfDecode"]="false";
19772
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
19773
		$conf["authenticate::enCodeStr"]["gpgDecrypt"]="true";
19774
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
19775
		$conf["authenticate::enCodeStr"]["gpgId"]=$conf["gpgId"];
19776
		#參考資料:
19777
		#sha1=>http://php.net/manual/en/function.sha1.php
19778
		#md5=>http://php.net/manual/en/function.md5.php
19779
		#password_hash=>http://php.net/manual/en/function.password-hash.php
19780
		#password_verify=>http://php.net/manual/en/function.password-verify.php
19781
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
19782
		#備註:
19783
		#無.
19784
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
19785
		unset($conf["authenticate::enCodeStr"]);
19786
 
19787
		#如果執行失敗
19788
		if($enCodeStr["status"]==="false"){
19789
 
19790
			#設置執行異常
19791
			$result["status"]="false";
19792
 
19793
			#設置執行錯誤
19794
			$result["error"]=$enCodeStr;
19795
 
19796
			#回傳結果
19797
			return $result;
19798
 
19799
			}#if end
19800
 
19801
		#取得解密後的字串
19802
		$receivedData=$enCodeStr["content"];
226 liveuser 19803
 
66 liveuser 19804
		#json_decode
19805
		$receivedData=json_decode($receivedData);
226 liveuser 19806
 
66 liveuser 19807
		#如果訊息內容為 "quit"
19808
		if($receivedData==="quit"){
226 liveuser 19809
 
66 liveuser 19810
			#設置要回傳的訊息
19811
			$talkback="結束與 server 的連線";
226 liveuser 19812
 
66 liveuser 19813
			#json encode 要回傳的訊息
19814
			$talkback=json_encode($talkback).PHP_EOL;
226 liveuser 19815
 
66 liveuser 19816
			#如果是 ws 模式
19817
			if($conf["wsMode"]==="true"){
226 liveuser 19818
 
66 liveuser 19819
				#如果已經 handshake 過
19820
				if($connections[$conIndex]["handshaked"]==="true"){
226 liveuser 19821
 
19822
					#如果要 unmask
66 liveuser 19823
					if($connections[$conIndex]["unmask"]==="true"){
226 liveuser 19824
 
66 liveuser 19825
						#函式說明:
226 liveuser 19826
						#加密 handshake 後要傳送的訊息
66 liveuser 19827
						#回傳結果:
19828
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
19829
						#$result["error"],執行不正常結束的錯訊息陣列.
19830
						#$result["content"],陣列,加密 handshake 後要傳送給 client 的訊息,若有多個代表要分為多個 Fragmentation 來依序傳送.
19831
						#$result["argu"],陣列,使用的參數.
19832
						#必填參數:
19833
						#$conf["text"],字串,要加密的訊息.
226 liveuser 19834
						$conf["webSock::encode"]["text"]=$talkback;
66 liveuser 19835
						#可省略參數:
19836
						#$conf["payloadIsBin"],字串,"true"定義Payload data是為2元碼;預設為"false"代表為文字.
19837
						#$conf["payloadIsBin"]="false";
19838
						#$conf["ping"],字串,"true"代表為ping訊息;反之為"false",預設為"false".
19839
						#$conf["ping"]="false";
19840
						#$conf["pong"],字串,"true"代表為pong訊息;反之為"false",預設為"false".
19841
						#$conf["pong"]="false";
19842
						#$conf["frames"],陣列,目前既有的訊息frame,預設為空陣列,代表沒有.
19843
						#$conf["frames"]=array();
19844
						#$conf["mask"],字串,代表是否要將內容進行mask,預設為"false",代表不要,適用於server to client;反之為"true"代表要,適用於client to server.
19845
						#$conf["mask"]="false";
19846
						#$conf["debug"],字串,"true"代表要show debug訊息;反之為預設"false".
19847
						#$conf["debug"]="false";
19848
						#參考資料:
19849
						#無.
19850
						#備註:
19851
						#目前$conf["text"]長度超過125會出錯.
19852
						$talkback=webSock::encode($conf["webSock::encode"]);
19853
						unset($conf["webSock::encode"]);
226 liveuser 19854
 
66 liveuser 19855
						#如果執行失敗
19856
						if($talkback["status"]==="false"){
226 liveuser 19857
 
66 liveuser 19858
							#印出結果
19859
							var_dump($talkback);
226 liveuser 19860
 
66 liveuser 19861
							#結束執行
19862
							exit;
226 liveuser 19863
 
66 liveuser 19864
							}#if end
226 liveuser 19865
 
66 liveuser 19866
						#debug
19867
						#var_dump(__LINE__,$talkback);
226 liveuser 19868
 
66 liveuser 19869
						}#if end
226 liveuser 19870
 
66 liveuser 19871
					}#if end
226 liveuser 19872
 
66 liveuser 19873
				}#if end
226 liveuser 19874
 
66 liveuser 19875
			#反之不為 web socket 訊息
19876
			else{
226 liveuser 19877
 
66 liveuser 19878
				#儲存成只有一個訊息
19879
				$talkback["content"][]=$talkback;
226 liveuser 19880
 
66 liveuser 19881
				}#else
226 liveuser 19882
 
66 liveuser 19883
			#針對每個訊息的分段
19884
			foreach($talkback["content"] as $msg){
226 liveuser 19885
 
66 liveuser 19886
				#回傳訊息
19887
				$socket_write=socket_write($con["connect"], $msg, strlen($msg));
226 liveuser 19888
 
66 liveuser 19889
				#debug
19890
				#var_dump(__LINE__,$socket_write,socket_strerror(socket_last_error($con["connect"])));
226 liveuser 19891
 
66 liveuser 19892
				}#foreach end
226 liveuser 19893
 
66 liveuser 19894
			#關閉被 client 的連線
19895
			socket_close($con["connect"]);
226 liveuser 19896
 
66 liveuser 19897
			#清理連線的陣列
19898
			unset($connections[$conIndex]);
226 liveuser 19899
 
66 liveuser 19900
			#設置執行正常
19901
			$result["status"]="true";
226 liveuser 19902
 
66 liveuser 19903
			#回傳結果
19904
			return $result;
226 liveuser 19905
 
66 liveuser 19906
			}#if end
226 liveuser 19907
 
66 liveuser 19908
		}#function noAuth end
226 liveuser 19909
 
66 liveuser 19910
	/*
19911
	#函式說明:
19912
	#依照參數來執行對應的函式.
19913
	#回傳結果:
226 liveuser 19914
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 19915
	#$result["function"],當前執行的函數名稱.
19916
	#$result["content"],加密後的結果.
19917
	#$result["error"],錯誤訊息陣列.
19918
	#$result["argu"],使用的參數.
19919
	#必填參數:
19920
	#$conf["data"],字串,收到bin2hex編碼後再gpg加密後的資料.
19921
	$conf["data"]="";
19922
	#$conf["serverSock"],socket,代表web socket server的socket.
19923
	$conf["serverSock"]=;
19924
	#$conf["clientSock"],socket,代表web socket client的socket.
19925
	#$conf["clientInfo"],陣列,用戶端的資訊.
19926
	$conf["clientInfo"]=array();
19927
	#$conf["clientIndex"],字串,代表client於allConn中的索引.
19928
	$conf["clientIndex"]="";
19929
	#$conf["allConn"],陣列,所有連線的用戶端的連線資訊.
19930
	$conf["allConn"]=array();
19931
	#可省略參數:
19932
	#無.
19933
	#參考資料:
19934
	#無.
19935
	#備註:
19936
	#無.
19937
	*/
19938
	public static function callFunc(&$conf){
19939
 
19940
		#初始化要回傳的結果
19941
		$result=array();
19942
 
19943
		#取得當前執行的函數名稱
19944
		$result["function"]=__FUNCTION__;
19945
 
19946
		#涵式說明:
19947
		#判斷當前環境為web還是cmd
19948
		#回傳結果:
19949
		#$result,"web"或"cmd"
19950
		if(csInformation::getEnv()==="web"){
226 liveuser 19951
 
66 liveuser 19952
			#設置執行失敗
19953
			$result["status"]="false";
226 liveuser 19954
 
66 liveuser 19955
			#設置執行錯誤訊息
19956
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
226 liveuser 19957
 
66 liveuser 19958
			#回傳結果
19959
			return $result;
226 liveuser 19960
 
66 liveuser 19961
			}#if end
19962
 
19963
		#取得參數
19964
		$result["argu"]=$conf;
19965
 
19966
		#如果 $conf 不為陣列
19967
		if(gettype($conf)!="array"){
226 liveuser 19968
 
66 liveuser 19969
			#設置執行失敗
19970
			$result["status"]="false";
226 liveuser 19971
 
66 liveuser 19972
			#設置執行錯誤訊息
19973
			$result["error"][]="\$conf變數須為陣列形態";
226 liveuser 19974
 
66 liveuser 19975
			#如果傳入的參數為 null
19976
			if($conf==null){
226 liveuser 19977
 
66 liveuser 19978
				#設置執行錯誤訊息
19979
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
226 liveuser 19980
 
66 liveuser 19981
				}#if end
19982
 
19983
			#回傳結果
19984
			return $result;
226 liveuser 19985
 
66 liveuser 19986
			}#if end
226 liveuser 19987
 
66 liveuser 19988
		#檢查參數
19989
		#函式說明:
19990
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
19991
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
19992
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
19993
		#$result["function"],當前執行的函式名稱.
19994
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
19995
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
19996
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
19997
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
19998
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
19999
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
20000
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
20001
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
20002
		#必填寫的參數:
20003
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
20004
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
20005
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
20006
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("data","serverSock","clientInfo","clientIndex","allConn");
20007
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
20008
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","resource","array","string","array");
20009
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
20010
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
20011
		#可以省略的參數:
20012
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
20013
		#$conf["canBeEmptyString"]="false";
20014
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
20015
		#$conf["canNotBeEmpty"]=array();
20016
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
20017
		#$conf["canBeEmpty"]=array();
20018
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
20019
		#$conf["variableCheck::checkArguments"]["skipableVariableCanNotBeEmpty"]=array();
20020
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
20021
		#$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("listenIp","listenPort","wsMode","processFuncs");
226 liveuser 20022
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
66 liveuser 20023
		#$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","array");
20024
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
20025
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("127.0.0.1",null,"false",null);
20026
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
20027
		#$conf["arrayCountEqualCheck"][]=array();
20028
		#參考資料來源:
20029
		#array_keys=>http://php.net/manual/en/function.array-keys.php
20030
		#建議:
20031
		#增加可省略參數全部不能為空字串或空陣列的參數功能.
20032
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
20033
		unset($conf["variableCheck::checkArguments"]);
226 liveuser 20034
 
66 liveuser 20035
		#如果檢查參數失敗
20036
		if($checkArguments["status"]==="false"){
226 liveuser 20037
 
66 liveuser 20038
			#設置執行失敗
20039
			$result["status"]="false";
226 liveuser 20040
 
66 liveuser 20041
			#設置執行錯誤訊息
20042
			$result["error"]=$checkArguments;
226 liveuser 20043
 
66 liveuser 20044
			#回傳結果
20045
			return $result;
226 liveuser 20046
 
66 liveuser 20047
			}#if end
226 liveuser 20048
 
66 liveuser 20049
		#如果檢查參數不通過
20050
		if($checkArguments["passed"]==="false"){
226 liveuser 20051
 
66 liveuser 20052
			#設置執行失敗
20053
			$result["status"]="false";
226 liveuser 20054
 
66 liveuser 20055
			#設置執行錯誤訊息
20056
			$result["error"]=$checkArguments;
226 liveuser 20057
 
66 liveuser 20058
			#回傳結果
20059
			return $result;
226 liveuser 20060
 
66 liveuser 20061
			}#if end
20062
 
20063
		#取得收到的訊息
20064
		$receivedData=$conf["data"];
226 liveuser 20065
 
66 liveuser 20066
		#取得 server 的 socket
20067
		$serverSocket=$conf["serverSock"];
226 liveuser 20068
 
66 liveuser 20069
		#取得 client 的 socket
20070
		$clientSocket=$conf["clientSock"];
226 liveuser 20071
 
66 liveuser 20072
		#取得 client 的資訊
20073
		$clientInfo=$conf["clientInfo"];
226 liveuser 20074
 
66 liveuser 20075
		#取得 client 的索引
20076
		$clientIndex=$conf["clientIndex"];
226 liveuser 20077
 
66 liveuser 20078
		#取得 all clients 的資訊
20079
		$allConn=$conf["allConn"];
226 liveuser 20080
 
66 liveuser 20081
		#hex2bin
20082
		#函式說明:
20083
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,gpg,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
20084
		#回傳結果:
226 liveuser 20085
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 20086
		#$result["function"],當前執行的函數名稱.
20087
		#$result["content"],加密後的結果.
20088
		#$result["error"],錯誤訊息陣列.
20089
		#$result["argu"],使用的參數.
20090
		#必填參數:
20091
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
20092
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$receivedData;
20093
		#$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加解密.
20094
		$conf["authenticate::enCodeStr"]["enCodeType"]="hex2bin";
20095
		#可省略參數:
20096
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
20097
		#$conf["sha1Raw"]="false";
20098
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
20099
		#$conf["p_hash"]="";
20100
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
20101
		#$conf["keyForAes256"]="";
20102
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
20103
		#$conf["aes256Encode"]="";
20104
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
20105
		#$conf["qbpwcfDecode"]="false";
20106
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
20107
		#$conf["gpgDecrypt"]="false";
20108
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
20109
		$conf["authenticate::enCodeStr"]["gpgId"]=gnupgId;
20110
		#參考資料:
20111
		#sha1=>http://php.net/manual/en/function.sha1.php
20112
		#md5=>http://php.net/manual/en/function.md5.php
20113
		#password_hash=>http://php.net/manual/en/function.password-hash.php
20114
		#password_verify=>http://php.net/manual/en/function.password-verify.php
20115
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
20116
		#備註:
20117
		#無.
20118
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
20119
		unset($conf["authenticate::enCodeStr"]);
226 liveuser 20120
 
66 liveuser 20121
		#如果執行失敗
20122
		if($enCodeStr["status"]==="false"){
226 liveuser 20123
 
66 liveuser 20124
			#印出結果
20125
			return $enCodeStr;
226 liveuser 20126
 
66 liveuser 20127
			}#if end
226 liveuser 20128
 
66 liveuser 20129
		#用GnuPG解密
20130
		#函式說明:
20131
		#加密或編碼字串,可以用的方法有sha1,md5,password_sha,qbpwcf,bin2hex,hex2bin,gpg,sha1可以回傳20或40的數值字串,md5可以回傳32個數值字串,password_hash可以回傳60~255個字元.
20132
		#回傳結果:
226 liveuser 20133
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
66 liveuser 20134
		#$result["function"],當前執行的函數名稱.
20135
		#$result["content"],加密後的結果.
20136
		#$result["error"],錯誤訊息陣列.
20137
		#$result["argu"],使用的參數.
20138
		#必填參數:
20139
		#$conf["enCodeStr"],any,要加密的字串,陣列,物件.
20140
		$conf["authenticate::enCodeStr"]["enCodeStr"]=$$enCodeStr["content"];
20141
		#$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加解密.
20142
		$conf["authenticate::enCodeStr"]["enCodeType"]="gpg";
20143
		#可省略參數:
20144
		#$conf["sha1Raw"],字串,sha1加密的結果要用20個0與1組合還是要用40位數的16進位數值,"true"代表前者,"false"代表後者,預設為"false".
20145
		#$conf["sha1Raw"]="false";
20146
		#$conf["p_hash"],字串,p_hash加密過後的字串,該參數若存在且$conf["enCodeType"]為"p_hash",則代表是要檢查$conf["enCodeStr"]是否為符合$conf["p_hash"]的密碼.
20147
		#$conf["p_hash"]="";
20148
		#$conf["keyForAes256"],字串,用來 AES256 加解密的金鑰.
20149
		#$conf["keyForAes256"]="";
20150
		#$conf["aes256Encode"],字串,"true"代表是要加密,"false"代表是要解密.
20151
		#$conf["aes256Encode"]="";
20152
		#$conf["qbpwcfDecode"],字串,若"enCodeType"為"qbpwcf",則預設為"false",代表加密;反之為"true",代表解密.
20153
		#$conf["qbpwcfDecode"]="false";
20154
		#$conf["gpgDecrypt"],字串,若"enCodeType"為"gpg",則預設為"false",代表加密;反之為"true",代表解密.
20155
		#$conf["gpgDecrypt"]="false";
20156
		#$conf["gpgId"],字串,若"enCodeType"為"gpg"時,該參數必填.
20157
		$conf["authenticate::enCodeStr"]["gpgId"]=gnupgId;
20158
		#參考資料:
20159
		#sha1=>http://php.net/manual/en/function.sha1.php
20160
		#md5=>http://php.net/manual/en/function.md5.php
20161
		#password_hash=>http://php.net/manual/en/function.password-hash.php
20162
		#password_verify=>http://php.net/manual/en/function.password-verify.php
20163
		#json_decode=>https://www.php.net/manual/en/function.json-decode.php
20164
		#備註:
20165
		#無.
20166
		$enCodeStr=authenticate::enCodeStr($conf["authenticate::enCodeStr"]);
20167
		unset($conf["authenticate::enCodeStr"]);
226 liveuser 20168
 
66 liveuser 20169
		#如果執行失敗
20170
		if($enCodeStr["status"]==="false"){
226 liveuser 20171
 
66 liveuser 20172
			#印出結果
20173
			return $enCodeStr;
226 liveuser 20174
 
66 liveuser 20175
			}#if end
226 liveuser 20176
 
66 liveuser 20177
		#解碼取得的內容
20178
		$receivedData=json_decode($enCodeStr["content"]);
226 liveuser 20179
 
66 liveuser 20180
		#如果有設置 callFunc
20181
		if(isset($receivedData->callFunc)){
226 liveuser 20182
 
66 liveuser 20183
			#取得要呼叫的函式
20184
			$func=$receivedData->callFunc;
226 liveuser 20185
 
66 liveuser 20186
			#檢查是否有權限執行該函式
20187
			#函式說明:
20188
			#提供webSock::nativeSocketTcpIpServer用於接受檢查權限的功能.
20189
			#回傳結果:
20190
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
20191
			#$result["error"],執行不正常結束的錯訊息陣列.
20192
			#$result["argu"],陣列,使用的參數.
20193
			#必填參數:
20194
			#$conf["data"],字串,收到的bin2hex編碼後果gpg加密過後的json格式資料,必填的key有"randomStr","username","password".
20195
			$conf["self::checkAuth"]["data"]=$conf["data"];
20196
			#$conf["serverSock"],resource,web socket server socket
20197
			$conf["self::checkAuth"]["serverSock"]=$conf["serverSock"];
20198
			#$conf["clientSock"],$resource,web socket client socket
20199
			$conf["self::checkAuth"]["clientSock"]=$conf["clientSock"];
20200
			#$conf["clientInfo"],陣列,web socket client info.
20201
			$conf["self::checkAuth"]["clientInfo"]=$conf["clientInfo"];
20202
			#$conf["clientIndex"],整數.web socket client index.
20203
			$conf["self::checkAuth"]["clientIndex"]=$conf["clientIndex"];
20204
			#$conf["allConn"],陣列,all web socket client info.
20205
			$conf["self::checkAuth"]["allConn"]=$conf["allConn"];
20206
			#$conf["func"],字串,要檢查的是否具備權限的函式.
20207
			$conf["self::checkAuth"]["func"]=$func;
20208
			#可省略參數:
20209
			#$conf["wsMode"],字串,是否要按照rfc6555,預設為"true"為是;"false"為否.
20210
			#$conf["wsMode"]="true";
20211
			#$conf["gpgId"],字串,用於加解密的gpg id,預設為gnupgId.
20212
			#$conf["gpgId"]=gnupgId;
20213
			#$conf["falseAllowFuncPlus"],陣列,額外的未認證時可以執行的函式清單.
20214
			#$conf["falseAllowFuncPlus"]=array();
20215
			#$conf["publicAllowFuncPlus"],陣列,額外的認證為public時可以執行的函式清單.
20216
			#$conf["publicAllowFuncPlus"]=array();
20217
			#參考資料:
20218
			#https://www.rfc-editor.org/rfc/rfc6455#page-28, Web Socket Base Framing Protocol.
20219
			#備註:
20220
			#無.
20221
			$checkAuth=self::checkAuth($conf["self::checkAuth"]);
20222
			unset($conf["self::checkAuth"]);
226 liveuser 20223
 
66 liveuser 20224
			#如果異常
20225
			if($checkAuth["status"]==="false"){
226 liveuser 20226
 
66 liveuser 20227
				#回傳結果
20228
				return $checkAuth;
226 liveuser 20229
 
66 liveuser 20230
				}#if end
226 liveuser 20231
 
66 liveuser 20232
			#移除使用好的元素
20233
			unset($receivedData["callFunc"]);
226 liveuser 20234
 
66 liveuser 20235
			#置換data為未加密的內容
20236
			$conf["data"]=json_encode($receivedData);
226 liveuser 20237
 
66 liveuser 20238
			#呼叫對應的函式
20239
			return eval($func."(&\$conf);");
226 liveuser 20240
 
66 liveuser 20241
			}#if end
226 liveuser 20242
 
66 liveuser 20243
		#設置執行失敗
20244
		$result["ststus"]="false";
226 liveuser 20245
 
66 liveuser 20246
		#回傳結果
20247
		return $result;
20248
 
20249
		}#function callFunc end
226 liveuser 20250
 
3 liveuser 20251
	}#class webSock end
20252
 
226 liveuser 20253
?>