NoticeAction.class.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <?php
  2. class NoticeAction extends Action {
  3. public function jgpush( ){
  4. $app_key = '58e15e345e0c21b7e638e186';
  5. $master_secret = 'a91d0b1c1fa1b327db832506';
  6. $client = new \JPush\Client($app_key, $master_secret);
  7. $push_payload = $client->push()
  8. ->setPlatform('all')
  9. ->addAllAudience()
  10. ->setNotificationAlert('车辆异动告警');
  11. try {
  12. $response = $push_payload->send();
  13. print_r($response);
  14. } catch (\JPush\Exceptions\APIConnectionException $e) {
  15. // try something here
  16. print $e;
  17. } catch (\JPush\Exceptions\APIRequestException $e) {
  18. // try something here
  19. print $e;
  20. }
  21. }
  22. public function pushFromKafka( ){
  23. $conf = new RdKafka\Conf();
  24. // Set a rebalance callback to log partition assignments (optional)(当有新的消费进程加入或者退出消费组时,kafka 会自动重新分配分区给消费者进程,这里注册了一个回调函数,当分区被重新分配时触发)
  25. $conf->setRebalanceCb(function (RdKafka\KafkaConsumer $kafka, $err, array $partitions = null) {
  26. switch ($err) {
  27. case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS:
  28. echo "Assign: ";
  29. var_dump($partitions);
  30. $kafka->assign($partitions);
  31. break;
  32. case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS:
  33. echo "Revoke: ";
  34. var_dump($partitions);
  35. $kafka->assign(NULL);
  36. break;
  37. default:
  38. throw new \Exception($err);
  39. }
  40. });
  41. // Configure the group.id. All consumer with the same group.id will consume( 配置groud.id 具有相同 group.id 的consumer 将会处理不同分区的消息,所以同一个组内的消费者数量如果订阅了一个topic, 那么消费者进程的数量多于这个topic 分区的数量是没有意义的。)
  42. // different partitions.
  43. $conf->set('group.id', 'myConsumerGroup');
  44. // Initial list of Kafka brokers(添加 kafka集群服务器地址)
  45. $conf->set('metadata.broker.list', '127.0.0.1');
  46. $topicConf = new RdKafka\TopicConf();
  47. // Set where to start consuming messages when there is no initial offset in
  48. // offset store or the desired offset is out of range.
  49. // 'smallest': start from the beginning
  50. $topicConf->set('auto.offset.reset', 'smallest');
  51. // Set the configuration to use for subscribed/assigned topics
  52. $conf->setDefaultTopicConf($topicConf);
  53. $consumer = new RdKafka\KafkaConsumer($conf);
  54. // 消费者订阅
  55. $consumer->subscribe(['gps_alarm_msg_queue']);
  56. while (true) {
  57. $message = $consumer->consume(120*1000);
  58. switch ($message->err) {
  59. case RD_KAFKA_RESP_ERR_NO_ERROR:
  60. $msg_data = json_decode($message->payload,true);
  61. if($msg_data){
  62. // 使用极光推送消息
  63. $jpush_client = new \JPush\Client( C('JPUSH_APP_KEY'), C('JPUSH_MASTER_SECRET') );
  64. // 电子围栏告警,上锁车辆异动告警,低电量告警,被盗告警,广播消息推送
  65. $this->jpushMsg( $jpush_client, $msg_data );
  66. }
  67. break;
  68. case RD_KAFKA_RESP_ERR__PARTITION_EOF:
  69. echo "No more messages; will wait for more\n";
  70. break;
  71. case RD_KAFKA_RESP_ERR__TIMED_OUT:
  72. echo "Timed out\n";
  73. break;
  74. default:
  75. throw new \Exception($message->errstr(), $message->err);
  76. break;
  77. }
  78. }
  79. }
  80. public function jpushMsg( $client, $msg_data ){
  81. /*
  82. $msg_data = '{
  83. "type":2,
  84. "title":"被盗告警",
  85. "content":"车被偷了,赶紧去找",
  86. "device_number":"FFFFFF123122"
  87. }';
  88. $msg_data = '{
  89. "type":9,
  90. "title":"群推消息",
  91. "content":"这是一个广播"
  92. }';
  93. */
  94. $single_push_type = array(
  95. C('OUTAGE_ALARM'), // 1-断电报警
  96. C('SOS_ALARM'), // 2-SOS报警
  97. C('LOWWER_BATTERY_ALARM'), // 3-低电量告警
  98. C('SHAKE_ALARM'), // 4-震动报警
  99. C('SHIFT_ALARM'), // 5-位移报警
  100. C('LOCK_VEHICLE_ALARM'), // 6-锁车告警
  101. C('STOLEN_ALARM'), // 7-被盗告警
  102. C('FENCE_ALARM'), // 8-电子围栏告警
  103. );
  104. if(!is_array($msg_data)){
  105. echo 'invalid message data format!'.$msg_data . PHP_EOL;
  106. return;
  107. }
  108. // 通过传过来的车牌查出 JgClientRegistrationId
  109. if( empty($client) ){
  110. $client = new \JPush\Client( C('JPUSH_APP_KEY'), C('JPUSH_MASTER_SECRET') );
  111. }
  112. if( in_array($msg_data['type'],$single_push_type) && $msg_data['device_number'] ){
  113. // 判断是否在围栏告警时间间隔内
  114. if( C('FENCE_ALARM_INTERVAL') && $msg_data['type'] == C('FENCE_ALARM') ){
  115. $last_alarm_time = S('last_fence_alarm_'.$msg_data['device_number']);
  116. $interval_time = C('FENCE_ALARM_INTERVAL')*60;
  117. if( time() - $last_alarm_time < $interval_time ){
  118. echo $msg_data['device_number'] . ' 围栏告警时间间隔:'.C('FENCE_ALARM_INTERVAL').'分钟,最后一次告警时间:'.$last_alarm_time . PHP_EOL;
  119. return;
  120. }
  121. }
  122. // 取车辆数据
  123. $where = array('DeviceNumber|GpsDeviceNumber' => $msg_data['device_number']);
  124. $fields= 'CityId,LicensePlate,FullName,JgClientRegistrationId';
  125. if( !S( 'jpush_vinfo_'.$msg_data['device_number'] ) ){ //如果不存在,则缓存
  126. $vehicle_info = M('jms_vehicle')->field($fields)->where($where)->find();
  127. S( 'jpush_vinfo_'.$msg_data['device_number'], $vehicle_info, 60 ); //缓存1分钟
  128. }
  129. $vehicle_info = S( 'jpush_vinfo_'.$msg_data['device_number'] ); //从缓存取
  130. }elseif( $msg_data['type'] == C('BROADCASTING') ){
  131. //广播
  132. }else{
  133. echo '未知的告警类型:'.$msg_data['type'].PHP_EOL;
  134. return;
  135. }
  136. // 推送平台
  137. $platform = array('ios', 'android');
  138. // 通知栏显示内容
  139. $alert = $msg_data['content'];
  140. // 推送android
  141. $android_notification = array(
  142. 'title' => $msg_data['title'],
  143. 'builder_id' => 2, //通知栏样式
  144. );
  145. // 推送ios
  146. $ios_notification = array(
  147. 'sound' => 'default',
  148. 'badge' => '+1',
  149. 'content-available' => true
  150. );
  151. // 可选项
  152. $options = array(
  153. 'sendno' => 100,
  154. 'time_to_live' => 100,
  155. );
  156. // 组装推送
  157. $cid = $client->push()->getCid();
  158. //var_dump($cid['body']['cidlist'][0]);
  159. $push_payload = $client->push()
  160. ->setCid($cid['body']['cidlist'][0])
  161. ->setPlatform( $platform )
  162. ->iosNotification($alert, $ios_notification)
  163. ->androidNotification($alert, $android_notification)
  164. ->options($options);
  165. if( $msg_data['type'] == C('BROADCASTING') ){ // 9-广播
  166. $push_payload->addAllAudience();
  167. }elseif( isset($vehicle_info) && $vehicle_info ){ // 单推
  168. $msg_data['vehicle_info'] = $vehicle_info;
  169. $push_payload->addRegistrationId($vehicle_info['JgClientRegistrationId']);
  170. }else{
  171. //未知类型
  172. var_dump('出错了:'.$msg_data);
  173. return;
  174. }
  175. try {
  176. $response = $push_payload->send();
  177. // 保存日志
  178. $msg_data['response'] = array(
  179. 'code' => $response['http_code'],
  180. 'resp_msg' => 'ok',
  181. );
  182. $this->saveLog($msg_data);
  183. print_r($response);
  184. if( $response['http_code'] == 200 ){ //如果成功了
  185. if( C('FENCE_ALARM_INTERVAL') && $msg_data['type'] == C('FENCE_ALARM') ){
  186. //设置最后围栏告警时间缓存
  187. S('last_fence_alarm_'.$msg_data['device_number'], time(), C('FENCE_ALARM_INTERVAL')*60);
  188. }
  189. }
  190. } catch (\JPush\Exceptions\APIConnectionException $e) {
  191. // try something here
  192. $msg_data['response'] = array(
  193. 'code' => $e->getHttpCode(),
  194. 'resp_msg' => substr($e->__toString(), strpos($e->__toString(),'[')),
  195. );
  196. $this->saveLog($msg_data);
  197. print $e;
  198. } catch (\JPush\Exceptions\APIRequestException $e) {
  199. // try something here
  200. $msg_data['response'] = array(
  201. 'code' => $e->getHttpCode(),
  202. 'resp_msg' => substr($e->__toString(), strpos($e->__toString(),'[')),
  203. );
  204. $this->saveLog($msg_data);
  205. print $e;
  206. }
  207. }
  208. public function saveLog( $msg_data ){
  209. $fdls_app_message = M('jms_baojing_message');
  210. $log_data = array(
  211. 'ID' => create_guid(),
  212. 'Type' => $msg_data['type'],
  213. 'Title' => $msg_data['title'],
  214. 'Comment' => $msg_data['content'],
  215. 'SendStatus' => $msg_data['response']['code'],
  216. 'AddTime' => date('Y-m-d H:i:s'),
  217. 'RespMsg' => $msg_data['response']['resp_msg'],
  218. );
  219. if( $msg_data['type'] != C('BROADCASTING') ){ // 非广播
  220. $log_data['CityId'] = $msg_data['vehicle_info']['CityId'];
  221. $log_data['DeviceNumber'] = $msg_data['device_number'];
  222. $log_data['FullName'] = $msg_data['vehicle_info']['FullName'];
  223. $log_data['LicensePlate'] = $msg_data['vehicle_info']['LicensePlate'];
  224. }
  225. $result = $fdls_app_message->createAdd($log_data);
  226. return $result;
  227. }
  228. }