Browse Source

Merge pull request #42 from lawrencehj/wvp-28181-2.0

增加报警事件处理功能等
pull/46/head
648540858 4 years ago
committed by GitHub
parent
commit
2c47c8c86b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      README.md
  2. 10
      src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceAlarm.java
  3. 12
      src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
  4. 26
      src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEvent.java
  5. 47
      src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEventListener.java
  6. 40
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
  7. 32
      src/main/java/com/genersoft/iot/vmp/vmanager/SEEController/SEEController.java
  8. 2
      web_src/src/components/ParentPlatformList.vue
  9. 52
      web_src/src/components/UiHeader.vue
  10. 3
      web_src/src/main.js

3
README.md

@ -33,7 +33,8 @@ https://gitee.com/18010473990/wvp-GB28181.git
16. 支持直接输出RTSP、RTMP、HTTP-FLV、Websocket-FLV、HLS多种协议流地址 16. 支持直接输出RTSP、RTMP、HTTP-FLV、Websocket-FLV、HLS多种协议流地址
17. 支持国标网络校时 17. 支持国标网络校时
18. 支持公网部署, 支持wvp与zlm分开部署 18. 支持公网部署, 支持wvp与zlm分开部署
19. 支持播放h265, g.711格式的流(需要将closeWaitRTPInfo设为false). 19. 支持播放h265, g.711格式的流(需要将closeWaitRTPInfo设为false)
20. 报警信息处理,支持向前端推送报警信息
# 2.0 支持特性 # 2.0 支持特性
- [ ] 国标通道向上级联 - [ ] 国标通道向上级联

10
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceAlarm.java

@ -11,7 +11,7 @@ public class DeviceAlarm {
/** /**
* 报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级 警情- * 报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级 警情-
*/ */
private String alarmPriorit; private String alarmPriority;
/** /**
* 报警方式 , 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警, * 报警方式 , 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,
@ -53,12 +53,12 @@ public class DeviceAlarm {
this.deviceId = deviceId; this.deviceId = deviceId;
} }
public String getAlarmPriorit() { public String getAlarmPriority() {
return alarmPriorit; return alarmPriority;
} }
public void setAlarmPriorit(String alarmPriorit) { public void setAlarmPriority(String alarmPriority) {
this.alarmPriorit = alarmPriorit; this.alarmPriority = alarmPriority;
} }
public String getAlarmMethod() { public String getAlarmMethod() {

12
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java

@ -6,6 +6,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEvent;
import com.genersoft.iot.vmp.gb28181.event.offline.OfflineEvent; import com.genersoft.iot.vmp.gb28181.event.offline.OfflineEvent;
import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent; import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent;
@ -53,4 +55,14 @@ public class EventPublisher {
platformNotRegisterEvent.setPlatformGbID(platformGbId); platformNotRegisterEvent.setPlatformGbID(platformGbId);
applicationEventPublisher.publishEvent(platformNotRegisterEvent); applicationEventPublisher.publishEvent(platformNotRegisterEvent);
} }
/**
* 设备报警事件
* @param deviceAlarm
*/
public void deviceAlarmEventPublish(DeviceAlarm deviceAlarm) {
AlarmEvent alarmEvent = new AlarmEvent(this);
alarmEvent.setAlarmInfo(deviceAlarm);
applicationEventPublisher.publishEvent(alarmEvent);
}
} }

26
src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEvent.java

@ -0,0 +1,26 @@
package com.genersoft.iot.vmp.gb28181.event.alarm;
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
import org.springframework.context.ApplicationEvent;
/**
* @description: 报警事件
* @author: lawrencehj
* @data: 2021-01-20
*/
public class AlarmEvent extends ApplicationEvent {
public AlarmEvent(Object source) {
super(source);
}
private DeviceAlarm deviceAlarm;
public DeviceAlarm getAlarmInfo() {
return deviceAlarm;
}
public void setAlarmInfo(DeviceAlarm deviceAlarm) {
this.deviceAlarm = deviceAlarm;
}
}

47
src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEventListener.java

@ -0,0 +1,47 @@
package com.genersoft.iot.vmp.gb28181.event.alarm;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @description: 报警事件监听
* @author: lawrencehj
* @data: 2021-01-20
*/
@Component
public class AlarmEventListener implements ApplicationListener<AlarmEvent> {
private final static Logger logger = LoggerFactory.getLogger(AlarmEventListener.class);
private static SseEmitter emitter = new SseEmitter();
public void addSseEmitters(SseEmitter sseEmitter) {
emitter = sseEmitter;
}
@Override
public void onApplicationEvent(AlarmEvent event) {
if (logger.isDebugEnabled()) {
logger.debug("设备报警事件触发,deviceId:" + event.getAlarmInfo().getDeviceId() + ", "
+ event.getAlarmInfo().getAlarmDescription());
}
try {
String msg = "<strong>设备编码:</strong> <i>" + event.getAlarmInfo().getDeviceId() + "</i>"
+ "<br><strong>报警描述:</strong> <i>" + event.getAlarmInfo().getAlarmDescription() + "</i>"
+ "<br><strong>报警时间:</strong> <i>" + event.getAlarmInfo().getAlarmTime() + "</i>"
+ "<br><strong>定位经度:</strong> <i>" + event.getAlarmInfo().getLongitude() + "</i>"
+ "<br><strong>定位纬度:</strong> <i>" + event.getAlarmInfo().getLatitude() + "</i>";
emitter.send(msg);
} catch (IOException e) {
if (logger.isDebugEnabled()) {
logger.debug("SSE 通道已关闭");
}
// e.printStackTrace();
}
}
}

40
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java

@ -174,7 +174,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
SipUri uri = (SipUri) address.getURI(); SipUri uri = (SipUri) address.getURI();
String platformId = uri.getUser(); String platformId = uri.getUser();
// if (deviceListElement == null) { // 存在DeviceList则为响应 catalog, 不存在DeviceList则为查询请求 // if (deviceListElement == null) { // 存在DeviceList则为响应 catalog, 不存在DeviceList则为查询请求
if (name == "Query") { // 区分是Response——查询响应,还是Query——查询请求 if (name.equalsIgnoreCase("Query")) { // 区分是Response——查询响应,还是Query——查询请求
// TODO 后续将代码拆分 // TODO 后续将代码拆分
ParentPlatform parentPlatform = storager.queryParentPlatById(platformId); ParentPlatform parentPlatform = storager.queryParentPlatById(platformId);
if (parentPlatform == null) { if (parentPlatform == null) {
@ -324,19 +324,41 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
// storager.queryChannel(deviceId) // storager.queryChannel(deviceId)
return; return;
} }
device.setName(XmlUtil.getText(rootElement, "DeviceName"));
device.setManufacturer(XmlUtil.getText(rootElement, "Manufacturer")); DeviceAlarm deviceAlarm = new DeviceAlarm();
device.setModel(XmlUtil.getText(rootElement, "Model")); deviceAlarm.setDeviceId(deviceId);
device.setFirmware(XmlUtil.getText(rootElement, "Firmware")); deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
if (StringUtils.isEmpty(device.getStreamMode())) { deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod"));
device.setStreamMode("UDP"); deviceAlarm.setAlarmTime(XmlUtil.getText(rootElement, "AlarmTime"));
if (XmlUtil.getText(rootElement, "AlarmDescription") == null) {
deviceAlarm.setAlarmDescription("");
} else {
deviceAlarm.setAlarmDescription(XmlUtil.getText(rootElement, "AlarmDescription"));
} }
storager.updateDevice(device); if (XmlUtil.getText(rootElement, "Longitude") == null || XmlUtil.getText(rootElement, "Longitude") == "") {
deviceAlarm.setLongitude(0.00);
} else {
deviceAlarm.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude")));
}
if (XmlUtil.getText(rootElement, "Latitude") == null || XmlUtil.getText(rootElement, "Latitude") =="") {
deviceAlarm.setLatitude(0.00);
} else {
deviceAlarm.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude")));
}
// device.setName(XmlUtil.getText(rootElement, "DeviceName"));
// device.setManufacturer(XmlUtil.getText(rootElement, "Manufacturer"));
// device.setModel(XmlUtil.getText(rootElement, "Model"));
// device.setFirmware(XmlUtil.getText(rootElement, "Firmware"));
// if (StringUtils.isEmpty(device.getStreamMode())) {
// device.setStreamMode("UDP");
// }
// storager.updateDevice(device);
//cmder.catalogQuery(device, null); //cmder.catalogQuery(device, null);
// 回复200 OK // 回复200 OK
responseAck(evt); responseAck(evt);
if (offLineDetector.isOnline(deviceId)) { if (offLineDetector.isOnline(deviceId)) {
publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); publisher.deviceAlarmEventPublish(deviceAlarm);
} }
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
// } catch (DocumentException e) { // } catch (DocumentException e) {

32
src/main/java/com/genersoft/iot/vmp/vmanager/SEEController/SEEController.java

@ -0,0 +1,32 @@
package com.genersoft.iot.vmp.vmanager.SEEController;
import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEventListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
/**
* @description: SSE推送
* @author: lawrencehj
* @data: 2021-01-20
*/
@Controller
@RequestMapping("/api")
public class SEEController {
@Autowired
AlarmEventListener alarmEventListener;
//设置响应
@RequestMapping("/emit")
public SseEmitter emit() {
SseEmitter sseEmitter = new SseEmitter(0L);
try {
alarmEventListener.addSseEmitters(sseEmitter);
}catch (Exception e){
sseEmitter.completeWithError(e);
}
return sseEmitter;
}
}

2
web_src/src/components/ParentPlatformList.vue

@ -137,7 +137,7 @@ export default {
}); });
}, },
chooseChannel: function(platform) { chooseChannel: function(platform) {
this.$refs.chooseChannelDialog.openDialog(platform.deviceGBId, ()=>{ this.$refs.chooseChannelDialog.openDialog(platform.serverGBId, ()=>{
this.initData() this.initData()
}) })
}, },

52
web_src/src/components/UiHeader.vue

@ -4,6 +4,7 @@
<el-menu-item index="/">控制台</el-menu-item> <el-menu-item index="/">控制台</el-menu-item>
<el-menu-item index="/videoList">设备列表</el-menu-item> <el-menu-item index="/videoList">设备列表</el-menu-item>
<el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item> <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item>
<el-switch v-model="alarmNotify" active-text="报警信息推送" style="display: block float: right" @change="sseControl"></el-switch>
<el-menu-item style="float: right;" @click="loginout">退出</el-menu-item> <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item>
</el-menu> </el-menu>
</div> </div>
@ -12,14 +13,63 @@
<script> <script>
export default { export default {
name: "UiHeader", name: "UiHeader",
components: { Notification },
data() {
return {
alarmNotify: true,
sseSource: null,
};
},
methods:{ methods:{
loginout(){ loginout(){
// cookie // cookie
this.$cookies.remove("session"); this.$cookies.remove("session");
this.$router.push('/login'); this.$router.push('/login');
this.sseSource.close();
}, },
beforeunloadHandler() {
this.sseSource.close();
},
sseControl() {
let that = this;
if (this.alarmNotify) {
this.sseSource = new EventSource('/api/emit');
this.sseSource.addEventListener('message', function(evt) {
that.$notify({
title: '收到报警信息',
dangerouslyUseHTMLString: true,
message: evt.data,
type: 'warning'
});
console.log("收到信息:" + evt.data);
});
this.sseSource.addEventListener('open', function(e) {
console.log("SSE连接打开.");
}, false);
this.sseSource.addEventListener('error', function(e) {
if (e.target.readyState == EventSource.CLOSED) {
console.log("SSE连接关闭");
} else {
console.log(e.target.readyState);
}
}, false);
} else {
this.sseSource.removeEventListener('open', null);
this.sseSource.removeEventListener('message', null);
this.sseSource.removeEventListener('error', null);
this.sseSource.close();
} }
} }
},
mounted() {
window.addEventListener('beforeunload', e => this.beforeunloadHandler(e))
// window.addEventListener('unload', e => this.unloadHandler(e))
this.sseControl();
},
destroyed() {
window.removeEventListener('beforeunload', e => this.beforeunloadHandler(e))
// window.removeEventListener('unload', e => this.unloadHandler(e))
},
}
</script> </script>

3
web_src/src/main.js

@ -9,10 +9,13 @@ import VueCookies from 'vue-cookies';
import echarts from 'echarts'; import echarts from 'echarts';
import VueClipboard from 'vue-clipboard2' import VueClipboard from 'vue-clipboard2'
import { Notification } from 'element-ui';
Vue.use(VueClipboard) Vue.use(VueClipboard)
Vue.use(ElementUI); Vue.use(ElementUI);
Vue.use(VueCookies); Vue.use(VueCookies);
Vue.prototype.$axios = axios; Vue.prototype.$axios = axios;
Vue.prototype.$notify = Notification;
axios.defaults.baseURL = (process.env.NODE_ENV === 'development') ? process.env.BASE_API : ""; axios.defaults.baseURL = (process.env.NODE_ENV === 'development') ? process.env.BASE_API : "";

Loading…
Cancel
Save