|
@@ -0,0 +1,298 @@
|
|
|
+<?php
|
|
|
+require('../vendor/autoload.php');
|
|
|
+use \PhpMqtt\Client\MqttClient;
|
|
|
+use \PhpMqtt\Client\ConnectionSettings;
|
|
|
+use think\facade\Cache;
|
|
|
+date_default_timezone_set("PRC");
|
|
|
+define('HOST', '127.0.0.1');
|
|
|
+define('PORT', '6379');
|
|
|
+define('PASSWORD', 'R!478gH*%23nPn');
|
|
|
+// define('PASSWORD', '123456');
|
|
|
+define('DATABASE', 2);
|
|
|
+
|
|
|
+
|
|
|
+function app_redis()
|
|
|
+{
|
|
|
+ static $redis = null;
|
|
|
+ static $conn = false;
|
|
|
+ if (!$conn) {
|
|
|
+ connect: //定义标签
|
|
|
+ $redis = new Redis();
|
|
|
+ try {
|
|
|
+ //建立的Redis短连接,在请求结束后不会自动关闭,相当于持久连接.
|
|
|
+ $conn = $redis->connect(HOST, PORT);
|
|
|
+ $conn = $redis->auth(PASSWORD);
|
|
|
+ $conn = $redis->select(DATABASE);
|
|
|
+ // 连接成功,返回$redis对象,连接失败,返回false.
|
|
|
+ return ($conn === true) ? $redis : false;
|
|
|
+ } catch (Exception $e) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 这里假设PHP-FPM在处理一个请求的时间内,Redis连接都是可用的.
|
|
|
+ // 所以只在PHP-CLI下检查Redis连接的状态,进行断线重连.
|
|
|
+ if (php_sapi_name() === 'cli') {
|
|
|
+ try {
|
|
|
+ // ping用于检查当前连接的状态,成功时返回+PONG,失败时抛出一个RedisException对象.
|
|
|
+ // ping失败时警告:
|
|
|
+ // Warning: Redis::ping(): connect() failed: Connection refused
|
|
|
+ // var_dump('AAAAAAAAA', $redis);
|
|
|
+ echo 'Redis 连接状态' . $redis->ping() . PHP_EOL;
|
|
|
+ @$redis->ping();
|
|
|
+ if (!$redis->ping()) {
|
|
|
+ goto connect; //跳转到标签出继续执行连接操作
|
|
|
+ }
|
|
|
+ } catch (Exception $e) {
|
|
|
+ // 信息如 Connection lost 或 Redis server went away
|
|
|
+ echo $e->getMessage();
|
|
|
+ echo 'Redis 连接失败 重新连接:' . PHP_EOL;
|
|
|
+ // 断线重连
|
|
|
+ goto connect;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $redis;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function rlog(...$args)
|
|
|
+{
|
|
|
+ if (empty($args[0])) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ static $LOG_CONSOLE = false; //是否输出到控制台
|
|
|
+ static $LOG_NAME = "parea_inoutres_push.log"; //值为空时 不写入文件
|
|
|
+ static $LOG_SIZE = 64 * 1024 * 1024; //文件最大尺寸
|
|
|
+
|
|
|
+ static $LOG_CACHE = false; //是否缓存日志内容 用于批量写入文件
|
|
|
+ static $CACHE_DURATION = 10; //缓存最大时间 秒
|
|
|
+ static $CACHE_SIZE = 1024; //缓存大小
|
|
|
+ static $cacheStartTime = 0;
|
|
|
+ static $cacheBuf = '';
|
|
|
+
|
|
|
+ static $LOG_TIMES = 10; //调用这个函数最大次数 超过次数后判断下文件大小
|
|
|
+ static $logCount = 0;
|
|
|
+
|
|
|
+
|
|
|
+ $buf = '';
|
|
|
+ if (count($args) == 1 && $args[0] == "\n") { //只有换行时 不写入时间戳了
|
|
|
+ $buf = "\n";
|
|
|
+ } else {
|
|
|
+ $pid = ''; //进程id
|
|
|
+ if (function_exists('posix_getpid')) {
|
|
|
+ $pid = ' ' . posix_getpid() . ' ';
|
|
|
+ }
|
|
|
+ $fileLine = ''; //文件名:行号
|
|
|
+ {
|
|
|
+ $debug = debug_backtrace();
|
|
|
+ $fileLine = ($pid == '' ? ' ' : '') . basename($debug[0]['file']) . ':' . $debug[0]['line'] . ' ';
|
|
|
+ }
|
|
|
+ $buf = date("y-m-d H:i:s") . "{$pid}{$fileLine}" . implode(' ', $args) . "\n";
|
|
|
+ }
|
|
|
+
|
|
|
+ $logCount++;
|
|
|
+ if (!empty($LOG_NAME)) {
|
|
|
+ if ($LOG_CACHE) {
|
|
|
+ $cacheBuf .= $buf;
|
|
|
+ //超过缓存尺寸 或者 超过缓存时长 写缓存到文件
|
|
|
+ if (strlen($cacheBuf) > $CACHE_SIZE || time() - $cacheStartTime > $CACHE_DURATION) {
|
|
|
+ $cacheStartTime = time();
|
|
|
+ goto write;
|
|
|
+ } else {
|
|
|
+ goto skipWrite;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $cacheBuf = $buf;
|
|
|
+ }
|
|
|
+ write: {
|
|
|
+ //超过尺寸后 删除旧文件 把新文件重命名为旧文件 多进程同时操作 不加锁问题不大
|
|
|
+ if ($logCount > $LOG_TIMES && filesize($LOG_NAME) > $LOG_SIZE) {
|
|
|
+ $oldLogName = $LOG_NAME . '.old';
|
|
|
+ if (file_exists($oldLogName)) {
|
|
|
+ if (!unlink($oldLogName)) {
|
|
|
+ echo "unlink err\n";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!rename($LOG_NAME, $oldLogName)) {
|
|
|
+ echo "rename err\n";
|
|
|
+ }
|
|
|
+ $logCount = 0;
|
|
|
+ }
|
|
|
+ if (!file_put_contents($LOG_NAME, $cacheBuf, FILE_APPEND)) {
|
|
|
+ echo "file_put_contents err\n";
|
|
|
+ }
|
|
|
+ $cacheBuf = '';
|
|
|
+ }
|
|
|
+ skipWrite: {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($LOG_CONSOLE) {
|
|
|
+ echo $buf;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function http($url, $params, $header = [], $method = 'GET', $timeout = 10)
|
|
|
+{
|
|
|
+ // POST $params 字符串形式query=abcd&abc=12345
|
|
|
+ //GET $params 数组['query' => 'abcd', 'abc' => 12345]
|
|
|
+ // $header[] = "Content-Type: application/x-www-form-urlencoded";
|
|
|
+ // $header[] = "Content-Type: application/soap+xml; charset=utf-8";
|
|
|
+ // $header[] = "Content-Type: application/json; charset=utf-8";
|
|
|
+ // $header[] = "Expect: ";
|
|
|
+ rlog("[HTTP] url:$url,method:$method" . ",header:" . json_encode($header));
|
|
|
+ if (strtoupper($method) == 'POST') {
|
|
|
+ rlog("[POST] send params " . (!is_array($params) ? $params : json_encode($params, JSON_UNESCAPED_UNICODE)));
|
|
|
+ } else {
|
|
|
+ rlog("[GET] send " . json_encode($params));
|
|
|
+ }
|
|
|
+ $header[] = "Expect: ";
|
|
|
+ $opts = array(
|
|
|
+ CURLOPT_TIMEOUT => $timeout,
|
|
|
+ CURLOPT_RETURNTRANSFER => 1,
|
|
|
+ CURLOPT_SSL_VERIFYPEER => false,
|
|
|
+ CURLOPT_SSL_VERIFYHOST => false,
|
|
|
+ CURLOPT_HTTPHEADER => $header
|
|
|
+ );
|
|
|
+
|
|
|
+ /* 根据请求类型设置特定参数 */
|
|
|
+ switch (strtoupper($method)) {
|
|
|
+ case 'GET':
|
|
|
+ $opts[CURLOPT_URL] = $url . (empty($params) ? '' : ('?' . http_build_query($params)));
|
|
|
+ break;
|
|
|
+ case 'POST':
|
|
|
+ //$params = http_build_query($params);
|
|
|
+ $opts[CURLOPT_URL] = $url;
|
|
|
+ $opts[CURLOPT_POST] = 1;
|
|
|
+ $opts[CURLOPT_POSTFIELDS] = json_encode($params);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ rlog("[ERR] method " . $method);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ global $ch; //curl长连接
|
|
|
+ if (empty($ch)) {
|
|
|
+ $ch = curl_init();
|
|
|
+ }
|
|
|
+ if (empty($ch)) {
|
|
|
+ rlog("[ERR] curl_init");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $csa = curl_setopt_array($ch, $opts);
|
|
|
+ if (empty($csa)) {
|
|
|
+ rlog("[ERR] curl_setopt_array");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $data = curl_exec($ch);
|
|
|
+ if ($data === false) {
|
|
|
+ rlog("[ERR] curl_exec errno:" . curl_errno($ch) . " " . curl_error($ch));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //unicode转中文
|
|
|
+ $data = decodeUnicode($data);
|
|
|
+ rlog("[HTTP] recv " . $data);
|
|
|
+ //curl_close($ch);
|
|
|
+ return $data;
|
|
|
+}
|
|
|
+function decodeUnicode($str)
|
|
|
+{
|
|
|
+ return preg_replace_callback('/\\\\u([0-9a-f]{4})/i', function ($matches) {
|
|
|
+ return iconv("UCS-2BE", "UTF-8", pack("H*", $matches[1]));
|
|
|
+ }, $str);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// while (true) {
|
|
|
+// try {
|
|
|
+// rlog('INFO', 'task start');
|
|
|
+
|
|
|
+// $infos = app_redis()->hgetall("indoor_inoutres_push");
|
|
|
+// foreach ($infos as $k => $v) {
|
|
|
+// # code...
|
|
|
+// $data = json_decode($v, true);
|
|
|
+// if ( (time() - $data["time"] ) > $offlineInt ) {
|
|
|
+// # code...
|
|
|
+// if ($data["status"] == 1) {
|
|
|
+// # code...
|
|
|
+// // $url="http://localhost:8115/api/accessClassReport";
|
|
|
+// $url="http://61.175.203.188:10001/api/accessClassReport";
|
|
|
+// $url_data = [
|
|
|
+// "mac" => $data["mac"],
|
|
|
+// "data" => [
|
|
|
+// [
|
|
|
+// "label" => $data["id"],
|
|
|
+// "time" => time(),
|
|
|
+// "dirt" => 2,
|
|
|
+// "rssi" => $data["rssi"],
|
|
|
+// "avg" => $data["avg"]
|
|
|
+// ]
|
|
|
+// ]
|
|
|
+// ];
|
|
|
+// http($url, $url_data, [], 'POST');
|
|
|
+// rlog("PUSH INFO","离线推送依赖数据", $v);
|
|
|
+// }
|
|
|
+// app_redis()->hdel('indoor_rfidinfos',$k);;
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+// } catch (\Exception $ex) {
|
|
|
+// rlog("INFO", 'pushhttp',"推送 异常".$ex->getMessage());
|
|
|
+// }
|
|
|
+// $sleepTime = floor($offlineInt/10);
|
|
|
+// if ($sleepTime < 3) {
|
|
|
+// # code...
|
|
|
+// $sleepTime = 3;
|
|
|
+// }
|
|
|
+// sleep($sleepTime); //1分钟遍历一次
|
|
|
+// }
|
|
|
+
|
|
|
+// 正式部分
|
|
|
+while (true) {
|
|
|
+ try {
|
|
|
+
|
|
|
+ if (app_redis() === false) {
|
|
|
+ echo 'redis连接错误!' . PHP_EOL;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $data = app_redis()->lpop('parea_inoutres_push');
|
|
|
+
|
|
|
+ if(!$data){
|
|
|
+ // var_dump($data);
|
|
|
+ echo "redis无数据!",PHP_EOL;
|
|
|
+ sleep(1);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ echo ('取出数据' . $data." TYPE:". gettype($data) . PHP_EOL);
|
|
|
+
|
|
|
+ $url_data = json_decode($data, true);
|
|
|
+
|
|
|
+ $url="http://localhost:8115/api/areaReport";
|
|
|
+
|
|
|
+
|
|
|
+ http($url, $url_data, [], 'POST');
|
|
|
+
|
|
|
+ if($url_data["first_time"]){
|
|
|
+ $camData = [
|
|
|
+ "station" => $url_data["mac"],
|
|
|
+ "list" => [
|
|
|
+ [
|
|
|
+ "label" =>$url_data["id"],
|
|
|
+ "first_time" => $url_data["first_time"],
|
|
|
+ "time" => $url_data["time"]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+
|
|
|
+ $resp = http("http://localhost:8115/api/areaLabelReport", $camData, [], 'POST');
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ rlog("PUSH INFO","推送依赖数据", $data);
|
|
|
+ }catch (\Exception $ex) {
|
|
|
+ rlog("INFO", 'pushhttp',"推送 异常".$ex->getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // sleep(3);
|
|
|
+}
|