触发报警信息后,摄像头会把相应的报警信息通过camera_alarm路由键推送到rabbitmq的amq.topic交换机,amq.topic交换机和camera_alarm队列通过camera_alarm路由键绑定,所以最后报警信息会被推送至camera_alarm队列,消费者(后台服务)只需要监听该队列即可。
报警信息的具体内容如下:
{
'id': 200,
'alarm_id': 100,
'status': 0,
'device_id': 1,
'device_name': '森林防⽕',
'device_type': 0,
'device_manufacturer': 1,
'image': '/record/hk_alarm/20201119/image_1_20201119131301.jpg',
'video': '/record/hk_alarm/20201119/video_1_20201119131301.mp4',
'rule_id': 0,
'event_channel': 1,
'fire_max_temperature': '0.00',
'fire_target_distance': 0,
'event_type': 18833,
'event_type_desc': '⽕点检测报警.',
'event_type_ext': 1,
'event_type_ext_desc': '烟雾检测报警.',
'created_at': '2020-11-19 14:09:07',
'updated_at': '2020-11-19 14:09:07'
}
正式环境只能在靖安旅游集散中心内网环境下访问。
本例使用SpringBoot集成RabbitMQ进行测试。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
spring:
rabbitmq:
host: 112.74.89.58
port: 43504
virtual-host: /
# 消息发送到消息队列服务器确认
publisher-confirms: true
# 消息成功发送到队列确认
publisher-returns: true
# 和publisher-returns搭配使用,只要消息抵达队列,以异步发送优先回调publisher-return
template:
mandatory: true
# 手动ack
listener:
simple:
acknowledge-mode: manual
@EnableRabbit
@SpringBootApplication
public class CameraAlarmApplication {
public static void main(String[] args) {
SpringApplication.run(CameraAlarmApplication.class, args);
}
}
根据发生的内容格式封装CameraAlarmMessage
@Data
public class CameraAlarmMessage {
/**
* 99:设备列表、1:结束事件、0:新增事件
* (只需要关注status为0的事件)
*/
private Integer status;
/**
* status为0,1时会有该字段
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime created_at;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updated_at;
/**
* status为99时会有该字段
*/
private String data_count;
/**
* status为99时会有该字段
*/
private Object[] data;
/**
* status为0,1时会有该字段
*/
private Long id;
/**
* 设备id
* status为0,1时会有该字段
*/
private Long device_id;
// == status为0时会有以下字段 ==
/**
* 设备品牌 1:海康、2:大华
*/
private Integer device_manufacturer;
private Long alarm_id;
/**
* 设备名称
*/
private String device_name;
private Integer device_type;
/**
* 图片
*/
private String image;
/**
* 视频
*/
private String video;
private Integer rule_id;
private Integer event_channel;
private String fire_max_temperature;
private String fire_target_distance;
/**
* 事件类型
* 4354:⾏为分析报警信息(海康)、18833:⽕点检测报警(海康)、
* 4391:报告报警上传,注:报警柱(海康)、8591:视频移动侦测事件(大华)、
* 8561:设备请求对⽅发起对讲事件,报警柱(大华)
*/
private Integer event_type;
private String event_type_desc;
/**
* 事件类型
*/
private String event_type_ext;
/**
* 事件类型描述
*/
private String event_type_ext_desc;
}
@Component
@RabbitListener(queues = "camera_alarm") // 监听 camera_alarm 队列
public class CameraAlarmListener {
// 本例使用ObjectMapper把json格式的数据转换成实体类
public static final ObjectMapper mapper = new ObjectMapper();
static {
JavaTimeModule javaTimeModule = new JavaTimeModule();
// LocalDateTime 日期支持
javaTimeModule.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
mapper.registerModule(javaTimeModule);
mapper.setTimeZone(TimeZone.getDefault());
}
@RabbitHandler
public void listener(Object data, Channel channel, Message message) throws IOException {
try {
// 警告信息
String body = new String(message.getBody(), Charset.forName("utf-8"));
// json数据转换成实体类
CameraAlarmMessage cameraAlarmMessage = mapper.readValue(body, CameraAlarmMessage.class);
// 根据图例,status为0时表示新增事件
if (0 == cameraAlarmMessage.getStatus().intValue()) {
// 打印事件信息
System.out.println("==============");
System.out.println(cameraAlarmMessage.toString());
System.out.println("==============");
// TODO 具体业务操作
}
// 手动 ack
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
} catch (Exception e) {
// 发生异常直接 reject
channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);
}
}
}