648540858
2021-01-21 2c47c8c86b0a685e92b0a605ae6f96901cf10555
Merge pull request #42 from lawrencehj/wvp-28181-2.0

增加报警事件处理功能等
7个文件已修改
3个文件已添加
235 ■■■■■ 已修改文件
README.md 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceAlarm.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEvent.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEventListener.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/vmanager/SEEController/SEEController.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web_src/src/components/ParentPlatformList.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
web_src/src/components/UiHeader.vue 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web_src/src/main.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -33,7 +33,8 @@
16. 支持直接输出RTSP、RTMP、HTTP-FLV、Websocket-FLV、HLS多种协议流地址  
17. 支持国标网络校时  
18. 支持公网部署, 支持wvp与zlm分开部署   
19. 支持播放h265, g.711格式的流(需要将closeWaitRTPInfo设为false).
19. 支持播放h265, g.711格式的流(需要将closeWaitRTPInfo设为false)
20. 报警信息处理,支持向前端推送报警信息
# 2.0 支持特性 
- [ ] 国标通道向上级联  
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceAlarm.java
@@ -11,7 +11,7 @@
    /**
     * 报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级 警情-
     */
    private String alarmPriorit;
    private String alarmPriority;
    /**
     * 报警方式 , 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,
@@ -53,12 +53,12 @@
        this.deviceId = deviceId;
    }
    public String getAlarmPriorit() {
        return alarmPriorit;
    public String getAlarmPriority() {
        return alarmPriority;
    }
    public void setAlarmPriorit(String alarmPriorit) {
        this.alarmPriorit = alarmPriorit;
    public void setAlarmPriority(String alarmPriority) {
        this.alarmPriority = alarmPriority;
    }
    public String getAlarmMethod() {
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
@@ -6,6 +6,8 @@
import org.springframework.context.ApplicationEventPublisher;
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.online.OnlineEvent;
@@ -52,5 +54,15 @@
        PlatformNotRegisterEvent platformNotRegisterEvent = new PlatformNotRegisterEvent(this);
        platformNotRegisterEvent.setPlatformGbID(platformGbId);
        applicationEventPublisher.publishEvent(platformNotRegisterEvent);
    }
    }
    /**
     * 设备报警事件
     * @param deviceAlarm
     */
    public void deviceAlarmEventPublish(DeviceAlarm deviceAlarm) {
        AlarmEvent alarmEvent = new AlarmEvent(this);
        alarmEvent.setAlarmInfo(deviceAlarm);
        applicationEventPublisher.publishEvent(alarmEvent);
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEvent.java
New file
@@ -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;
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEventListener.java
New file
@@ -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();
        }
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -174,7 +174,7 @@
            SipUri uri = (SipUri) address.getURI();
            String platformId = uri.getUser();
            // if (deviceListElement == null) { // 存在DeviceList则为响应 catalog, 不存在DeviceList则为查询请求
            if (name == "Query") { // 区分是Response——查询响应,还是Query——查询请求
            if (name.equalsIgnoreCase("Query")) { // 区分是Response——查询响应,还是Query——查询请求
                    // TODO 后续将代码拆分
                ParentPlatform parentPlatform = storager.queryParentPlatById(platformId);
                if (parentPlatform == null) {
@@ -324,19 +324,41 @@
                // storager.queryChannel(deviceId)
                return;
            }
            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");
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setDeviceId(deviceId);
            deviceAlarm.setAlarmPriority(XmlUtil.getText(rootElement, "AlarmPriority"));
            deviceAlarm.setAlarmMethod(XmlUtil.getText(rootElement, "AlarmMethod"));
            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);
            // 回复200 OK
            responseAck(evt);
            if (offLineDetector.isOnline(deviceId)) {
                publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
                publisher.deviceAlarmEventPublish(deviceAlarm);
            }
        } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
            // } catch (DocumentException e) {
src/main/java/com/genersoft/iot/vmp/vmanager/SEEController/SEEController.java
New file
@@ -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;
    }
}
web_src/src/components/ParentPlatformList.vue
@@ -137,7 +137,7 @@
            });
    },
    chooseChannel: function(platform) {
       this.$refs.chooseChannelDialog.openDialog(platform.deviceGBId, ()=>{
       this.$refs.chooseChannelDialog.openDialog(platform.serverGBId, ()=>{
         this.initData()
       })
    },
web_src/src/components/UiHeader.vue
@@ -3,7 +3,8 @@
        <el-menu router :default-active="this.$route.path" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" mode="horizontal">
            <el-menu-item index="/">控制台</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>
    </div>
@@ -12,14 +13,63 @@
<script>
export default {
    name: "UiHeader",
    components: { Notification },
    data() {
        return {
            alarmNotify: true,
            sseSource: null,
        };
    },
    methods:{
          loginout(){
            // 删除cookie,回到登录页面
            this.$cookies.remove("session");
            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>
web_src/src/main.js
@@ -9,10 +9,13 @@
import echarts from 'echarts';
import VueClipboard from 'vue-clipboard2'
import { Notification } from 'element-ui';
Vue.use(VueClipboard)
Vue.use(ElementUI);
Vue.use(VueCookies);
Vue.prototype.$axios = axios;
Vue.prototype.$notify = Notification;
axios.defaults.baseURL = (process.env.NODE_ENV === 'development') ? process.env.BASE_API : "";