VM暫存
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

251 行
8.9KB

  1. <?php
  2. require_once '/home/bigbang/libs/Workerman/Autoloader.php';
  3. use Workerman\Worker;
  4. Worker::$logFile = '/dev/null'; // 不記錄log file
  5. //Worker::$pidFile = '/tmp/run/'.basename(__FILE__).'.pid';
  6. //Worker::$logFile = __DIR__ . '/../acer2server.log';
  7. // 場站共用設定檔
  8. require_once '/home/bigbang/apps/coworker/station.config.php';
  9. define('APP_NAME', 'acer'); // application name
  10. define('WORKERMAN_DEBUG', 1);
  11. if (WORKERMAN_DEBUG)
  12. {
  13. ini_set('display_errors', '1');
  14. error_reporting(E_ALL);
  15. set_error_handler('error_handler', E_ALL);
  16. }
  17. ///////////////////////////////
  18. //
  19. // 回傳代碼定義
  20. //
  21. ///////////////////////////////
  22. // 結果代碼
  23. define('ALTOB_RESULT_CODE_SUCCESS', 'OK'); // 成功
  24. define('ALTOB_RESULT_CODE_FAIL', 'GG'); // 失敗
  25. // 錯誤碼
  26. define('ALTOB_ERROR_CODE_NONE', '0000'); // 預設值 (成功帶這個)
  27. define('ALTOB_ERROR_CODE_UNKNOWN_INPUT', '1001'); // 未知的 輸入
  28. define('ALTOB_ERROR_CODE_UNKNOWN_CMD', '1002'); // 未知的 CMD
  29. define('ALTOB_ERROR_CODE_UNDEFINED', '9999'); // 未定義的錯誤
  30. define('ALTOB_ERROR_CODE_ACER_RESULT_FAIL', '2001'); // ACER 回傳處理錯誤
  31. ///////////////////////////////
  32. //
  33. // 主程式
  34. //
  35. ///////////////////////////////
  36. // 傳送主機資料
  37. $ch = curl_init();
  38. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  39. curl_setopt($ch, CURLOPT_POST, true); // 啟用POST
  40. // 建立一個Worker監聽8033埠,不使用任何應用層協定
  41. $tcp_worker = new Worker("tcp://0.0.0.0:8033");
  42. // 啟動N個進程對外提供服務
  43. $tcp_worker->count = 4;
  44. $tcp_worker->onConnect = function($connection)
  45. {
  46. echo "New Connection\n";
  47. };
  48. $tcp_worker->onClose = function($connection)
  49. {
  50. echo "Connection closed\n";
  51. };
  52. // 當用戶端發來數據(主程式)
  53. $tcp_worker->onMessage = function($connection, $tcp_in)
  54. {
  55. global $ch;
  56. $explode_tcp_in = explode(chr(28), $tcp_in); // 0x1C tcp欄位分隔
  57. $send_data = null;
  58. if(empty($explode_tcp_in) || count($explode_tcp_in) != 5)
  59. {
  60. trigger_error(".. unknown tcp_in|". print_r($explode_tcp_in, true) .'|');
  61. $send_data = gen_error_result(ALTOB_ERROR_CODE_UNKNOWN_INPUT);
  62. }
  63. else
  64. {
  65. list(, $seq, $cmd, $data, ) = $explode_tcp_in;
  66. $seq = 1;
  67. switch($cmd)
  68. {
  69. // 票卡入場訊號,供 ALTOB 登記
  70. case '001':
  71. //(傳入:卡號、入場編號、是否月租卡; 回傳:成功、入場編號)
  72. list($card_no, $cario_no, $card_type) = explode(chr(31), $data); // 0x1F data欄位分隔
  73. trigger_error("cmd:{$cmd}, card_no:{$card_no}, cario_no:{$cario_no}, card_type:{$card_type}");
  74. // 呼叫 cmd_001
  75. $data = array('card_no' => $card_no, 'cario_no' => $cario_no, 'card_type' => $card_type);
  76. curl_setopt($ch, CURLOPT_URL, 'http://localhost/acer_service.html/cmd_001/');
  77. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
  78. $jdata = curl_exec($ch);
  79. $result = json_decode($jdata, true);
  80. trigger_error("{$cmd}|{$card_no}|{$cario_no}|{$card_type}|result|" . print_r($result, true));
  81. $send_data = gen_cario_result($seq, $cmd,
  82. $result['result_code'],
  83. $result['result']['cario_no'],
  84. $result['result']['error_code']);
  85. break;
  86. // 票卡離場訊號,供 ALTOB 登記
  87. case '002':
  88. //(傳入:卡號、繳費時間、是否月租卡; 回傳:成功、入場編號)
  89. list($card_no, $pay_time, $card_type) = explode(chr(31), $data); // 0x1F data欄位分隔
  90. trigger_error("cmd:{$cmd}, card_no:{$card_no}, pay_time:{$pay_time}, card_type:{$card_type}");
  91. // 呼叫 cmd_002
  92. $data = array('card_no' => $card_no, 'pay_time' => $pay_time, 'card_type' => $card_type);
  93. curl_setopt($ch, CURLOPT_URL, 'http://localhost/acer_service.html/cmd_002/');
  94. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
  95. $jdata = curl_exec($ch);
  96. $result = json_decode($jdata, true);
  97. trigger_error("{$cmd}|{$card_no}|{$pay_time}|{$card_type}|result|" . print_r($result, true));
  98. $send_data = gen_cario_result($seq, $cmd,
  99. $result['result_code'],
  100. $result['result']['cario_no'],
  101. $result['result']['error_code']);
  102. break;
  103. // 票號離場訊號,回傳若成功觸發 ACER 開門
  104. case '003':
  105. // (傳入:6 碼數字; 回傳:入場編號、成功與否代號)
  106. list($ticket_no) = explode(chr(31), $data); // 0x1F data欄位分隔
  107. trigger_error("cmd:{$cmd}, ticket_no:{$ticket_no}");
  108. // 呼叫 cmd_003
  109. $data = array('ticket_no' => $ticket_no);
  110. curl_setopt($ch, CURLOPT_URL, 'http://localhost/acer_service.html/cmd_003/');
  111. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
  112. $jdata = curl_exec($ch);
  113. $result = json_decode($jdata, true);
  114. trigger_error("{$cmd}|{$ticket_no}|result|" . print_r($result, true));
  115. $send_data = gen_cario_result($seq, $cmd,
  116. $result['result_code'],
  117. $result['result']['cario_no'],
  118. $result['result']['error_code'],
  119. $result['result']['msg_code']);
  120. break;
  121. default:
  122. trigger_error(".. unknown cmd | {$seq}, {$cmd}, {$data}|");
  123. $send_data = gen_error_result(ALTOB_ERROR_CODE_UNKNOWN_CMD);
  124. break;
  125. }
  126. }
  127. // 未定義的錯誤
  128. if(empty($send_data))
  129. {
  130. $send_data = gen_error_result(ALTOB_ERROR_CODE_UNDEFINED);
  131. }
  132. $connection->close($send_data);
  133. };
  134. // 執行worker
  135. Worker::runAll();
  136. // 產生錯誤回傳
  137. function gen_error_result($error_code)
  138. {
  139. return gen_cario_result(0, 0, ALTOB_RESULT_CODE_FAIL, 0, $error_code);
  140. }
  141. // 產生 cario_no 回傳
  142. function gen_cario_result($seq, $cmd, $result_code, $cario_no, $error_code, $msg_code=0)
  143. {
  144. $send_data = '';
  145. $seq_pad = str_pad($seq, 5, '0', STR_PAD_LEFT); // 序號: 5 碼 (左邊補 0)
  146. $cmd_pad = str_pad($cmd, 3, '0', STR_PAD_LEFT); // 指令: 3 碼 (左邊補 0)
  147. $cario_no_pad = str_pad($cario_no, 10, '0', STR_PAD_LEFT); // 入場編號: 10 碼 (左邊補 0)
  148. $error_code_pad = str_pad($error_code, 4, '0', STR_PAD_LEFT); // 錯誤碼: 4 碼 (左邊補 0)
  149. $msg_code_pad = str_pad($msg_code, 5, '0', STR_PAD_LEFT); // 離場代碼: 5 碼 (左邊補 0)
  150. trigger_error(__FUNCTION__ . "..{$seq_pad}|{$cmd_pad}|{$cario_no_pad}|{$error_code_pad}|{$msg_code_pad}..");
  151. if(empty($msg_code))
  152. {
  153. $packformat = "a2Ca10Ca4";
  154. $data = pack($packformat,
  155. // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
  156. $result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad
  157. );
  158. $data_len = strlen($data);
  159. $socket_len = $data_len + 16;
  160. //trigger_error(".. TEST socket_len | {$socket_len}, {$data_len}|". intval($socket_len / 0x0100). '_'. intval($socket_len % 0x0100));
  161. $send_data = pack("Ca2Ca5Ca3C{$packformat}CCC",
  162. 0x02, // STX:封包起始碼(0x02)
  163. $socket_len, 0x1c, // 封包長度:從STX到ETX的位元數
  164. $seq_pad, 0x1c, // 封包流水號:5碼ASCII數字(不足5碼時左補”0”補滿5碼)
  165. $cmd_pad, 0x1c, // CmdID:命令ID
  166. // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
  167. $result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad,
  168. 0x1c,
  169. 0x80, // CRC:封包檢查碼
  170. 0x03 // ETX:封包結束碼(0x03)
  171. );
  172. }
  173. else
  174. {
  175. $packformat = "a2Ca10Ca4Ca5";
  176. $data = pack($packformat,
  177. // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
  178. $result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad, 0x1f, $msg_code_pad
  179. );
  180. $data_len = strlen($data);
  181. $socket_len = $data_len + 16;
  182. //trigger_error(".. TEST socket_len | {$socket_len}, {$data_len}|". intval($socket_len / 0x0100). '_'. intval($socket_len % 0x0100));
  183. $send_data = pack("Ca2Ca5Ca3C{$packformat}CCC",
  184. 0x02, // STX:封包起始碼(0x02)
  185. $socket_len, 0x1c, // 封包長度:從STX到ETX的位元數
  186. $seq_pad, 0x1c, // 封包流水號:5碼ASCII數字(不足5碼時左補”0”補滿5碼)
  187. $cmd_pad, 0x1c, // CmdID:命令ID
  188. // Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
  189. $result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad, 0x1f, $msg_code_pad,
  190. 0x1c,
  191. 0x80, // CRC:封包檢查碼
  192. 0x03 // ETX:封包結束碼(0x03)
  193. );
  194. }
  195. return $send_data;
  196. }
  197. // 發生錯誤時集中在此處理
  198. function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
  199. {
  200. $str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
  201. error_log($str, 3, LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名
  202. }