count = 4; $tcp_worker->onConnect = function($connection) { echo "New Connection\n"; }; $tcp_worker->onClose = function($connection) { echo "Connection closed\n"; }; // 當用戶端發來數據(主程式) $tcp_worker->onMessage = function($connection, $tcp_in) { global $ch; $explode_tcp_in = explode(chr(28), $tcp_in); // 0x1C tcp欄位分隔 $send_data = null; if(empty($explode_tcp_in) || count($explode_tcp_in) != 5) { trigger_error(".. unknown tcp_in|". print_r($explode_tcp_in, true) .'|'); $send_data = gen_error_result(ALTOB_ERROR_CODE_UNKNOWN_INPUT); } else { list(, $seq, $cmd, $data, ) = $explode_tcp_in; $seq = 1; switch($cmd) { // 票卡入場訊號,供 ALTOB 登記 case '001': //(傳入:卡號、入場編號、是否月租卡; 回傳:成功、入場編號) list($card_no, $cario_no, $card_type) = explode(chr(31), $data); // 0x1F data欄位分隔 trigger_error("cmd:{$cmd}, card_no:{$card_no}, cario_no:{$cario_no}, card_type:{$card_type}"); // 呼叫 cmd_001 $data = array('card_no' => $card_no, 'cario_no' => $cario_no, 'card_type' => $card_type); curl_setopt($ch, CURLOPT_URL, 'http://localhost/acer_service.html/cmd_001/'); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); $jdata = curl_exec($ch); $result = json_decode($jdata, true); trigger_error("{$cmd}|{$card_no}|{$cario_no}|{$card_type}|result|" . print_r($result, true)); $send_data = gen_cario_result($seq, $cmd, $result['result_code'], $result['result']['cario_no'], $result['result']['error_code']); break; // 票卡離場訊號,供 ALTOB 登記 case '002': //(傳入:卡號、繳費時間、是否月租卡; 回傳:成功、入場編號) list($card_no, $pay_time, $card_type) = explode(chr(31), $data); // 0x1F data欄位分隔 trigger_error("cmd:{$cmd}, card_no:{$card_no}, pay_time:{$pay_time}, card_type:{$card_type}"); // 呼叫 cmd_002 $data = array('card_no' => $card_no, 'pay_time' => $pay_time, 'card_type' => $card_type); curl_setopt($ch, CURLOPT_URL, 'http://localhost/acer_service.html/cmd_002/'); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); $jdata = curl_exec($ch); $result = json_decode($jdata, true); trigger_error("{$cmd}|{$card_no}|{$pay_time}|{$card_type}|result|" . print_r($result, true)); $send_data = gen_cario_result($seq, $cmd, $result['result_code'], $result['result']['cario_no'], $result['result']['error_code']); break; // 票號離場訊號,回傳若成功觸發 ACER 開門 case '003': // (傳入:6 碼數字; 回傳:入場編號、成功與否代號) list($ticket_no) = explode(chr(31), $data); // 0x1F data欄位分隔 trigger_error("cmd:{$cmd}, ticket_no:{$ticket_no}"); // 呼叫 cmd_003 $data = array('ticket_no' => $ticket_no); curl_setopt($ch, CURLOPT_URL, 'http://localhost/acer_service.html/cmd_003/'); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); $jdata = curl_exec($ch); $result = json_decode($jdata, true); trigger_error("{$cmd}|{$ticket_no}|result|" . print_r($result, true)); $send_data = gen_cario_result($seq, $cmd, $result['result_code'], $result['result']['cario_no'], $result['result']['error_code'], $result['result']['msg_code']); break; default: trigger_error(".. unknown cmd | {$seq}, {$cmd}, {$data}|"); $send_data = gen_error_result(ALTOB_ERROR_CODE_UNKNOWN_CMD); break; } } // 未定義的錯誤 if(empty($send_data)) { $send_data = gen_error_result(ALTOB_ERROR_CODE_UNDEFINED); } $connection->close($send_data); }; // 執行worker Worker::runAll(); // 產生錯誤回傳 function gen_error_result($error_code) { return gen_cario_result(0, 0, ALTOB_RESULT_CODE_FAIL, 0, $error_code); } // 產生 cario_no 回傳 function gen_cario_result($seq, $cmd, $result_code, $cario_no, $error_code, $msg_code=0) { $send_data = ''; $seq_pad = str_pad($seq, 5, '0', STR_PAD_LEFT); // 序號: 5 碼 (左邊補 0) $cmd_pad = str_pad($cmd, 3, '0', STR_PAD_LEFT); // 指令: 3 碼 (左邊補 0) $cario_no_pad = str_pad($cario_no, 10, '0', STR_PAD_LEFT); // 入場編號: 10 碼 (左邊補 0) $error_code_pad = str_pad($error_code, 4, '0', STR_PAD_LEFT); // 錯誤碼: 4 碼 (左邊補 0) $msg_code_pad = str_pad($msg_code, 5, '0', STR_PAD_LEFT); // 離場代碼: 5 碼 (左邊補 0) trigger_error(__FUNCTION__ . "..{$seq_pad}|{$cmd_pad}|{$cario_no_pad}|{$error_code_pad}|{$msg_code_pad}.."); if(empty($msg_code)) { $packformat = "a2Ca10Ca4"; $data = pack($packformat, // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內 $result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad ); $data_len = strlen($data); $socket_len = $data_len + 16; //trigger_error(".. TEST socket_len | {$socket_len}, {$data_len}|". intval($socket_len / 0x0100). '_'. intval($socket_len % 0x0100)); $send_data = pack("Ca2Ca5Ca3C{$packformat}CCC", 0x02, // STX:封包起始碼(0x02) $socket_len, 0x1c, // 封包長度:從STX到ETX的位元數 $seq_pad, 0x1c, // 封包流水號:5碼ASCII數字(不足5碼時左補”0”補滿5碼) $cmd_pad, 0x1c, // CmdID:命令ID // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內 $result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad, 0x1c, 0x80, // CRC:封包檢查碼 0x03 // ETX:封包結束碼(0x03) ); } else { $packformat = "a2Ca10Ca4Ca5"; $data = pack($packformat, // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內 $result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad, 0x1f, $msg_code_pad ); $data_len = strlen($data); $socket_len = $data_len + 16; //trigger_error(".. TEST socket_len | {$socket_len}, {$data_len}|". intval($socket_len / 0x0100). '_'. intval($socket_len % 0x0100)); $send_data = pack("Ca2Ca5Ca3C{$packformat}CCC", 0x02, // STX:封包起始碼(0x02) $socket_len, 0x1c, // 封包長度:從STX到ETX的位元數 $seq_pad, 0x1c, // 封包流水號:5碼ASCII數字(不足5碼時左補”0”補滿5碼) $cmd_pad, 0x1c, // CmdID:命令ID // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內 $result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad, 0x1f, $msg_code_pad, 0x1c, 0x80, // CRC:封包檢查碼 0x03 // ETX:封包結束碼(0x03) ); } return $send_data; } // 發生錯誤時集中在此處理 function error_handler($errno, $errstr, $errfile, $errline, $errcontext) { $str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n"; error_log($str, 3, LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名 }