648540858
2021-11-05 f1217682a9d1726b5b5673343dfe9b035e1180d4
重构28181信令结构,解决循环依赖导致的无法直接注入
39个文件已修改
4个文件已添加
1 文件已重命名
18个文件已删除
3934 ■■■■■ 已修改文件
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/SipDeviceRunner.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/bean/MobilePosition.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java 243 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/CheckForAllRecordsThread.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/SIPResponseProcessorAbstract.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/ITimeoutProcessor.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/impl/TimeoutProcessorImpl.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/SIPRequestAbstractProcessor.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java 478 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java 1177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/NotifyRequestProcessor.java 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/utils/redis/JedisUtil.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -1,7 +1,7 @@
package com.genersoft.iot.vmp.common;
/**    
 * @Description: 定义常量
 * @description: 定义常量
 * @author: swwheihei
 * @date:   2019年5月30日 下午3:04:04   
 *   
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
@@ -16,7 +16,7 @@
import redis.clients.jedis.JedisPoolConfig;
/**
 * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
 * @description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
 * @author: swwheihei
 * @date: 2019年5月30日 上午10:58:25
 * 
src/main/java/com/genersoft/iot/vmp/conf/SipDeviceRunner.java
@@ -32,5 +32,7 @@
        for (String deviceId : onlineForAll) {
            storager.online(deviceId);
        }
        // TODO 查询在线设备那些开启了订阅,为设备开启定时的目录订阅
    }
}
src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java
@@ -4,7 +4,7 @@
import org.springframework.context.annotation.Configuration;
/**    
 * @Description: 获取数据库配置
 * @description: 获取数据库配置
 * @author: swwheihei
 * @date:   2020年5月6日 下午2:46:00     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -1,19 +1,10 @@
package com.genersoft.iot.vmp.gb28181;
import java.text.ParseException;
import java.util.Properties;
import java.util.TooManyListenersException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.sip.*;
import javax.sip.header.CallIdHeader;
import javax.sip.header.Header;
import javax.sip.message.Response;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
import gov.nist.javax.sip.SipProviderImpl;
import gov.nist.javax.sip.SipStackImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -21,14 +12,15 @@
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory;
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
import gov.nist.javax.sip.SipStackImpl;
import javax.sip.*;
import java.util.Properties;
import java.util.TooManyListenersException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Component
public class SipLayer implements SipListener {
public class SipLayer{
    private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
@@ -36,7 +28,7 @@
    private SipConfig sipConfig;
    @Autowired
    private SIPProcessorFactory processorFactory;
    private SIPProcessorObserver sipProcessorObserver;
    @Autowired
    private SipSubscribe sipSubscribe;
@@ -50,19 +42,16 @@
     */
    private ThreadPoolExecutor processThreadPool;
    @Bean("initSipServer")
    private ThreadPoolExecutor initSipServer() {
    public SipLayer() {
        int processThreadNum = Runtime.getRuntime().availableProcessors() * 10;
        LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<>(10000);
        processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum,
                0L,TimeUnit.MILLISECONDS,processQueue,
                new ThreadPoolExecutor.CallerRunsPolicy());
        return processThreadPool;
    }
    @Bean("sipFactory")
    @DependsOn("initSipServer")
    private SipFactory createSipFactory() {
        sipFactory = SipFactory.getInstance();
        sipFactory.setPathName("gov.nist");
@@ -70,7 +59,7 @@
    }
    
    @Bean("sipStack")
    @DependsOn({"initSipServer", "sipFactory"})
    @DependsOn({"sipFactory"})
    private SipStack createSipStack() throws PeerUnavailableException {
        Properties properties = new Properties();
        properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
@@ -96,7 +85,7 @@
        try {
            tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "TCP");
            tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint);
            tcpSipProvider.addSipListener(this);
            tcpSipProvider.addSipListener(sipProcessorObserver);
            logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getPort() + "}");
        } catch (TransportNotSupportedException e) {
            e.printStackTrace();
@@ -119,8 +108,7 @@
        try {
            udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getPort(), "UDP");
            udpSipProvider = (SipProviderImpl)sipStack.createSipProvider(udpListeningPoint);
            udpSipProvider.addSipListener(this);
//            udpSipProvider.setAutomaticDialogSupportEnabled(false);
            udpSipProvider.addSipListener(sipProcessorObserver);
        } catch (TransportNotSupportedException e) {
            e.printStackTrace();
        } catch (InvalidArgumentException e) {
@@ -133,142 +121,6 @@
        }
        logger.info("Sip Server UDP 启动成功 port [" + sipConfig.getMonitorIp() + ":" + sipConfig.getPort() + "]");
        return udpSipProvider;
    }
    /**
     * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a
     * new request arrives.
     */
    @Override
    public void processRequest(RequestEvent evt) {
        logger.debug(evt.getRequest().toString());
        // 由于jainsip是单线程程序,为提高性能并发处理
        processThreadPool.execute(() -> {
            if (processorFactory != null) {
                processorFactory.createRequestProcessor(evt).process();
            }
        });
    }
    @Override
    public void processResponse(ResponseEvent evt) {
        Response response = evt.getResponse();
        logger.debug(evt.getResponse().toString());
        int status = response.getStatusCode();
        if (((status >= 200) && (status < 300)) || status == 401) { // Success!
            ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
            try {
                processor.process(evt, this, sipConfig);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) {
                CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
                if (callIdHeader != null) {
                    SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId());
                    if (subscribe != null) {
                        SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(evt);
                        subscribe.response(eventResult);
                    }
                }
            }
        } else if ((status >= 100) && (status < 200)) {
            // 增加其它无需回复的响应,如101、180等
        } else {
            logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/);
            if (evt.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0 ) {
                CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
                if (callIdHeader != null) {
                    SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId());
                    if (subscribe != null) {
                        SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(evt);
                        subscribe.response(eventResult);
                    }
                }
            }
        }
    }
    /**
     * <p>
     * Title: processTimeout
     * </p>
     * <p>
     * Description:
     * </p>
     *
     * @param timeoutEvent
     */
    @Override
    public void processTimeout(TimeoutEvent timeoutEvent) {
        // TODO Auto-generated method stub
        CallIdHeader callIdHeader = timeoutEvent.getClientTransaction().getDialog().getCallId();
        String callId = callIdHeader.getCallId();
        SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
        SipSubscribe.EventResult<TimeoutEvent> timeoutEventEventResult = new SipSubscribe.EventResult<>(timeoutEvent);
        errorSubscribe.response(timeoutEventEventResult);
    }
    /**
     * <p>
     * Title: processIOException
     * </p>
     * <p>
     * Description:
     * </p>
     *
     * @param exceptionEvent
     */
    @Override
    public void processIOException(IOExceptionEvent exceptionEvent) {
        // TODO Auto-generated method stub
    }
    /**
     * <p>
     * Title: processTransactionTerminated
     * </p>
     * <p>
     * Description:
     * </p>
     *
     * @param transactionTerminatedEvent
     */
    @Override
    public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
        // TODO Auto-generated method stub
//        CallIdHeader callIdHeader = transactionTerminatedEvent.getClientTransaction().getDialog().getCallId();
//        String callId = callIdHeader.getCallId();
//        SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
//        SipSubscribe.EventResult<TransactionTerminatedEvent> eventResult = new SipSubscribe.EventResult<>(transactionTerminatedEvent);
//        errorSubscribe.response(eventResult);
    }
    /**
     * <p>
     * Title: processDialogTerminated
     * </p>
     * <p>
     * Description:
     * </p>
     *
     * @param dialogTerminatedEvent
     */
    @Override
    public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
        // TODO Auto-generated method stub
//        CallIdHeader callIdHeader = dialogTerminatedEvent.getDialog().getCallId();
//        String callId = callIdHeader.getCallId();
//        SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
//        SipSubscribe.EventResult<DialogTerminatedEvent> eventResult = new SipSubscribe.EventResult<>(dialogTerminatedEvent);
//        errorSubscribe.response(eventResult);
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
@@ -9,7 +9,7 @@
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
/**    
 * @Description:注册逻辑处理,当设备注册后触发逻辑。
 * @description:注册逻辑处理,当设备注册后触发逻辑。
 * @author: swwheihei
 * @date:   2020年5月8日 下午9:41:46     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -109,6 +109,11 @@
     */
    private String charset ;
    /**
     * 目录订阅周期,0为不订阅
     */
    private int subscribeCycleForCatalog ;
    public String getDeviceId() {
@@ -270,4 +275,12 @@
    public void setCharset(String charset) {
        this.charset = charset;
    }
    public int getSubscribeCycleForCatalog() {
        return subscribeCycleForCatalog;
    }
    public void setSubscribeCycleForCatalog(int subscribeCycleForCatalog) {
        this.subscribeCycleForCatalog = subscribeCycleForCatalog;
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/MobilePosition.java
@@ -1,7 +1,7 @@
package com.genersoft.iot.vmp.gb28181.bean;
/**
 * @Description: 移动位置bean
 * @description: 移动位置bean
 * @author: lawrencehj
 * @date: 2021年1月23日
 */
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java
@@ -6,7 +6,7 @@
import java.util.List;
/**    
 * @Description:设备录像信息bean
 * @description:设备录像信息bean
 * @author: swwheihei
 * @date:   2020年5月8日 下午2:05:56     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java
@@ -8,7 +8,7 @@
import java.util.Date;
/**
 * @Description:设备录像bean
 * @description:设备录像bean
 * @author: swwheihei
 * @date:   2020年5月8日 下午2:06:54     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java
@@ -7,7 +7,7 @@
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
/**    
 * @Description:设备离在线状态检测器,用于检测设备状态
 * @description:设备离在线状态检测器,用于检测设备状态
 * @author: swwheihei
 * @date:   2020年5月13日 下午2:40:29     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
@@ -13,7 +13,7 @@
import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent;
/**    
 * @Description:Event事件通知推送器,支持推送在线事件、离线事件
 * @description:Event事件通知推送器,支持推送在线事件、离线事件
 * @author: swwheihei
 * @date:   2020年5月6日 上午11:30:50     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepaliveTimeoutListenerForPlatform.java
@@ -12,7 +12,7 @@
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
/**    
 * @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
 * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
 * @author: swwheihei
 * @date:   2020年5月6日 上午11:35:46     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java
@@ -12,7 +12,7 @@
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
/**    
 * @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
 * @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
 * @author: swwheihei
 * @date:   2020年5月6日 上午11:35:46     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java
@@ -3,7 +3,7 @@
import org.springframework.context.ApplicationEvent;
/**    
 * @Description: 离线事件类
 * @description: 离线事件类
 * @author: swwheihei
 * @date:   2020年5月6日 上午11:33:13     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java
@@ -11,8 +11,8 @@
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
/**
 * @Description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源:
 *               1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor}
 * @description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源:
 *               1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor}
 *               2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener}
 * @author: swwheihei
 * @date: 2020年5月6日 下午1:51:23
@@ -54,5 +54,8 @@
        // 处理离线监听
        storager.outline(event.getDeviceId());
        // TODO 离线取消订阅
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java
@@ -4,7 +4,7 @@
import org.springframework.context.ApplicationEvent;
/**    
 * @Description: 在线事件类
 * @description: 在线事件类
 * @author: swwheihei
 * @date:   2020年5月6日 上午11:32:56     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java
@@ -13,12 +13,11 @@
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * @Description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源:
 *               1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor}
 *               2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor}
 * @description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源:
 *               1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor}
 *               2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.MessageRequestProcessor}
 * @author: swwheihei
 * @date: 2020年5月6日 下午1:51:23
 */
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformKeepaliveExpire/PlatformKeepaliveExpireEventLister.java
@@ -18,7 +18,7 @@
import javax.sip.message.Response;
/**
 * @Description: 平台心跳超时事件
 * @description: 平台心跳超时事件
 * @author: panll
 * @date: 2020年11月5日 10:00
 */
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
@@ -19,7 +19,7 @@
import java.util.*;
/**
 * @Description: 平台未注册事件,来源有二:
 * @description: 平台未注册事件,来源有二:
 *               1、平台新添加
 *               2、平台心跳超时
 * @author: panll
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
@@ -15,7 +15,7 @@
import org.springframework.stereotype.Component;
/**    
 * @Description:视频流session管理器,管理视频预览、预览回放的通信句柄
 * @description:视频流session管理器,管理视频预览、预览回放的通信句柄
 * @author: swwheihei
 * @date:   2020年5月13日 下午4:03:02     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
New file
@@ -0,0 +1,113 @@
package com.genersoft.iot.vmp.gb28181.transmit;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.event.response.ISIPResponseProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.sip.*;
import javax.sip.header.CSeqHeader;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
 * @description: SIP信令处理类观察者
 * @author: panlinlin
 * @date:   2021年11月5日 下午15:32
 */
@Component
public class SIPProcessorObserver implements SipListener {
    private final static Logger logger = LoggerFactory.getLogger(SIPProcessorObserver.class);
    private static Map<String, ISIPRequestProcessor> requestProcessorMap = new ConcurrentHashMap<>();
    private static Map<String, ISIPResponseProcessor> responseProcessorMap = new ConcurrentHashMap<>();
    private static ITimeoutProcessor timeoutProcessor;
    /**
     * 添加 request订阅
     * @param method 方法名
     * @param processor 处理程序
     */
    public void addRequestProcessor(String method, ISIPRequestProcessor processor) {
        requestProcessorMap.put(method, processor);
    }
    /**
     * 添加 response订阅
     * @param method 方法名
     * @param processor 处理程序
     */
    public void addResponseProcessor(String method, ISIPResponseProcessor processor) {
        responseProcessorMap.put(method, processor);
    }
    /**
     * 添加 超时事件订阅
     * @param processor 处理程序
     */
    public void addTimeoutProcessor(ITimeoutProcessor processor) {
        this.timeoutProcessor = processor;
    }
    /**
     * 分发RequestEvent事件
     * @param requestEvent RequestEvent事件
     */
    @Override
    public void processRequest(RequestEvent requestEvent) {
        String method = requestEvent.getRequest().getMethod();
        ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method);
        if (sipRequestProcessor == null) {
            logger.warn("不支持方法{}的request", method);
            return;
        }
        requestProcessorMap.get(requestEvent.getRequest().getMethod()).process(requestEvent);
    }
    /**
     * 分发ResponseEvent事件
     * @param responseEvent responseEvent事件
     */
    @Override
    public void processResponse(ResponseEvent responseEvent) {
        CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME);
        String method = cseqHeader.getMethod();
        ISIPResponseProcessor sipRequestProcessor = responseProcessorMap.get(method);
        if (sipRequestProcessor == null) {
            logger.warn("不支持方法{}的response", method);
            return;
        }
        sipRequestProcessor.process(responseEvent);
    }
    /**
     * 向超时订阅发送消息
     * @param timeoutEvent timeoutEvent事件
     */
    @Override
    public void processTimeout(TimeoutEvent timeoutEvent) {
        if(timeoutProcessor != null) {
            timeoutProcessor.process(timeoutEvent);
        }
    }
    @Override
    public void processIOException(IOExceptionEvent exceptionEvent) {
    }
    @Override
    public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
    }
    @Override
    public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/CheckForAllRecordsThread.java
@@ -7,7 +7,7 @@
import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.MessageRequestProcessor;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import org.slf4j.Logger;
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
@@ -11,7 +11,7 @@
import org.springframework.web.context.request.async.DeferredResult;
/**    
 * @Description: 异步请求处理
 * @description: 异步请求处理
 * @author: swwheihei
 * @date:   2020年5月8日 下午7:59:05     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java
@@ -1,7 +1,7 @@
package com.genersoft.iot.vmp.gb28181.transmit.callback;
/**    
 * @Description: 请求信息定义
 * @description: 请求信息定义
 * @author: swwheihei
 * @date:   2020年5月8日 下午1:09:18     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -7,7 +7,7 @@
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
/**    
 * @Description:设备能力接口,用于定义设备的控制、查询能力
 * @description:设备能力接口,用于定义设备的控制、查询能力
 * @author: swwheihei
 * @date:   2020年5月3日 下午9:16:34     
 */
@@ -299,4 +299,11 @@
     * @return                true = 命令发送成功
     */
    boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime);
    /**
     * 订阅、取消订阅目录信息
     * @param device        视频设备
     * @return                true = 命令发送成功
     */
    boolean catalogSubscribe(Device device, SipSubscribe.Event okEvent ,SipSubscribe.Event errorEvent);
}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -19,7 +19,7 @@
import java.util.UUID;
/**
 * @Description: 平台命令request创造器 TODO 冗余代码太多待优化
 * @description: 平台命令request创造器 TODO 冗余代码太多待优化
 * @author: panll
 * @date: 2020年5月6日 上午9:29:02
 */
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
@@ -18,7 +18,7 @@
import com.genersoft.iot.vmp.gb28181.bean.Device;
/**
 * @Description:摄像头命令request创造器 TODO 冗余代码太多待优化
 * @description:摄像头命令request创造器 TODO 冗余代码太多待优化
 * @author: swwheihei
 * @date: 2020年5月6日 上午9:29:02
 */
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -1,20 +1,17 @@
package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.util.HashSet;
import javax.sip.*;
import javax.sip.address.SipURI;
import javax.sip.header.CallIdHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.Request;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.conf.UserSetup;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
import com.genersoft.iot.vmp.media.zlm.*;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
@@ -29,20 +26,20 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
import org.springframework.util.StringUtils;
import javax.sip.*;
import javax.sip.address.SipURI;
import javax.sip.header.CallIdHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.Request;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.util.HashSet;
/**    
 * @Description:设备能力接口,用于定义设备的控制、查询能力
 * @description:设备能力接口,用于定义设备的控制、查询能力
 * @author: swwheihei
 * @date:   2020年5月3日 下午9:22:48     
 */
@@ -55,12 +52,10 @@
    @Autowired
    private SipConfig sipConfig;
    @Lazy
    @Autowired
    @Qualifier(value="tcpSipProvider")
    private SipProviderImpl tcpSipProvider;
    @Lazy
    @Autowired
    @Qualifier(value="udpSipProvider")
    private SipProviderImpl udpSipProvider;
@@ -89,11 +84,6 @@
    @Autowired
    private IMediaServerService mediaServerService;
    private SIPDialog dialog;
    public SipConfig getSipConfig() {
        return sipConfig;
    }
    /**
     * 云台方向放控制,使用配置文件中的默认镜头移动速度
@@ -1490,6 +1480,33 @@
        }
    }
    @Override
    public boolean catalogSubscribe(Device device, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) {
        try {
            StringBuffer cmdXml = new StringBuffer(200);
            cmdXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
            cmdXml.append("<Query>\r\n");
            cmdXml.append("<CmdType>CataLog</CmdType>\r\n");
            cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
            cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
            cmdXml.append("</Query>\r\n");
            String tm = Long.toString(System.currentTimeMillis());
            CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
                    : udpSipProvider.getNewCallId();
            Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), "z9hG4bK-viaPos-" + tm, "fromTagPos" + tm, null, device.getSubscribeCycleForCatalog(), "presence" , callIdHeader);
            transmitRequest(device, request, errorEvent, okEvent);
            return true;
        } catch ( NumberFormatException | ParseException | InvalidArgumentException    | SipException e) {
            e.printStackTrace();
            return false;
        }
    }
    private ClientTransaction transmitRequest(Device device, Request request) throws SipException {
        return transmitRequest(device, request, null, null);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/SIPResponseProcessorAbstract.java
New file
@@ -0,0 +1,8 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.response;
import org.springframework.beans.factory.InitializingBean;
public abstract class SIPResponseProcessorAbstract implements InitializingBean, ISIPResponseProcessor {
}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/ITimeoutProcessor.java
New file
@@ -0,0 +1,7 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.timeout;
import javax.sip.TimeoutEvent;
public interface ITimeoutProcessor {
    void process(TimeoutEvent event);
}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/timeout/impl/TimeoutProcessorImpl.java
New file
@@ -0,0 +1,36 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.timeout.impl;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.sip.TimeoutEvent;
import javax.sip.header.CallIdHeader;
@Component
public class TimeoutProcessorImpl implements InitializingBean, ITimeoutProcessor {
    @Autowired
    private SIPProcessorObserver processorObserver;
    @Autowired
    private SipSubscribe sipSubscribe;
    @Override
    public void afterPropertiesSet() throws Exception {
        processorObserver.addTimeoutProcessor(this);
    }
    @Override
    public void process(TimeoutEvent event) {
        // TODO Auto-generated method stub
        CallIdHeader callIdHeader = event.getClientTransaction().getDialog().getCallId();
        String callId = callIdHeader.getCallId();
        SipSubscribe.Event errorSubscribe = sipSubscribe.getErrorSubscribe(callId);
        SipSubscribe.EventResult<TimeoutEvent> timeoutEventEventResult = new SipSubscribe.EventResult<>(event);
        errorSubscribe.response(timeoutEventEventResult);
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/SIPRequestAbstractProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/NotifyRequestProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/RegisterResponseProcessor.java
File was deleted
src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java
@@ -6,7 +6,7 @@
import java.util.Locale;
/**    
 * @Description:时间工具类,主要处理ISO 8601格式转换
 * @description:时间工具类,主要处理ISO 8601格式转换
 * @author: swwheihei
 * @date:   2020年5月8日 下午3:24:42     
 */
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
File was renamed from src/main/java/com/genersoft/iot/vmp/utils/SipUtils.java
@@ -1,4 +1,4 @@
package com.genersoft.iot.vmp.utils;
package com.genersoft.iot.vmp.gb28181.utils;
import gov.nist.javax.sip.address.AddressImpl;
import gov.nist.javax.sip.address.SipUri;
@@ -9,15 +9,20 @@
/**
 * @author panlinlin
 * @version 1.0.0
 * @Description JAIN SIP的工具类
 * @description JAIN SIP的工具类
 * @createTime 2021年09月27日 15:12:00
 */
public class SipUtils {
    public static String getUserIdFromFromHeader(Request request) {
        FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
        return getUserIdFromFromHeader(fromHeader);
    }
    public static String getUserIdFromFromHeader(FromHeader fromHeader) {
        AddressImpl address = (AddressImpl)fromHeader.getAddress();
        SipUri uri = (SipUri) address.getURI();
        return uri.getUser();
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
@@ -1,15 +1,7 @@
package com.genersoft.iot.vmp.gb28181.utils;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
@@ -18,6 +10,12 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.sip.RequestEvent;
import javax.sip.message.Request;
import java.io.ByteArrayInputStream;
import java.io.StringReader;
import java.util.*;
/**
 * 基于dom4j的工具包
@@ -161,4 +159,23 @@
            }
        }
    }
    public static  Element getRootElement(RequestEvent evt) throws DocumentException {
        return getRootElement(evt, "gb2312");
    }
    public static Element getRootElement(RequestEvent evt, String charset) throws DocumentException {
        Request request = evt.getRequest();
        return getRootElement(request.getRawContent(), charset);
    }
    public static Element getRootElement(byte[] content, String charset) throws DocumentException {
        if (charset == null) {
            charset = "gb2312";
        }
        SAXReader reader = new SAXReader();
        reader.setEncoding(charset);
        Document xml = reader.read(new ByteArrayInputStream(content));
        return xml.getRootElement();
    }
}
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -31,7 +31,7 @@
import javax.servlet.http.HttpServletRequest;
/**    
 * @Description:针对 ZLMediaServer的hook事件监听
 * @description:针对 ZLMediaServer的hook事件监听
 * @author: swwheihei
 * @date:   2020年5月8日 上午10:46:48     
 */
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
@@ -8,7 +8,7 @@
import java.util.concurrent.ConcurrentHashMap;
/**
 * @Description:针对 ZLMediaServer的hook事件订阅
 * @description:针对 ZLMediaServer的hook事件订阅
 * @author: pan
 * @date:   2020年12月2日 21:17:32
 */
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -10,7 +10,7 @@
import com.github.pagehelper.PageInfo;
/**    
 * @Description:视频设备数据存储接口
 * @description:视频设备数据存储接口
 * @author: swwheihei
 * @date:   2020年5月6日 下午2:14:31     
 */
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -25,7 +25,7 @@
import org.springframework.transaction.annotation.Transactional;
/**    
 * @Description:视频设备数据存储-jdbc实现
 * @description:视频设备数据存储-jdbc实现
 * @author: swwheihei
 * @date:   2020年5月6日 下午2:31:42
 */
src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java
@@ -6,7 +6,7 @@
import org.springframework.stereotype.Component;
/**    
 * @Description:spring bean获取工厂,获取spring中的已初始化的bean
 * @description:spring bean获取工厂,获取spring中的已初始化的bean
 * @author: swwheihei
 * @date:   2019年6月25日 下午4:51:52   
 * 
src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java
@@ -9,7 +9,7 @@
import com.alibaba.fastjson.serializer.SerializerFeature;
/**    
 * @Description:使用fastjson实现redis的序列化
 * @description:使用fastjson实现redis的序列化
 * @author: swwheihei
 * @date:   2020年5月6日 下午8:40:11     
 */
src/main/java/com/genersoft/iot/vmp/utils/redis/JedisUtil.java
@@ -8,7 +8,7 @@
import java.util.Set;
/**
 * @Description:Jedis工具类
 * @description:Jedis工具类
 * @author: wangshaopeng@sunnybs.com
 * @date: 2021年03月22日 下午8:27:29
 */
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
@@ -9,7 +9,7 @@
import org.springframework.util.CollectionUtils;
/**    
 * @Description:Redis工具类
 * @description:Redis工具类
 * @author: swwheihei
 * @date:   2020年5月6日 下午8:27:29     
 */
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
@@ -1,11 +1,21 @@
package com.genersoft.iot.vmp.vmanager.gb28181.device;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.service.IDeviceService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -15,15 +25,6 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import javax.sip.message.Response;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
@Api(tags = "国标设备查询", value = "国标设备查询")
@@ -49,6 +50,9 @@
    
    @Autowired
    private DeviceOffLineDetector offLineDetector;
    @Autowired
    private IDeviceService deviceService;
    /**
     * 使用ID查询国标设备
@@ -301,6 +305,18 @@
            if (!StringUtils.isEmpty(device.getName())) deviceInStore.setName(device.getName());
            if (!StringUtils.isEmpty(device.getCharset())) deviceInStore.setCharset(device.getCharset());
            if (!StringUtils.isEmpty(device.getMediaServerId())) deviceInStore.setMediaServerId(device.getMediaServerId());
            if (deviceInStore.getSubscribeCycleForCatalog() <=0 && device.getSubscribeCycleForCatalog() > 0) {
                deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
                // 开启订阅
                deviceService.addCatalogSubscribe(deviceInStore);
            }
            if (deviceInStore.getSubscribeCycleForCatalog() > 0 && device.getSubscribeCycleForCatalog() <= 0) {
                deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
                // 取消订阅
                deviceService.removeCatalogSubscribe(deviceInStore);
            }
            storager.updateDevice(deviceInStore);
            cmder.deviceInfoQuery(deviceInStore);
        }