Subversion Repositories php-qbpwcf

Rev

Blame | Last modification | View Log | RSS feed

#!/usr/bin/php
<?php

#使用命名空間qbpwcf
namespace qbpwcf;

#匯入外部套件
include("/usr/lib/qbpwcf/allInOne.php");

#函式說明:
#建立php原生的socket tcp/ip server,進而實作webSocket
#回傳結果:
#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
#$result["error"],錯誤訊息陣列.
#$resutl["function"],當前執行的涵式名稱.
#$result["argu"],所使用的參數.
#必填參數:
#$conf["fileArgu"],字串,變數__FILE__的內容.
$conf["fileArgu"]=__FILE__;
#可省略參數:
#$conf["listenIp"],字串,要接聽的主機ip,預設為本機的ip.
#$conf["listenIp"]="169.254.1.1";
#$conf["listenPort"],字串,要接聽的port,預設為已使用port+1.
$conf["listenPort"]="8088";
#$conf["httpMode"],字串,是否要用http模式,預設為"false",不使用,若為"true"則要使用.
$conf["httpMode"]="true";
#$conf["processFuncs"],陣列,針對收到的訊息要呼叫的函式,會帶入一個參數陣列,array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
$conf["processFuncs"]=array("\qbpwcf\connect2devcom","\qbpwcf\help","\qbpwcf\getBuf","\qbpwcf\cmd2gw","\qbpwcf\getOnlineUsers","\qbpwcf\ping","\qbpwcf\checkSession");
#參考資料:
#http://php.net/manual/en/sockets.examples.php
#http://us3.php.net/manual/en/function.socket-select.php
#response should at least end with "\r"=>http://stackoverflow.com/questions/25739768/websocket-communication-between-chromeclient-and-hotspotserver-status-line
#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
#webSocket實做=>http://srchea.com/build-a-real-time-application-using-html5-websockets
#webSocketServer實做=>http://www.cuelogic.com/blog/php-and-html5-websocket-server-and-client-communication/
#備註:
#僅能在命令列執行
$nativeSocketTcpIpServer=\qbpwcf\webSock::nativeSocketTcpIpServer($conf);
unset($conf);

#如果執行失敗
if($nativeSocketTcpIpServer["status"]==="false"){

        #印出結果
        var_dump($nativeSocketTcpIpServer);

        #結束執行
        exit;

        }#if end

#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
#(重新)連線到 devcom
function connect2devcom(&$params){

        #如果是要建立跟 devcom 的連線

        #如果資料長度大於 "connect to devcom with:"
        if( strlen($params["data"]) > strlen("connect to devcom with:") ){

                #判斷開頭是否為 "connect to devcom with:"
                #涵式說明:
                #取得符合特定字首與字尾的字串
                #回傳的結果:
                #$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
                #$result["function"],當前執行的函數名稱.
                #$result["error"],錯誤訊息陣列.
                #$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
                #$result["returnString"],爲符合字首條件的字串內容。
                #$result["argu"],使用的參數.
                #必填參數:
                #$conf["checkString"],字串,要檢查的字串.
                $conf["checkString"]=$params["data"];
                #可省略參數:
                #$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
                $conf["frontWord"]="connect to devcom with:";
                #$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
                #$conf["tailWord"]="";
                #參考資料:
                #str_spilt(),可以將字串依照字母分割成一個個陣列字串。
                $getMeetConditionsString=search::getMeetConditionsString($conf);
                unset($conf);

                #如果尋找出錯
                if($getMeetConditionsString["status"]==="false"){

                        #印出結果
                        var_dump($getMeetConditionsString);

                        #結束執行
                        exit;

                        }#if end

                #如果沒找到
                if($getMeetConditionsString["founded"]==="false"){

                        #讓程式繼續跑
                        return false;

                        }#if end

                #函式說明:
                #將字串特定關鍵字與其前面的內容剔除
                #回傳結果:
                #$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
                #$result["error"],錯誤訊息陣列.
                #$result["warning"],警告訊息鎮列.
                #$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
                #$result["function"],當前執行的函數名稱.
                #$result["oriStr"],要處理的原始字串內容.
                #$result["content"],處理好的的字串內容.        
                #必填的參數:
                #$conf["stringIn"],字串,要處理的字串.
                $conf["stringIn"]=$params["data"];
                #$conf["keyWord"],字串,特定字串.
                $conf["keyWord"]="connect to devcom with:";
                $delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf);
                unset($conf);

                #如果處理出錯
                if($delStrBeforeKeyWord["status"]==="false"){

                        #印出結果
                        var_dump($delStrBeforeKeyWord);

                        #結束執行
                        exit;

                        }#if end

                #如果關鍵字不存在
                if($delStrBeforeKeyWord["founded"]==="false"){

                        #印出結果
                        #var_dump($delStrBeforeKeyWord);

                        #讓程式繼續執行
                        return false;

                        }#if end

                #取得使用的賬號與密碼
                $emailAndPass=$delStrBeforeKeyWord["content"];

                #分割信箱與密碼
                #涵式說明:
                #將固定格式的字串分開,並回傳分開的結果。
                #回傳結果:
                #$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
                #$result["error"],錯誤訊息陣列
                #$result["function"],當前執行的函數名稱.
                #$result["argu"],使用的參數.
                #$result["oriStr"],要分割的原始字串內容
                #$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
                #$result["dataCounts"],爲總共分成幾段
                #$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
                #必填的參數:
                #$conf["stringIn"],字串,要處理的字串.
                $conf["stringIn"]=$emailAndPass;
                #$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
                $conf["spiltSymbol"]=";";
                #可省略參數:
                #$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
                $conf["allowEmptyStr"]="false";
                $spiltString=stringProcess::spiltString($conf);
                unset($conf);

                #如果分割失敗
                if($spiltString["status"]==="false"){
                
                        #印出結果
                        var_dump($spiltString);

                        #結束執行
                        exit;
                
                        }#if end

                #如果分割失敗
                if($spiltString["found"]==="false"){
                
                        #印出結果
                        var_dump($spiltString);

                        #讓程式繼續執行  
                        return false;
                
                        }#if end
                        
                #如果沒有分成兩段
                if($spiltString["dataCounts"]!==2){

                        #印出結果
                        var_dump($spiltString);

                        #讓程式繼續執行  
                        return false;

                        }#if end

                #email
                $email=$spiltString["dataArray"][0];

                #password
                $password=$spiltString["dataArray"][1];

                #取得server的ip
                #涵式說明:
                #依據提供查詢IP服務的網站取得伺服器對外的IP.
                #回傳的結果:
                #$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
                #$result["function"],當前執行的函數名稱.
                #$result["error"],錯誤訊息陣列.
                #$result["content"],伺服端對外的IP.
                #必填參數:
                #$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
                $conf["fileArgu"]=__FILE__;
                #備註:
                #需要有網站支援此服務.
                $getServerRealIP=csInformation::getServerRealIP($conf);
                unset($conf["conf"]);

                #如果執行錯誤
                if($getServerRealIP["status"]==="false")
                {
                        #印出結果
                        var_dump($getServerRealIP);

                }#if end
                
                #如果有取得對外IP
                if(isset($getServerRealIP["content"]))
                {
                        #get server ip
                        $serverIP=$getServerRealIP["content"];
                }
                
                #default is devel ip
                $serverIP="169.254.1.3";

                #判斷server的IP
                switch($serverIP)
                {
                        #52.77.106.22 - real remote
                        #172.31.28.13 - real local
                        case "52.77.106.22":
                        case "172.31.28.13":

                                #real site url
                                $cms_host="https://aesopower-cms.qbpwcf.org";

                                #跳出迴圈
                                break;

                        #18.139.160.209 - test remote
                        #172.31.23.224 - test local
                        case "18.139.160.209":
                        case "172.31.23.224":

                                #test site url
                                $cms_host="https://aesopower-cms-test.qbpwcf.org";

                                #跳出迴圈
                                break;

                        #其他狀況為 devel site
                        default:
                        
                                #devel site url
                                $cms_host="https://aesopower-cms-sock-podman.qbpwcf.org";
                        

                }#switch end

                #設置網址
                $cms_host=$cms_host."/verifyacct";
                
                #驗證賬號密碼是否正確
                #url=>cms_host/verifyacct
                #函式說明:
                #運行curl cmd
                #回傳結果:
                #$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
                #$result["error"],錯誤訊息陣列.
                #$result["function"],當前執行的函式名稱.
                #$result["content"],取得的回應內容.
                #$result["cookie"],cookie檔案的位置與名稱.
                #$result["cmd"],執行的command.
                #$result["argu],使用的參數.
                #必填參數:
                #$conf["url"],字串,目標url.
                $conf["url"]=$cms_host;
                #$conf["fileArgu"],字串,變數__FILE__的內容.
                $conf["fileArgu"]=__FILE__;
                #可省略參數:
                #$conf["header"],字串陣列,要傳送的header.
                #$conf["header"]=array();
                #$conf["allowAnySSLcertificate"],字串,是否允許不可信任的SSL憑證,預設為"true".
                #$conf["allowAnySSLcertificate"]="";
                #$conf["postVar"],字串陣列,每個要傳送的post變數名稱(陣列的key值)與數值.
                $conf["postVar"]=array();
                $conf["postVar"]["identity"]=$email;
                $conf["postVar"]["password"]=$password;
                #$conf["rawPost"]="字串",要傳送的raw post內容.
                #$conf["rawPost"]="";
                #$conf["urlEncode"],字串,post的內容是否要url_encode,"true"代表要,預設為"false"代表不要.
                #$conf["urlEncode"]="false";
                #$conf["agent"],字串,user agent的名稱.
                #$conf["agent"]="";
                #$conf["cookie"],字串,cookie位置與檔案位置.
                #$conf["cookie"]="";
                #$conf["forceNewCookie"],字串,是否要重置cookie,"true"代表要,"false"代表不要,預設為"false".
                #$conf["forceNewCookie"]="";
                $curlCmd=catchWebContent::curlCmd($conf);
                unset($conf);

                #如果運行失敗
                if($curlCmd["status"]==="false")
                {
                
                        #印出結果
                        var_dump($curlCmd);

                        #讓程式繼續執行
                        return false;
                
                }#if end
                
                #取得回應
                $res=$curlCmd["content"];

                #decode回應
                $res=json_decode($res[0]);
                
                #如果驗證不通過
                if($res->status==="false"){
                
                        #印出結果
                        var_dump("驗證不通過");
                        
                        #初始化訊息
                        $data="auth failed";
                        
                        var_dump($data);
                        
                        #json encode
                        $data=json_encode($data);
                        
                        #函式說明:
                        #加密 handshake 後要傳送的訊息 
                        #必填參數:
                        #$conf["text"],字串,要加密的訊息.
                        $conf["text"]=$data; 
                        $data=\qbpwcf\webSock::encode($conf);
                        unset($conf);

                        #告訴用戶
                        socket_write($params["clientSock"],$data,strlen($data));
                        
                        #讓程式繼續跑
                        return false;
                
                        }#if end

                $conf=array();
                $conf["ip"]="127.0.0.1";
                $conf["port"]="7053";
                $conf["dbFile"]="/var/log/".$email.".db";
                $conf["timeout"]="480";
                $conf["email"]=$email;
                #參考資料
                #https://stackoverflow.com/questions/7415091/php-exec-hangs-doesnt-continue-to-next-line => prevernt hang
                $cmd="keepAliveTcp.php -ip ".$conf["ip"]." -port ".$conf["port"]." -dbFile ".$conf["dbFile"]." -timeout ".$conf["timeout"]." -email ".$conf["email"]." > /dev/null 2>&1 &";
                $output=array();
                $status=0;
                exec($cmd,$output,$status);

                #如果執行失敗
                if($status!==0){

                        #印出結果
                        var_dump("運行 ".$cmd." 指令失敗");

                        #結束執行
                        exit;

                        }#if end

                #反之執行成功
                else{

                        #設置對應的 devcomDbFile
                        $params["clientInfo"]["devcomDbFile"]=$conf["dbFile"];

                        #取得要傳送的資料
                        $data=json_encode("Created db file:".$conf["dbFile"]); 

                        #當內容長度大於 124
                        if(strlen($data)>124){

                                #取得部分資料
                                $dp=substr($data,0,124)."&";
                                
                                #函式說明:
                                #加密 handshake 後要傳送的訊息 
                                #必填參數:
                                #$conf["text"],字串,要加密的訊息.
                                $conf["text"]=$dp; 
                                $dp=\qbpwcf\webSock::encode($conf);
                                unset($conf);
                                                
                                #告訴用戶
                                socket_write($params["clientSock"],$dp,strlen($dp));
                                
                                #取得剩餘的部分
                                $data=substr($data,124);
                                
                                #設置剩餘的部分
                                $params["clientInfo"]["buf"]=$data;

                                #讓程式繼續執行
                                return false;
                        
                                }#if end

                        #函式說明:
                        #加密 handshake 後要傳送的訊息 
                        #必填參數:
                        #$conf["text"],字串,要加密的訊息.
                        $conf["text"]=$data; 
                        $data=\qbpwcf\webSock::encode($conf);
                        unset($conf);

                        #告訴用戶
                        socket_write($params["clientSock"],$data,strlen($data));

                        }#else end

                }#if end

        #讓程式繼續執行
        return false;

        }#connect2devcom end

#提示用法
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
function help(&$params){

        #如果是要 查看用法 
        
        #如果資料為 "help"
        if( $params["data"]==="help" ){
        
                #說明
                $data=array();
                $data[]="help,本說明";
                $data[]="id?,查尋自己的id";
                $data[]="ids?,查尋在線的人除了自己有哪些";
                $data[]="talkTo?,目前在跟哪些人對話";
                $data[]="talkTo:[id],準備跟特定的人講話";
                $data[]="connect to devcom with:[email],用email/賬戶跟Devcom進行連線";
                $data[]="cmd2gw:[gwId]:[cmd],下達指令cmd給id為gwId的gw";
                $data[]="getOnlineUsers,取得在線使用者人數";
                $data=json_encode($data);
                
                #當內容長度大於 124
                if(strlen($data)>124){
                
                        #取得部分資料
                        $dp=substr($data,0,124)."&";
                        
                        #函式說明:
                        #加密 handshake 後要傳送的訊息 
                        #必填參數:
                        #$conf["text"],字串,要加密的訊息.
                        $conf["text"]=$dp; 
                        $dp=\qbpwcf\webSock::encode($conf);
                        unset($conf);

                        #告訴用戶
                        socket_write($params["clientSock"],$dp,strlen($dp));
                        
                        #取得剩餘的部分
                        $data=substr($data,124);
                        
                        #設置對應的 devcomDbFile
                        $params["clientInfo"]["buf"]=$data;

                        #讓程式繼續執行
                        return false;
                
                        }#if end

                #函式說明:
                #加密 handshake 後要傳送的訊息 
                #必填參數:
                #$conf["text"],字串,要加密的訊息.
                $conf["text"]=$data; 
                $data=\qbpwcf\webSock::encode($conf);
                unset($conf);

                #告訴用戶
                socket_write($params["clientSock"],$data,strlen($data));
        
                }#if end
                
        #讓程式繼續執行
        return false;

        }#help end      
        
#取得 Buf 內容
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
function getBuf(&$params){

        #如果輸入的內容為 "get continue buf"
        if($params["data"]==="get continue buf"){

                #取得buf內容
                $data=$params["clientInfo"]["buf"];

                #當內容長度大於 124
                if(strlen($data)>124){

                        #取得部分資料
                        $dp=substr($data,0,124)."&";
                        
                        #函式說明:
                        #加密 handshake 後要傳送的訊息 
                        #必填參數:
                        #$conf["text"],字串,要加密的訊息.
                        $conf["text"]=$dp; 
                        $dp=\qbpwcf\webSock::encode($conf);
                        unset($conf);
                                        
                        #告訴用戶
                        socket_write($params["clientSock"],$dp,strlen($dp));
                        
                        #取得剩餘的部分
                        $data=substr($data,124);

                        #記錄剩下的 buf
                        $params["clientInfo"]["buf"]=$data;

                        #讓程式繼續執行
                        return false;
                
                        }#if end

                #函式說明:
                #加密 handshake 後要傳送的訊息 
                #必填參數:
                #$conf["text"],字串,要加密的訊息.
                $conf["text"]=$data; 
                $data=\qbpwcf\webSock::encode($conf);
                unset($conf);

                #告訴用戶
                socket_write($params["clientSock"],$data,strlen($data));

                #清空buf
                $params["clientInfo"]["buf"]='';

                #讓程式繼續執行
                return false;
        
                }#if end

        #讓程式繼續執行
        return false;

        }#function getBuf end

/*
#下達指令到gw
#預設參數:
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
#格式:
#cmd2gw:gwId:cmd
#ex:"cmd2gw:34:ID01=?"
*/
function cmd2gw(&$params)
{
        #如果資料長度大於 "cmd2gw:"
        if( strlen($params["data"]) > strlen("cmd2gw:") )
        {
                #判斷開頭是否為 "cmd2gw:"
                #涵式說明:
                #取得符合特定字首與字尾的字串
                #回傳的結果:
                #$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
                #$result["function"],當前執行的函數名稱.
                #$result["error"],錯誤訊息陣列.
                #$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
                #$result["returnString"],爲符合字首條件的字串內容。
                #$result["argu"],使用的參數.
                #必填參數:
                #$conf["checkString"],字串,要檢查的字串.
                $conf["checkString"]=$params["data"];
                #可省略參數:
                #$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
                $conf["frontWord"]="cmd2gw:";
                #$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
                #$conf["tailWord"]="";
                #參考資料:
                #str_spilt(),可以將字串依照字母分割成一個個陣列字串。
                $getMeetConditionsString=search::getMeetConditionsString($conf);
                unset($conf);

                #如果尋找出錯
                if($getMeetConditionsString["status"]==="false")
                {

                        #印出結果
                        var_dump($getMeetConditionsString);

                        #結束執行
                        exit;

                }#if end

                #如果沒找到
                if($getMeetConditionsString["founded"]==="false")
                {

                        #讓程式繼續跑
                        return false;

                }#if end

                #判斷是否有認證過了
                if(!isset($params["clientInfo"]["devcomDbFile"]))
                {
                        #初始化訊息
                        $data="no permission";
                        
                        var_dump($data);
                        
                        #json encode
                        $data=json_encode($data);
                        
                        #函式說明:
                        #加密 handshake 後要傳送的訊息 
                        #必填參數:
                        #$conf["text"],字串,要加密的訊息.
                        $conf["text"]=$data; 
                        $data=\qbpwcf\webSock::encode($conf);
                        unset($conf);

                        #告訴用戶
                        socket_write($params["clientSock"],$data,strlen($data));
                        
                        #讓程式繼續跑
                        return false;
                }
                
                #判斷認證是否過期了,認證檔案是否存在.
                #涵式說明:
                #檢查多個檔案與資料夾是否存在.
                #回傳的結果:
                #$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
                #$result["error"],錯誤訊息陣列.
                #$resutl["function"],當前執行的涵式名稱.
                #$result["argu"],使用的參數.
                #$result["allExist"],所有檔案皆存在的識別,"true"代表皆存在,"false"代表沒有全部都存在.
                #$result["varName"][$i],爲第$i個資料夾或檔案的路徑與名稱。
                #$result["varNameFullPath"][$i],爲第$i個資料夾或檔案的完整檔案系統路徑與名稱,如果不存在則代表路徑是網址.
                #$result["varNameWebPath"][$i],為第$i個資料夾或檔案的網址
                #$result["varExist"][$i],爲第$i個資料夾或檔案是否存在,"true"代表存在,"false"代表不存在。
                #必填參數:
                #$conf["fileArray"],陣列字串,要檢查是否存在的檔案有哪些,須爲一維陣列數值。
                $conf["fileArray"]=array($params["clientInfo"]["devcomDbFile"]);
                #$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
                $conf["fileArgu"]=__FILE__;
                #可省略參數
                #$conf["disableWebSearch"],"字串",是否取消「當檔案找不到時,改用catchWebContent類別的wget函數來檢查檔案是否存在於網路上」的功能,"false"不取消,若要取消該功能請設為"true",若抓到的內容為空字串則會視為檔案不存在,預設為"true".
                #$conf["disableWebSearch"]="false";
                #$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".
                #$conf["userDir"]="true";
                #參考資料來源:
                #http://php.net/manual/en/function.file-exists.php
                #http://php.net/manual/en/control-structures.foreach.php
                #備註:
                #函數file_exists檢查的路徑為檔案系統的路徑
                $checkMultiFileExist=fileAccess::checkMultiFileExist($conf);
                unset($conf);

                #如果出錯
                if($checkMultiFileExist["status"]==="false")
                {

                        #印出結果
                        var_dump($checkMultiFileExist);

                        #結束執行
                        exit;

                }#if end
                
                #如果db檔案不存在
                if($checkMultiFileExist["allExist"]=="false")
                {
                        #初始化訊息
                        $data="expired";
                        
                        var_dump($data);
                        
                        #json encode
                        $data=json_encode($data);
                        
                        #函式說明:
                        #加密 handshake 後要傳送的訊息 
                        #必填參數:
                        #$conf["text"],字串,要加密的訊息.
                        $conf["text"]=$data; 
                        $data=\qbpwcf\webSock::encode($conf);
                        unset($conf);

                        #告訴用戶
                        socket_write($params["clientSock"],$data,strlen($data));
                        
                        #讓程式繼續跑
                        return false;

                        #讓程式繼續執行
                        return;

                }#if end

                #函式說明:
                #將字串特定關鍵字與其前面的內容剔除
                #回傳結果:
                #$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
                #$result["error"],錯誤訊息陣列.
                #$result["warning"],警告訊息鎮列.
                #$result["founded"],有無找到定字串"true"代表有,"false"代表沒有.
                #$result["function"],當前執行的函數名稱.
                #$result["oriStr"],要處理的原始字串內容.
                #$result["content"],處理好的的字串內容.        
                #必填的參數:
                #$conf["stringIn"],字串,要處理的字串.
                $conf["stringIn"]=$params["data"];
                #$conf["keyWord"],字串,特定字串.
                $conf["keyWord"]="cmd2gw:";
                $delStrBeforeKeyWord=stringProcess::delStrBeforeKeyWord($conf);
                unset($conf);

                #如果處理出錯
                if($delStrBeforeKeyWord["status"]==="false")
                {

                        #印出結果
                        var_dump($delStrBeforeKeyWord);

                        #結束執行
                        exit;

                }#if end

                #如果關鍵字不存在
                if($delStrBeforeKeyWord["founded"]==="false")
                {

                        #印出結果
                        #var_dump($delStrBeforeKeyWord);

                        #讓程式幾執行
                        return false;

                }#if end

                #取得gwId與要執行的指令字串
                $idCmdStr=$delStrBeforeKeyWord["content"];
                
                #透過 $params["clientInfo"]["devcomDbFile"] 檔案來得知下指令的賬號 
                
                #透過 window.lms_menu.sel_id 來得之要對哪個 gw 下達指令
        
                #分割gwId與要執行的指令字串字串
                #涵式說明:
                #將固定格式的字串分開,並回傳分開的結果。
                #回傳結果:
                #$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
                #$result["error"],錯誤訊息陣列
                #$result["function"],當前執行的函數名稱.
                #$result["argu"],使用的參數.
                #$result["oriStr"],要分割的原始字串內容
                #$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
                #$result["dataCounts"],爲總共分成幾段
                #$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
                #必填的參數:
                #$conf["stringIn"],字串,要處理的字串.
                $conf["stringIn"]=$idCmdStr;
                #$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
                $conf["spiltSymbol"]=";";
                #可省略參數:
                #$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
                $conf["allowEmptyStr"]="false";
                $spiltString=stringProcess::spiltString($conf);
                unset($conf);

                #如果分割失敗
                if($spiltString["status"]==="false"){
                
                        #印出結果
                        var_dump($spiltString);

                        #結束執行
                        exit;
                
                        }#if end

                #如果分割失敗
                if($spiltString["found"]==="false"){
                
                        #印出結果
                        var_dump($spiltString);

                        #讓程式繼續執行  
                        return false;
                
                        }#if end
                        
                #如果沒有分成兩段
                if($spiltString["dataCounts"]!==2){

                        #印出結果
                        var_dump($spiltString);

                        #讓程式繼續執行  
                        return false;

                        }#if end

                #gwId
                $gwId=$spiltString["dataArray"][0];

                #cmd
                $cmd=$spiltString["dataArray"][1];

                #取得資料庫設定檔案內容
                #涵式說明:
                #解析PHP檔案裡面的變數.
                #回傳結果:
                #$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
                #$result["error"],錯誤訊息.
                #$result["function"],當前執行的函數名稱.
                #$result["argu"],所使用的參數.
                #$result["content"],找到的變數內容陣列.
                #$result["content"]["value"],依找到變數順序的數值.
                #$result["content"]["struc"],依找到變數順序的階層結構.
                #$result["content"]["direct],變數名稱對應的數值內容.
                #必填參數:
                #$conf["file"],字串,檔案的路徑與名稱.
                $conf["file"]="/var/www/html/latest/application/config/database.php";
                #$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
                $conf["fileArgu"]=__FILE__;
                #$conf["varName"],字串陣列,要搜尋的變數名稱,例如要搜尋變數$email則輸入"email".
                $conf["varName"]=array("db['default']['hostname']","db['default']['port']","db['default']['username']","db['default']['password']","db['default']['database']");
                #參考資料:
                #https://www.php.net/manual/en/function.parse-str.php
                $parseVaraiableInPHPfile=fileAccess::parseVaraiableInPHPfile($conf);
                unset($conf);

                #如果解析出錯
                if($parseVaraiableInPHPfile["status"]==="false")
                {
                        #印出結果
                        var_dump($parseVaraiableInPHPfile);

                        #讓程式繼續執行
                        return false;
                
                }#if end
                
                #取得 db host
                $dbHost=$parseVaraiableInPHPfile["content"]["direct"]["db['default']['hostname']"];

                #取得 db port
                $dbPort=$parseVaraiableInPHPfile["content"]["direct"]["db['default']['port']"];

                #取得 db user name
                $dbUser=$parseVaraiableInPHPfile["content"]["direct"]["db['default']['username']"];

                #取得 db password
                $dbPassword=$parseVaraiableInPHPfile["content"]["direct"]["db['default']['password']"];

                #取得 db name
                $dbName=$parseVaraiableInPHPfile["content"]["direct"]["db['default']['database']"];

                #用 gwId 來查尋 gsn,lanmac,imi
                #涵式說明:
                #一次取得資料庫、表的資料
                #回傳的結果
                #$result["status"],執行結果"true"為成功;"false"為執行失敗。
                #$result["error"],錯誤訊息陣列。
                #$result["function"],當前執行的漢書名稱.
                #$result["argu"],使用的參數.
                #$result["dataColumnName"],抓取的資料欄位名稱陣列.
                        #$result["dataColumnName"][$i]代表第$i+1個欄位名稱
                #$result["dataContent"],爲資料的內容。
                #$result["dataContent"][$conf["WhereColumnName"][$i]][$dataSetNum]
                        #$dataSetNum 爲第$dataSetNum+1筆資料
                        #$conf["WhereColumnName"][$i] 爲第 $i+1 個欄位的名稱
                #$result["dataCount"],爲取得的資料筆數。
                #$result["sql"],執行的sql字串.
                #必填的參數:
                $conf["dbAddress"]=$dbHost;#爲dbServer的位置。
                $conf["dbAccount"]=$dbUser;#爲登入dbServer的帳號。
                $conf["dbName"]=$dbName;#爲要存取的資料庫名稱
                $conf["tableName"]="device";#爲要存取的資料表名稱
                $conf["columnYouWant"]=array("lanmac","telcom_imi","telcom_gsn");#你想要的欄位!,若設為「array("*")」則代表全部欄位.
                #可省略的參數:
                $conf["dbPassword"]=$dbPassword;#爲要存取dbServer的密碼
                #$conf["dbPort"],字串,爲連線到mysql-Server時要使用的port,可省略,若省略則代表使用預設的3306 port.
                $conf["dbPort"]=$dbPort;
                $conf["WhereColumnName"]=array("id");#用於判斷語句的欄位項目陣列。
                $conf["WhereColumnValue"]=array($gwId);#用於判斷語句的欄位數值陣列,若與LIKE搭配,則可以在關鍵自字串的左右名加上「%」符號,這樣就可以搜尋具有該字串的內容。
                #$conf["WhereColumnCombine"]=array("");#用於判斷語句當中需要()起來的判斷式,須爲陣列值,"s"代表「(」,"e"代表「)」 ,若無則須設爲""。
                #$conf["WhereColumnOperator"]=array("");#用於判斷語句的比較符號陣列,可以用的符號有「"="、"!="、">"、"<"、"LIKE"、"NOT LIKE"」,預設都爲「=」。
                #$conf["WhereColumnAndOr"]=array("");#用於判斷語句條件之間成立的條件是AND還是OR,須爲陣列值。其數量應爲要判斷的欄位數量減一。
                #$conf["whereIn"],二維字串陣列,為每個in語句的內容,特定欄位數值等於陣列元素之一。array(array("colName",array("a","b","c")));代表欄位colName的值為a,b,c三者之一.
                #$conf["whereIn"]=array(array("colName",array("a","b","c")));
                #$conf["whereNotIn"],二維字串陣列,為每個not in語句的內容,array(array("colName",array("a","b","c")));代表欄位colName的值不為a,b,c三者之一.
                #$conf["whereNotIn"]=array(array("colName",array("a","b","c")));
                #$conf["orderItem"]="";#爲排序的項目依據,若要用隨機抽樣,可以用"rand()",可省略。
                #$conf["ascORdesc"]="";#爲要低增還是遞減排序,asc爲遞增;desc爲遞減。
                #$conf["numberStart"]="0";#為從第幾筆開始讀取,預設為0,代筆第一筆。
                #$conf["numLimit"]="30";#為要取幾筆資料,可以省略,省略則表示不限制數目。
                #$conf["groupBy"]=array("");#爲要以哪幾個欄爲作爲分羣的依據(欄位相同的數值僅會取出一筆)。
                $fastGetDbData=db::fastGetDbData($conf);
                unset($conf);
                
                #debug
                #$var_dump($fastGetDbData);
                
                #如果執行失敗
                if($fastGetDbData["status"]==="false")
                {
                        #印出結果
                        var_dump($fastGetDbData);

                        #讓程式繼續執行
                        exit;
                
                }#if end
                
                #如果沒有符合的資料
                if($fastGetDbData["dataCount"]===0)
                {
                        #印出結果
                        var_dump($fastGetDbData);

                        #讓程式繼續執行
                        return false;
                
                }#if end
                
                #取得devcom db檔案
                $devcomDbFile=$params["clientInfo"]["devcomDbFile"];
                
                #函式說明:
                #依據行號分隔抓取檔案的內容,結果會回傳一個陣列
                #回傳的變數說明:
                #$result["status"],執行是否成功,"true"代表成功;"fasle"代表失敗.
                #$result["error"],錯誤訊息提示.
                #$result["warning"],警告訊息.
                #$result["function"],當前執行的函數名稱.
                #$result["fileContent"],爲檔案的內容陣列.
                #$result["lineCount"],爲檔案內容總共的行數.
                #$result["fullContent"],為檔案的完整內容.
                #$result["base64data"],為檔案的base64內容.
                #$result["mimeType"],為檔案的mime type.
                #必填的參數:
                #$conf["filePositionAndName"],字串,爲檔案的位置以及名稱.
                $conf["filePositionAndName"]=$devcomDbFile;
                #$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
                $conf["fileArgu"]=__FILE__;
                #參考資料:
                #file(),取得檔案內容的行數.
                #file=>http:#php.net/manual/en/function.file.php
                #rtrim(),剔除透過file()取得每行內容結尾的換行符號.
                #filesize=>http://php.net/manual/en/function.filesize.php
                $getFileContent=fileAccess::getFileContent($conf);
                unset($conf);
                
                #如果執行失敗
                if($getFileContent["status"]==="false")
                {
                        #印出結果
                        var_dump($getFileContent);

                        #讓程式繼續執行
                        exit;
                
                }#if end
                
                #初始化儲存每列的內容
                $lineInDb=array();
                
                #如果沒有第一行內容
                if(!isset($getFileContent["fileContent"][0]))
                {
                        #印出結果
                        var_dump($getFileContent);

                        #讓程式繼續執行
                        exit;
                }
                
                #取得第一行的內容
                $firstLine=$getFileContent["fileContent"][0];
                                
                #解析第一行的內容,將換行符號剔除
                $firstLine=json_decode(trim($firstLine));
                
                #更新 last_action_time
                $firstLine->last_action_time=time(0);
                
                #更新第一行的內容
                $lineInDb[]=json_encode($firstLine);
                
                #有幾行就執行幾次
                for($i=1;$i<$getFileContent["lineCount"];$i++)
                {
                        #記錄內容
                        $lineInDb[]=$getFileContent["fileContent"][$i];
                
                }#for end
                
                #初始化末行的指令
                $lastLine=array();
                
                #設定末行的指令類型為"tgw"
                $lastLine["type"]="tgw";
                
                #設定末行的指令內容
                $lastLine["data"]=$cmd;
                
                #設定末行的gw id
                $lastLine["gwId"]=$gwId;
                
                #新增末行的指令
                $lineInDb[]=json_encode($lastLine);

                #回寫內容到 $devcomDbFile
                #涵式說明:
                #將多行字串寫入到檔案
                #回傳的結果:
                #$result["status"],"true"表示檔案寫入成功,"false"表示檔案寫入失敗.
                #$result["error"],錯誤訊息陣列.
                #$result["function"],當前執行函數的名稱.
                #必填的參數:
                #$conf["fileName"],字串,爲要編輯的檔案名稱
                $conf["fileName"]=$devcomDbFile;
                #$conf["inputString"],字串陣列,爲要寫入到 $conf["fileName"] 裏面的內容
                        #$conf["inputString"][$i] 代表第 $i+1 行。
                $conf["inputString"]=$lineInDb;
                #$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
                $conf["fileArgu"]=__FILE__;
                #可省略的參數:
                #$conf["writeMethod"]="a";#爲檔案撰寫的方式,可省略,是複寫'a'還是,重新寫入'w',預設爲'w',重新寫入。
                $writeMultiLine=fileAccess::writeMultiLine($conf);
                unset($conf);

                #如果執行失敗
                if($writeMultiLine["status"]==="false")
                {
                        #印出結果
                        var_dump($$writeMultiLine);

                        #讓程式繼續執行
                        exit;
                
                }#if end
                
                #提示指令已經進入佇列
                $data=json_encode("指令 ".$cmd." 送往id為 ".$gwId." 的gw 已經進入佇列");
                
                #函式說明:
                #加密 handshake 後要傳送的訊息 
                #必填參數:
                #$conf["text"],字串,要加密的訊息.
                $conf["text"]=$data; 
                $data=\qbpwcf\webSock::encode($conf);
                unset($conf);

                #告訴用戶
                socket_write($params["clientSock"],$data,strlen($data));

        }#if end

        #讓程式繼續執行
        return false;

        }#function cmd2gw end

/*
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
*/
function getOnlineUsers(&$params)
{
        #如果資料內容等於 "getOnlineUsers"
        if($params["data"]==="getOnlineUsers")
        {
                #get client sock
                $clientSock=&$params["clientSock"];
                
                #預設在線的使用者人數為0
                $onlineUserCount=0;
                
                #針對每個連線
                foreach($params["allConn"] as $index=>$conn)
                {
                        #如果存在id
                        if($conn["id"]!==null)
                        {
                                #計數+1
                                $onlineUserCount++;
                        }#if end
                
                }#foreach end
                
                #提示指令已經進入佇列
                $data=json_encode("目前在線使用者人數為:".$onlineUserCount);
                
                #函式說明:
                #加密 handshake 後要傳送的訊息 
                #必填參數:
                #$conf["text"],字串,要加密的訊息.
                $conf["text"]=$data; 
                $data=\qbpwcf\webSock::encode($conf);
                unset($conf);

                #告訴用戶
                socket_write($params["clientSock"],$data,strlen($data));
        
        }#if end
        
        #讓程式繼續執行
        return false;
}

/*
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
*/
function ping(&$params)
{
        #如果資料內容等於 "ping"
        if($params["data"]==="ping")
        {
                var_dump('set last ping time');
        
                //記錄最後一次 ping 的時間
                $params["clientInfo"]["lastPingTime"]=time(0);
        
        }#if end
        
        #針對每個用戶
        foreach($params["allConn"] as $index=>$client)
        {
                #如果有最後一次 ping 的時間
                if(isset($client["lastPingTime"]))
                {
                        #如果最後一次 ping 的時間距離現在超過 5 秒鐘
                        if(time(0)-$client["lastPingTime"]>5)
                        {
                                #關閉與用戶之間的連線
                                socket_close($client["connect"]);
                                
                                #移除在 server 上的記錄
                                unset($params["allConn"][$index]);
                        
                        }#if end
                
                }#if end
        
        }#foreach end

        #讓程式繼續執行
        return false;
}

/*
#$params=array("data"=>收到的資料,"serverSock"=>serverSock,"clientSock"=>clientSock,"clientInfo"=>用戶端的資訊,"clientIndex"=>用戶端的索引,"allConn"=>所有連線的用戶端的連線資訊);
#顯示 session 變數的內容
*/
function checkSession(&$params)
{
        var_dump($params);
        
        #讓程式繼續執行
        return false;
}

?>