648540858
2023-04-03 4f2d47385d3535edf73634831c56f7fc18ff3494
去除redis工具类直接使用RedisTemplate存取数据
16个文件已修改
2个文件已添加
2428 ■■■■ 已修改文件
src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/redis/RedisMsgListenConfig.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java 79 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java 269 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/utils/JsonUtil.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java 883 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil2.java 899 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/redis/RedisConfig.java
@@ -1,58 +1,31 @@
package com.genersoft.iot.vmp.conf.redis;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.service.redisMsg.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import com.alibaba.fastjson2.support.spring.data.redis.GenericFastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer;
/**
 * @description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
 * @author: swwheihei
 * @date: 2019年5月30日 上午10:58:25
 * Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
 * swwheihei
 * 2019年5月30日 上午10:58:25
 * 
 */
@Configuration
@Order(value=1)
public class RedisConfig extends CachingConfigurerSupport {
public class RedisConfig {
    @Autowired
    private RedisGpsMsgListener redisGPSMsgListener;
    @Autowired
    private RedisAlarmMsgListener redisAlarmMsgListener;
    @Autowired
    private RedisStreamMsgListener redisStreamMsgListener;
    @Autowired
    private RedisGbPlayMsgListener redisGbPlayMsgListener;
    @Autowired
    private RedisPushStreamStatusMsgListener redisPushStreamStatusMsgListener;
    @Autowired
    private RedisPushStreamStatusListMsgListener redisPushStreamListMsgListener;
    @Autowired
    private RedisPushStreamResponseListener redisPushStreamResponseListener;
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        // 使用fastJson序列化
        FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
        GenericFastJsonRedisSerializer fastJsonRedisSerializer = new GenericFastJsonRedisSerializer();
        // value值的序列化采用fastJsonRedisSerializer
        redisTemplate.setValueSerializer(fastJsonRedisSerializer);
        redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
@@ -63,27 +36,4 @@
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }
    /**
     * redis消息监听器容器 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器
     * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
     *
     * @param connectionFactory
     * @return
     */
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(redisGPSMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_GPS));
        container.addMessageListener(redisAlarmMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM_RECEIVE));
        container.addMessageListener(redisStreamMsgListener, new PatternTopic(VideoManagerConstants.WVP_MSG_STREAM_CHANGE_PREFIX + "PUSH"));
        container.addMessageListener(redisGbPlayMsgListener, new PatternTopic(RedisGbPlayMsgListener.WVP_PUSH_STREAM_KEY));
        container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE));
        container.addMessageListener(redisPushStreamListMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_LIST_CHANGE));
        container.addMessageListener(redisPushStreamResponseListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_RESPONSE));
        return container;
    }
}
src/main/java/com/genersoft/iot/vmp/conf/redis/RedisMsgListenConfig.java
New file
@@ -0,0 +1,68 @@
package com.genersoft.iot.vmp.conf.redis;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.service.redisMsg.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
/**
 * @description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
 * @author: swwheihei
 * @date: 2019年5月30日 上午10:58:25
 *
 */
@Configuration
@Order(value=1)
public class RedisMsgListenConfig {
    @Autowired
    private RedisGpsMsgListener redisGPSMsgListener;
    @Autowired
    private RedisAlarmMsgListener redisAlarmMsgListener;
    @Autowired
    private RedisStreamMsgListener redisStreamMsgListener;
    @Autowired
    private RedisGbPlayMsgListener redisGbPlayMsgListener;
    @Autowired
    private RedisPushStreamStatusMsgListener redisPushStreamStatusMsgListener;
    @Autowired
    private RedisPushStreamStatusListMsgListener redisPushStreamListMsgListener;
    @Autowired
    private RedisPushStreamResponseListener redisPushStreamResponseListener;
    /**
     * redis消息监听器容器 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器
     * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
     *
     * @param connectionFactory
     * @return
     */
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(redisGPSMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_GPS));
        container.addMessageListener(redisAlarmMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM_RECEIVE));
        container.addMessageListener(redisStreamMsgListener, new PatternTopic(VideoManagerConstants.WVP_MSG_STREAM_CHANGE_PREFIX + "PUSH"));
        container.addMessageListener(redisGbPlayMsgListener, new PatternTopic(RedisGbPlayMsgListener.WVP_PUSH_STREAM_KEY));
        container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE));
        container.addMessageListener(redisPushStreamListMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_LIST_CHANGE));
        container.addMessageListener(redisPushStreamResponseListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_RESPONSE));
        return container;
    }
}
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
@@ -72,22 +72,23 @@
     **/
    @Override
    public void configure(WebSecurity web) {
        ArrayList<String> matchers = new ArrayList<>();
        matchers.add("/");
        matchers.add("/#/**");
        matchers.add("/static/**");
        matchers.add("/index.html");
        matchers.add("/doc.html");
        matchers.add("/webjars/**");
        matchers.add("/swagger-resources/**");
        matchers.add("/v3/api-docs/**");
        matchers.add("/js/**");
        matchers.add("/api/device/query/snap/**");
        matchers.add("/record_proxy/*/**");
        matchers.addAll(userSetting.getInterfaceAuthenticationExcludes());
        // 可以直接访问的静态数据
        web.ignoring().antMatchers(matchers.toArray(new String[0]));
        if (userSetting.isInterfaceAuthentication()) {
            ArrayList<String> matchers = new ArrayList<>();
            matchers.add("/");
            matchers.add("/#/**");
            matchers.add("/static/**");
            matchers.add("/index.html");
            matchers.add("/doc.html");
            matchers.add("/webjars/**");
            matchers.add("/swagger-resources/**");
            matchers.add("/v3/api-docs/**");
            matchers.add("/js/**");
            matchers.add("/api/device/query/snap/**");
            matchers.add("/record_proxy/*/**");
            matchers.addAll(userSetting.getInterfaceAuthenticationExcludes());
            // 可以直接访问的静态数据
            web.ignoring().antMatchers(matchers.toArray(new String[0]));
        }
    }
    /**
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
@@ -8,22 +8,24 @@
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import gov.nist.javax.sip.message.SIPResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.List;
/**
 * @description:视频流session管理器,管理视频预览、预览回放的通信句柄
 * @author: swwheihei
 * @date:   2020年5月13日 下午4:03:02
/**
 * 视频流session管理器,管理视频预览、预览回放的通信句柄
 */
@Component
public class VideoStreamSessionManager {
    @Autowired
    private UserSetting userSetting;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    public enum SessionType {
        play,
@@ -52,7 +54,7 @@
        ssrcTransaction.setMediaServerId(mediaServerId);
        ssrcTransaction.setType(type);
        RedisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId()
        redisTemplate.opsForValue().set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId()
                + "_" +  deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction);
    }
@@ -71,11 +73,11 @@
            stream ="*";
        }
        String key = VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_" + deviceId + "_" + channelId + "_" + callId+ "_" + stream;
        List<Object> scanResult = RedisUtil.scan(key);
        List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
        if (scanResult.size() == 0) {
            return null;
        }
        return (SsrcTransaction)RedisUtil.get((String) scanResult.get(0));
        return (SsrcTransaction)redisTemplate.opsForValue().get(scanResult.get(0));
    }
    public List<SsrcTransaction> getSsrcTransactionForAll(String deviceId, String channelId, String callId, String stream){
@@ -92,13 +94,13 @@
            stream ="*";
        }
        String key = VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_" + deviceId + "_" + channelId + "_" + callId+ "_" + stream;
        List<Object> scanResult = RedisUtil.scan(key);
        List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
        if (scanResult.size() == 0) {
            return null;
        }
        List<SsrcTransaction> result = new ArrayList<>();
        for (Object keyObj : scanResult) {
            result.add((SsrcTransaction)RedisUtil.get((String) keyObj));
            result.add((SsrcTransaction)redisTemplate.opsForValue().get(keyObj));
        }
        return result;
    }
@@ -124,17 +126,17 @@
        if (ssrcTransaction == null) {
            return;
        }
        RedisUtil.del(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_"
        redisTemplate.delete(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_"
                +  deviceId + "_" + channelId + "_" + ssrcTransaction.getCallId() + "_" + ssrcTransaction.getStream());
    }
    public List<SsrcTransaction> getAllSsrc() {
        List<Object> ssrcTransactionKeys = RedisUtil.scan(String.format("%s_*_*_*_*", VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX+ userSetting.getServerId()));
        List<Object> ssrcTransactionKeys = RedisUtil.scan(redisTemplate, String.format("%s_*_*_*_*", VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX+ userSetting.getServerId()));
        List<SsrcTransaction> result= new ArrayList<>();
        for (int i = 0; i < ssrcTransactionKeys.size(); i++) {
            String key = (String)ssrcTransactionKeys.get(i);
            SsrcTransaction ssrcTransaction = JsonUtil.redisJsonToObject(key, SsrcTransaction.class);
        for (Object ssrcTransactionKey : ssrcTransactionKeys) {
            String key = (String) ssrcTransactionKey;
            SsrcTransaction ssrcTransaction = JsonUtil.redisJsonToObject(redisTemplate, key, SsrcTransaction.class);
            result.add(ssrcTransaction);
        }
        return result;
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
@@ -20,7 +20,7 @@
    void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException;
    void register(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException;
    void register(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException;
    void register(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean isRegister) throws SipException, InvalidArgumentException, ParseException;
    /**
     * 向上级平台注销
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -45,7 +45,7 @@
    @Autowired
    private IRedisCatchStorage redisCatchStorage;
    public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, long CSeq, String fromTag, String toTag, CallIdHeader callIdHeader, boolean isRegister) throws ParseException, InvalidArgumentException, PeerUnavailableException {
    public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, long CSeq, String fromTag, String toTag, CallIdHeader callIdHeader, int expires) throws ParseException, InvalidArgumentException, PeerUnavailableException {
        Request request = null;
        String sipAddress = parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort();
        //请求行
@@ -78,8 +78,8 @@
                .createSipURI(parentPlatform.getDeviceGBId(), sipAddress));
        request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress));
        ExpiresHeader expires = sipLayer.getSipFactory().createHeaderFactory().createExpiresHeader(isRegister ? parentPlatform.getExpires() : 0);
        request.addHeader(expires);
        ExpiresHeader expiresHeader = sipLayer.getSipFactory().createHeaderFactory().createExpiresHeader(expires);
        request.addHeader(expiresHeader);
        request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil));
@@ -87,10 +87,10 @@
    }
    public Request createRegisterRequest(@NotNull ParentPlatform parentPlatform, String fromTag, String toTag,
                                         WWWAuthenticateHeader www , CallIdHeader callIdHeader, boolean isRegister) throws ParseException, PeerUnavailableException, InvalidArgumentException {
                                         WWWAuthenticateHeader www , CallIdHeader callIdHeader, int expires) throws ParseException, PeerUnavailableException, InvalidArgumentException {
        Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), fromTag, toTag, callIdHeader, isRegister);
        Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(), fromTag, toTag, callIdHeader, expires);
        SipURI requestURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
        if (www == null) {
            AuthorizationHeader authorizationHeader = sipLayer.getSipFactory().createHeaderFactory().createAuthorizationHeader("Digest");
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -71,23 +71,23 @@
    @Override
    public void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException {
        register(parentPlatform, null, null, errorEvent, okEvent, false, true);
        register(parentPlatform, null, null, errorEvent, okEvent, true);
    }
    @Override
    public void register(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException {
        register(parentPlatform, sipTransactionInfo, null, errorEvent, okEvent, false, true);
        register(parentPlatform, sipTransactionInfo, null, errorEvent, okEvent, true);
    }
    @Override
    public void unregister(ParentPlatform parentPlatform, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException {
        register(parentPlatform, sipTransactionInfo, null, errorEvent, okEvent, false, false);
        register(parentPlatform, sipTransactionInfo, null, errorEvent, okEvent, false);
    }
    @Override
    public void register(ParentPlatform parentPlatform, @Nullable SipTransactionInfo sipTransactionInfo, @Nullable WWWAuthenticateHeader www,
                            SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain, boolean isRegister) throws SipException, InvalidArgumentException, ParseException {
                            SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean isRegister) throws SipException, InvalidArgumentException, ParseException {
            Request request;
            CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
@@ -105,10 +105,10 @@
                }
            }
            if (!registerAgain ) {
            if (www == null ) {
                request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform,
                        redisCatchStorage.getCSEQ(), fromTag,
                        toTag, callIdHeader, isRegister);
                        toTag, callIdHeader, isRegister? parentPlatform.getExpires() : 0);
                // 将 callid 写入缓存, 等注册成功可以更新状态
                String callIdFromHeader = callIdHeader.getCallId();
                redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, PlatformRegisterInfo.getInstance(parentPlatform.getServerGBId(), isRegister));
@@ -126,7 +126,7 @@
                });
            }else {
                request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform, fromTag, toTag, www, callIdHeader, isRegister);
                request = headerProviderPlatformProvider.createRegisterRequest(parentPlatform, fromTag, toTag, www, callIdHeader, isRegister? parentPlatform.getExpires() : 0);
            }
            sipSender.transmitRequest(parentPlatform.getDeviceIp(), request, null, okEvent);
@@ -497,10 +497,10 @@
    private void sendNotify(ParentPlatform parentPlatform, String catalogXmlContent,
                                   SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent,  SipSubscribe.Event okEvent )
            throws SipException, ParseException, InvalidArgumentException {
        MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipLayer.getSipFactory().createMessageFactory();
        MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipLayer.getSipFactory().createMessageFactory();
        String characterSet = parentPlatform.getCharacterSet();
         // 设置编码, 防止中文乱码
        messageFactory.setDefaultContentEncodingCharset(characterSet);
        // 设置编码, 防止中文乱码
        messageFactory.setDefaultContentEncodingCharset(characterSet);
        SIPRequest notifyRequest = headerProviderPlatformProvider.createNotifyRequest(parentPlatform, catalogXmlContent, subscribeInfo);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java
@@ -10,7 +10,6 @@
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.utils.UJson;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import gov.nist.javax.sip.message.SIPRequest;
import org.dom4j.Element;
import org.slf4j.Logger;
@@ -18,6 +17,7 @@
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
@@ -29,6 +29,7 @@
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
@@ -56,6 +57,9 @@
    @Qualifier("taskExecutor")
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    private Long recordInfoTtl = 1800L;
@@ -130,10 +134,11 @@
                                .collect(Collectors.toMap(record -> record.getStartTime()+ record.getEndTime(), UJson::writeJson));
                        // 获取任务结果数据
                        String resKey = VideoManagerConstants.REDIS_RECORD_INFO_RES_PRE + channelId + sn;
                        RedisUtil.hmset(resKey, map, recordInfoTtl);
                        redisTemplate.opsForHash().putAll(resKey, map);
                        redisTemplate.expire(resKey, recordInfoTtl, TimeUnit.SECONDS);
                        String resCountKey = VideoManagerConstants.REDIS_RECORD_INFO_RES_COUNT_PRE + channelId + sn;
                        long incr = RedisUtil.incr(resCountKey, map.size());
                        RedisUtil.expire(resCountKey, recordInfoTtl);
                        long incr = redisTemplate.opsForValue().increment(resCountKey, map.size());
                        redisTemplate.expire(resCountKey, recordInfoTtl, TimeUnit.SECONDS);
                        recordInfo.setRecordList(recordList);
                        recordInfo.setCount(Math.toIntExact(incr));
                        eventPublisher.recordEndEventPush(recordInfo);
@@ -141,7 +146,7 @@
                            return;
                        }
                        // 已接收完成
                        List<RecordItem> resList = RedisUtil.hmget(resKey).values().stream().map(e -> UJson.readJson(e.toString(), RecordItem.class)).collect(Collectors.toList());
                        List<RecordItem> resList = redisTemplate.opsForHash().entries(resKey).values().stream().map(e -> UJson.readJson(e.toString(), RecordItem.class)).collect(Collectors.toList());
                        if (resList.size() < sumNum) {
                            return;
                        }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java
@@ -92,7 +92,7 @@
            WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME);
            SipTransactionInfo sipTransactionInfo = new SipTransactionInfo(response);
            try {
                sipCommanderForPlatform.register(parentPlatform, sipTransactionInfo, www, null, null, true, platformRegisterInfo.isRegister());
                sipCommanderForPlatform.register(parentPlatform, sipTransactionInfo, www, null, null, platformRegisterInfo.isRegister());
            } catch (SipException | InvalidArgumentException | ParseException e) {
                logger.error("[命令发送失败] 国标级联 再次注册: {}", e.getMessage());
            }
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -10,7 +10,6 @@
import com.genersoft.iot.vmp.conf.exception.ControllerException;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.session.SsrcConfig;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
@@ -33,6 +32,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
@@ -75,13 +75,11 @@
    private MediaServerMapper mediaServerMapper;
    @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    TransactionDefinition transactionDefinition;
    private TransactionDefinition transactionDefinition;
    @Autowired
    private VideoStreamSessionManager streamSession;
    @Autowired
    private ZLMRTPServerFactory zlmrtpServerFactory;
@@ -94,6 +92,9 @@
    @Autowired
    private IRedisCatchStorage redisCatchStorage;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    /**
     * 初始化
@@ -109,12 +110,13 @@
            if (mediaServerItem.getSsrcConfig() == null) {
                SsrcConfig ssrcConfig = new SsrcConfig(mediaServerItem.getId(), null, sipConfig.getDomain());
                mediaServerItem.setSsrcConfig(ssrcConfig);
                RedisUtil.set(VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId(), mediaServerItem);
                redisTemplate.opsForValue().set(VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId(), mediaServerItem);
            }
            // 查询redis是否存在此mediaServer
            String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId();
            if (!RedisUtil.hasKey(key)) {
                RedisUtil.set(key, mediaServerItem);
            Boolean hasKey = redisTemplate.hasKey(key);
            if (hasKey != null && ! hasKey) {
                redisTemplate.opsForValue().set(key, mediaServerItem);
            }
        }
@@ -159,7 +161,7 @@
            } else {
                rtpServerPort = mediaServerItem.getRtpProxyPort();
            }
            RedisUtil.set(key, mediaServerItem);
            redisTemplate.opsForValue().set(key, mediaServerItem);
            return new SSRCInfo(rtpServerPort, ssrc, streamId);
        }
    }
@@ -193,7 +195,7 @@
        ssrcConfig.releaseSsrc(ssrc);
        mediaServerItem.setSsrcConfig(ssrcConfig);
        String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId();
        RedisUtil.set(key, mediaServerItem);
        redisTemplate.opsForValue().set(key, mediaServerItem);
    }
    /**
@@ -202,7 +204,7 @@
    @Override
    public void clearRTPServer(MediaServerItem mediaServerItem) {
        mediaServerItem.setSsrcConfig(new SsrcConfig(mediaServerItem.getId(), null, sipConfig.getDomain()));
        RedisUtil.zAdd(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(), mediaServerItem.getId(), 0);
        redisTemplate.opsForZSet().add(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(), mediaServerItem.getId(), 0);
    }
@@ -224,22 +226,22 @@
            );
        }
        String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItemInDataBase.getId();
        RedisUtil.set(key, mediaServerItemInDataBase);
        redisTemplate.opsForValue().set(key, mediaServerItemInDataBase);
    }
    @Override
    public List<MediaServerItem> getAll() {
        List<MediaServerItem> result = new ArrayList<>();
        List<Object> mediaServerKeys = RedisUtil.scan(String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX+ userSetting.getServerId() + "_" ));
        List<Object> mediaServerKeys = RedisUtil.scan(redisTemplate, String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX+ userSetting.getServerId() + "_" ));
        String onlineKey = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
        for (Object mediaServerKey : mediaServerKeys) {
            String key = (String) mediaServerKey;
            MediaServerItem mediaServerItem = JsonUtil.redisJsonToObject(key, MediaServerItem.class);
            MediaServerItem mediaServerItem = JsonUtil.redisJsonToObject(redisTemplate, key, MediaServerItem.class);
            if (Objects.isNull(mediaServerItem)) {
                continue;
            }
            // 检查状态
            Double aDouble = RedisUtil.zScore(onlineKey, mediaServerItem.getId());
            Double aDouble = redisTemplate.opsForZSet().score(onlineKey, mediaServerItem.getId());
            if (aDouble != null) {
                mediaServerItem.setStatus(true);
            }
@@ -265,13 +267,14 @@
    @Override
    public List<MediaServerItem> getAllOnline() {
        String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
        Set<String> mediaServerIdSet = RedisUtil.zRevRange(key, 0, -1);
        Set<Object> mediaServerIdSet = redisTemplate.opsForZSet().reverseRange(key, 0, -1);
        List<MediaServerItem> result = new ArrayList<>();
        if (mediaServerIdSet != null && mediaServerIdSet.size() > 0) {
            for (String mediaServerId : mediaServerIdSet) {
                String serverKey = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerId;
                result.add((MediaServerItem) RedisUtil.get(serverKey));
            for (Object mediaServerId : mediaServerIdSet) {
                String mediaServerIdStr = (String) mediaServerId;
                String serverKey = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerIdStr;
                result.add((MediaServerItem) redisTemplate.opsForValue().get(serverKey));
            }
        }
        Collections.reverse(result);
@@ -289,7 +292,7 @@
            return null;
        }
        String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerId;
        return JsonUtil.redisJsonToObject(key, MediaServerItem.class);
        return JsonUtil.redisJsonToObject(redisTemplate, key, MediaServerItem.class);
    }
    @Override
@@ -301,7 +304,7 @@
    @Override
    public void clearMediaServerForOnline() {
        String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
        RedisUtil.del(key);
        redisTemplate.delete(key);
    }
    @Override
@@ -401,16 +404,16 @@
        }
        mediaServerMapper.update(serverItem);
        String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + zlmServerConfig.getGeneralMediaServerId();
        if (RedisUtil.get(key) == null) {
        if (redisTemplate.opsForValue().get(key) == null) {
            SsrcConfig ssrcConfig = new SsrcConfig(zlmServerConfig.getGeneralMediaServerId(), null, sipConfig.getDomain());
            serverItem.setSsrcConfig(ssrcConfig);
        }else {
            MediaServerItem mediaServerItemInRedis = JsonUtil.redisJsonToObject(key, MediaServerItem.class);
            MediaServerItem mediaServerItemInRedis = JsonUtil.redisJsonToObject(redisTemplate, key, MediaServerItem.class);
            if (Objects.nonNull(mediaServerItemInRedis)) {
                serverItem.setSsrcConfig(mediaServerItemInRedis.getSsrcConfig());
            }
        }
        RedisUtil.set(key, serverItem);
        redisTemplate.opsForValue().set(key, serverItem);
        resetOnlineServerItem(serverItem);
@@ -473,15 +476,15 @@
        // 更新缓存
        String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
        // 使用zset的分数作为当前并发量, 默认值设置为0
        if (RedisUtil.zScore(key, serverItem.getId()) == null) {  // 不存在则设置默认值 已存在则重置
            RedisUtil.zAdd(key, serverItem.getId(), 0L);
        if (redisTemplate.opsForZSet().score(key, serverItem.getId()) == null) {  // 不存在则设置默认值 已存在则重置
            redisTemplate.opsForZSet().add(key, serverItem.getId(), 0L);
            // 查询服务流数量
            zlmresTfulUtils.getMediaList(serverItem, null, null, "rtsp",(mediaList ->{
                Integer code = mediaList.getInteger("code");
                if (code == 0) {
                    JSONArray data = mediaList.getJSONArray("data");
                    if (data != null) {
                        RedisUtil.zAdd(key, serverItem.getId(), data.size());
                        redisTemplate.opsForZSet().add(key, serverItem.getId(), data.size());
                    }
                }
            }));
@@ -497,14 +500,14 @@
            return;
        }
        String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
        RedisUtil.zIncrScore(key, mediaServerId, 1);
        redisTemplate.opsForZSet().incrementScore(key, mediaServerId, 1);
    }
    @Override
    public void removeCount(String mediaServerId) {
        String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
        RedisUtil.zIncrScore(key, mediaServerId, - 1);
        redisTemplate.opsForZSet().incrementScore(key, mediaServerId, - 1);
    }
    /**
@@ -514,16 +517,14 @@
    @Override
    public MediaServerItem getMediaServerForMinimumLoad(Boolean hasAssist) {
        String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
        if (RedisUtil.zSize(key)  == null || RedisUtil.zSize(key) == 0) {
            if (RedisUtil.zSize(key)  == null || RedisUtil.zSize(key) == 0) {
                logger.info("获取负载最低的节点时无在线节点");
                return null;
            }
        Long size = redisTemplate.opsForZSet().zCard(key);
        if (size  == null || size == 0) {
            logger.info("获取负载最低的节点时无在线节点");
            return null;
        }
        // 获取分数最低的,及并发最低的
        Set<Object> objects = RedisUtil.zRange(key, 0, -1);
        Set<Object> objects = redisTemplate.opsForZSet().range(key, 0, -1);
        ArrayList<Object> mediaServerObjectS = new ArrayList<>(objects);
        MediaServerItem mediaServerItem = null;
        if (hasAssist == null) {
@@ -686,9 +687,9 @@
    @Override
    public void delete(String id) {
        RedisUtil.zRemove(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(), id);
        redisTemplate.opsForZSet().remove(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(), id);
        String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + id;
        RedisUtil.del(key);
        redisTemplate.delete(key);
    }
    @Override
    public void deleteDb(String id){
@@ -711,7 +712,7 @@
            SsrcConfig ssrcConfig = new SsrcConfig(mediaServerItem.getId(), null, sipConfig.getDomain());
            mediaServerItem.setSsrcConfig(ssrcConfig);
            String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId();
            RedisUtil.set(key, mediaServerItem);
            redisTemplate.opsForValue().set(key, mediaServerItem);
            clearRTPServer(mediaServerItem);
        }
        final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerItem.getId();
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
@@ -146,7 +146,7 @@
        // 注销旧的
        try {
            if (parentPlatformOld.isStatus()) {
                logger.info("保存平台{}时发现救平台在线,发送注销命令", parentPlatform.getDeviceGBId());
                logger.info("保存平台{}时发现救平台在线,发送注销命令", parentPlatformOld.getServerGBId());
                commanderForPlatform.unregister(parentPlatformOld, parentPlatformCatchOld.getSipTransactionInfo(), null, eventResult -> {
                    logger.info("[国标级联] 注销成功, 平台:{}", parentPlatformOld.getServerGBId());
                });
@@ -253,7 +253,7 @@
                                // 心跳成功
                                // 清空之前的心跳超时计数
                                ParentPlatformCatch platformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
                                if (platformCatch.getKeepAliveReply() > 0) {
                                if (platformCatch != null && platformCatch.getKeepAliveReply() > 0) {
                                    platformCatch.setKeepAliveReply(0);
                                    redisCatchStorage.updatePlatformCatchInfo(platformCatch);
                                }
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -33,12 +33,12 @@
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
@@ -99,6 +99,9 @@
    @Autowired
    private ZlmHttpHookSubscribe subscribe;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Override
@@ -886,7 +889,7 @@
            throw new ServiceException("streamId不存在");
        }
        streamInfo.setPause(true);
        RedisUtil.set(key, streamInfo);
        redisTemplate.opsForValue().set(key, streamInfo);
        MediaServerItem mediaServerItem = mediaServerService.getOne(streamInfo.getMediaServerId());
        if (null == mediaServerItem) {
            logger.warn("mediaServer 不存在!");
@@ -910,7 +913,7 @@
            throw new ServiceException("streamId不存在");
        }
        streamInfo.setPause(false);
        RedisUtil.set(key, streamInfo);
        redisTemplate.opsForValue().set(key, streamInfo);
        MediaServerItem mediaServerItem = mediaServerService.getOne(streamInfo.getMediaServerId());
        if (null == mediaServerItem) {
            logger.warn("mediaServer 不存在!");
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
@@ -2,19 +2,17 @@
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.bean.*;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -22,6 +20,7 @@
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
@@ -68,7 +67,7 @@
    @Autowired
    private ZLMMediaListManager zlmMediaListManager;
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private ZLMRTPServerFactory zlmrtpServerFactory;
@@ -76,14 +75,10 @@
    @Autowired
    private IMediaServerService mediaServerService;
    @Autowired
    private IRedisCatchStorage redisCatchStorage;
    @Autowired
    private DynamicTask dynamicTask;
    @Autowired
    private ZLMMediaListManager mediaListManager;
    @Autowired
    private ZlmHttpHookSubscribe subscribe;
@@ -246,7 +241,7 @@
        WvpRedisMsg response = WvpRedisMsg.getResponseInstance(userSetting.getServerId(), toId,
                WvpRedisMsgCmd.REQUEST_PUSH_STREAM, serial, result);
        JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
        RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
        redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
    }
    /**
@@ -265,7 +260,7 @@
                    WvpRedisMsgCmd.GET_SEND_ITEM, serial, result);
            JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
            RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
            redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
            return;
        }
        // 确定流是否在线
@@ -288,7 +283,7 @@
                        userSetting.getServerId(), toId, WvpRedisMsgCmd.GET_SEND_ITEM, serial, result
                );
                JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
                RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
                redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
            }, userSetting.getPlatformPlayTimeout());
            // 添加订阅
@@ -302,7 +297,12 @@
            MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(1, content.getApp(), content.getStream(),
                    content.getChannelId(), content.getPlatformId(), content.getPlatformName(), content.getServerId(),
                    content.getMediaServerId());
            redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel);
            String key = VideoManagerConstants.VM_MSG_STREAM_PUSH_REQUESTED;
            logger.info("[redis发送通知] 推流被请求 {}: {}/{}", key, messageForPushChannel.getApp(), messageForPushChannel.getStream());
            redisTemplate.convertAndSend(key, JSON.toJSON(messageForPushChannel));
//            redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel);
        }
    }
@@ -327,7 +327,7 @@
                userSetting.getServerId(), toId, WvpRedisMsgCmd.GET_SEND_ITEM, serial, result
        );
        JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
        RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
        redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
    }
    /**
@@ -364,7 +364,7 @@
            wvpResult.setMsg("timeout");
            errorCallback.handler(wvpResult);
        }, userSetting.getPlatformPlayTimeout());
        RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
        redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
    }
    /**
@@ -389,6 +389,6 @@
            callbacksForStartSendRtpStream.remove(key);
            callbacksForError.remove(key);
        });
        RedisUtil.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
        redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
    }
}
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -23,6 +23,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.*;
@@ -39,14 +40,17 @@
    @Autowired
    private UserSetting userSetting;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Override
    public Long getCSEQ() {
        String key = VideoManagerConstants.SIP_CSEQ_PREFIX  + userSetting.getServerId();
        long result =  RedisUtil.incr(key, 1L);
        if (result > Integer.MAX_VALUE) {
            RedisUtil.set(key, 1);
            result = 1;
        Long result =  redisTemplate.opsForValue().increment(key, 1L);
        if (result != null && result > Integer.MAX_VALUE) {
            redisTemplate.opsForValue().set(key, 1);
            result = 1L;
        }
        return result;
    }
@@ -55,10 +59,10 @@
    public Long getSN(String method) {
        String key = VideoManagerConstants.SIP_SN_PREFIX  + userSetting.getServerId() + "_" +  method;
        long result =  RedisUtil.incr(key, 1L);
        if (result > Integer.MAX_VALUE) {
            RedisUtil.set(key, 1);
            result = 1;
        Long result =  redisTemplate.opsForValue().increment(key, 1L);
        if (result != null && result > Integer.MAX_VALUE) {
            redisTemplate.opsForValue().set(key, 1);
            result = 1L;
        }
        return result;
    }
@@ -66,61 +70,58 @@
    @Override
    public void resetAllCSEQ() {
        String scanKey = VideoManagerConstants.SIP_CSEQ_PREFIX  + userSetting.getServerId() + "_*";
        List<Object> keys = RedisUtil.scan(scanKey);
        List<Object> keys = RedisUtil.scan(redisTemplate, scanKey);
        for (Object o : keys) {
            String key = (String) o;
            RedisUtil.set(key, 1);
            redisTemplate.opsForValue().set(key, 1);
        }
    }
    @Override
    public void resetAllSN() {
        String scanKey = VideoManagerConstants.SIP_SN_PREFIX  + userSetting.getServerId() + "_*";
        List<Object> keys = RedisUtil.scan(scanKey);
        List<Object> keys = RedisUtil.scan(redisTemplate, scanKey);
        for (Object o : keys) {
            String key = (String) o;
            RedisUtil.set(key, 1);
            redisTemplate.opsForValue().set(key, 1);
        }
    }
    /**
     * 开始播放时将流存入redis
     *
     * @return
     */
    @Override
    public boolean startPlay(StreamInfo stream) {
        return RedisUtil.set(String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, userSetting.getServerId(),
         redisTemplate.opsForValue().set(String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, userSetting.getServerId(),
                        stream.getMediaServerId(), stream.getStream(), stream.getDeviceID(), stream.getChannelId()),
                stream);
        return true;
    }
    /**
     * 停止播放时从redis删除
     *
     * @return
     */
    @Override
    public boolean stopPlay(StreamInfo streamInfo) {
        if (streamInfo == null) {
            return false;
        }
        return RedisUtil.del(String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
        Boolean result = redisTemplate.delete(String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
                userSetting.getServerId(),
                streamInfo.getMediaServerId(),
                streamInfo.getStream(),
                streamInfo.getDeviceID(),
                streamInfo.getChannelId()));
        return result != null && result;
    }
    /**
     * 查询播放列表
     * @return
     */
    @Override
    public StreamInfo queryPlay(StreamInfo streamInfo) {
        return (StreamInfo)RedisUtil.get(String.format("%S_%s_%s_%s_%s_%s",
        return (StreamInfo)redisTemplate.opsForValue().get(String.format("%S_%s_%s_%s_%s_%s",
                VideoManagerConstants.PLAYER_PREFIX,
                userSetting.getServerId(),
                streamInfo.getMediaServerId(),
@@ -130,35 +131,35 @@
    }
    @Override
    public StreamInfo queryPlayByStreamId(String streamId) {
        List<Object> playLeys = RedisUtil.scan(String.format("%S_%s_*_%s_*", VideoManagerConstants.PLAYER_PREFIX, userSetting.getServerId(), streamId));
        if (playLeys == null || playLeys.size() == 0) {
        List<Object> playLeys = RedisUtil.scan(redisTemplate, String.format("%S_%s_*_%s_*", VideoManagerConstants.PLAYER_PREFIX, userSetting.getServerId(), streamId));
        if (playLeys.size() == 0) {
            return null;
        }
        return (StreamInfo)RedisUtil.get(playLeys.get(0).toString());
        return (StreamInfo)redisTemplate.opsForValue().get(playLeys.get(0).toString());
    }
    @Override
    public StreamInfo queryPlayByDevice(String deviceId, String channelId) {
        List<Object> playLeys = RedisUtil.scan(String.format("%S_%s_*_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
        List<Object> playLeys = RedisUtil.scan(redisTemplate, String.format("%S_%s_*_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
                userSetting.getServerId(),
                deviceId,
                channelId));
        if (playLeys == null || playLeys.size() == 0) {
        if (playLeys.size() == 0) {
            return null;
        }
        return (StreamInfo)RedisUtil.get(playLeys.get(0).toString());
        return (StreamInfo)redisTemplate.opsForValue().get(playLeys.get(0).toString());
    }
    @Override
    public Map<String, StreamInfo> queryPlayByDeviceId(String deviceId) {
        Map<String, StreamInfo> streamInfos = new HashMap<>();
        List<Object> players = RedisUtil.scan(String.format("%S_%s_*_*_%s_*", VideoManagerConstants.PLAYER_PREFIX, userSetting.getServerId(),deviceId));
        List<Object> players = RedisUtil.scan(redisTemplate, String.format("%S_%s_*_*_%s_*", VideoManagerConstants.PLAYER_PREFIX, userSetting.getServerId(),deviceId));
        if (players.size() == 0) {
            return streamInfos;
        }
        for (Object player : players) {
            String key = (String) player;
            StreamInfo streamInfo = JsonUtil.redisJsonToObject(key, StreamInfo.class);
            StreamInfo streamInfo = JsonUtil.redisJsonToObject(redisTemplate, key, StreamInfo.class);
            if (Objects.isNull(streamInfo)) {
                continue;
            }
@@ -170,23 +171,23 @@
    @Override
    public boolean startPlayback(StreamInfo stream, String callId) {
        return RedisUtil.set(String.format("%S_%s_%s_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
        redisTemplate.opsForValue().set(String.format("%S_%s_%s_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
                userSetting.getServerId(), stream.getMediaServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId), stream);
        return true;
    }
    @Override
    public boolean startDownload(StreamInfo stream, String callId) {
        boolean result;
        String key=String.format("%S_%s_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX,
                userSetting.getServerId(), stream.getMediaServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId);
        if (stream.getProgress() == 1) {
            logger.debug("添加下载缓存==已完成下载=》{}",key);
            result = RedisUtil.set(key, stream);
            redisTemplate.opsForValue().set(key, stream);
        }else {
            logger.debug("添加下载缓存==未完成下载=》{}",key);
            result = RedisUtil.set(key, stream, 60*60);
            redisTemplate.opsForValue().set(key, stream, 60*60);
        }
        return result;
        return true;
    }
    @Override
    public boolean stopDownload(String deviceId, String channelId, String stream, String callId) {
@@ -215,10 +216,10 @@
                stream,
                callId
        );
        List<Object> scan = RedisUtil.scan(key);
        List<Object> scan = RedisUtil.scan(redisTemplate, key);
        if (scan.size() > 0) {
            for (Object keyObj : scan) {
                RedisUtil.del((String) keyObj);
                redisTemplate.delete(keyObj);
            }
        }
        return true;
@@ -251,10 +252,10 @@
                stream,
                callId
        );
        List<Object> scan = RedisUtil.scan(key);
        List<Object> scan = RedisUtil.scan(redisTemplate, key);
        if (scan.size() > 0) {
            for (Object keyObj : scan) {
                RedisUtil.del((String) keyObj);
                redisTemplate.delete(keyObj);
            }
        }
        return true;
@@ -284,9 +285,9 @@
                stream,
                callId
        );
        List<Object> streamInfoScan = RedisUtil.scan(key);
        List<Object> streamInfoScan = RedisUtil.scan(redisTemplate, key);
        if (streamInfoScan.size() > 0) {
            return (StreamInfo) RedisUtil.get((String) streamInfoScan.get(0));
            return (StreamInfo) redisTemplate.opsForValue().get(streamInfoScan.get(0));
        }else {
            return null;
        }
@@ -316,59 +317,59 @@
                stream,
                callId
        );
        List<Object> streamInfoScan = RedisUtil.scan(key);
        List<Object> streamInfoScan = RedisUtil.scan(redisTemplate, key);
        return (String) streamInfoScan.get(0);
    }
    @Override
    public void updatePlatformCatchInfo(ParentPlatformCatch parentPlatformCatch) {
        String key = VideoManagerConstants.PLATFORM_CATCH_PREFIX  + userSetting.getServerId() + "_" +  parentPlatformCatch.getId();
        RedisUtil.set(key, parentPlatformCatch);
        redisTemplate.opsForValue().set(key, parentPlatformCatch);
    }
    @Override
    public ParentPlatformCatch queryPlatformCatchInfo(String platformGbId) {
        return (ParentPlatformCatch)RedisUtil.get(VideoManagerConstants.PLATFORM_CATCH_PREFIX + userSetting.getServerId() + "_" + platformGbId);
        return (ParentPlatformCatch)redisTemplate.opsForValue().get(VideoManagerConstants.PLATFORM_CATCH_PREFIX + userSetting.getServerId() + "_" + platformGbId);
    }
    @Override
    public void delPlatformCatchInfo(String platformGbId) {
        RedisUtil.del(VideoManagerConstants.PLATFORM_CATCH_PREFIX + userSetting.getServerId() + "_" + platformGbId);
        redisTemplate.delete(VideoManagerConstants.PLATFORM_CATCH_PREFIX + userSetting.getServerId() + "_" + platformGbId);
    }
    @Override
    public void delPlatformKeepalive(String platformGbId) {
        RedisUtil.del(VideoManagerConstants.PLATFORM_KEEPALIVE_PREFIX + userSetting.getServerId() + "_" + platformGbId);
        redisTemplate.delete(VideoManagerConstants.PLATFORM_KEEPALIVE_PREFIX + userSetting.getServerId() + "_" + platformGbId);
    }
    @Override
    public void delPlatformRegister(String platformGbId) {
        RedisUtil.del(VideoManagerConstants.PLATFORM_REGISTER_PREFIX + userSetting.getServerId() + "_" + platformGbId);
        redisTemplate.delete(VideoManagerConstants.PLATFORM_REGISTER_PREFIX + userSetting.getServerId() + "_" + platformGbId);
    }
    @Override
    public void updatePlatformRegisterInfo(String callId, PlatformRegisterInfo platformRegisterInfo) {
        String key = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + callId;
        RedisUtil.set(key, platformRegisterInfo, 30);
        redisTemplate.opsForValue().set(key, platformRegisterInfo, 30);
    }
    @Override
    public PlatformRegisterInfo queryPlatformRegisterInfo(String callId) {
        return (PlatformRegisterInfo)RedisUtil.get(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + callId);
        return (PlatformRegisterInfo)redisTemplate.opsForValue().get(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + callId);
    }
    @Override
    public void delPlatformRegisterInfo(String callId) {
        RedisUtil.del(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + callId);
         redisTemplate.delete(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + callId);
    }
    @Override
    public void cleanPlatformRegisterInfos() {
        List regInfos = RedisUtil.scan(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + "*");
        List regInfos = RedisUtil.scan(redisTemplate, VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_" + "*");
        for (Object key : regInfos) {
            RedisUtil.del(key.toString());
            redisTemplate.delete(key.toString());
        }
    }
@@ -382,7 +383,7 @@
                + sendRtpItem.getChannelId() + "_"
                + sendRtpItem.getStreamId() + "_"
                + sendRtpItem.getCallId();
        RedisUtil.set(key, sendRtpItem);
        redisTemplate.opsForValue().set(key, sendRtpItem);
    }
    @Override
@@ -405,9 +406,9 @@
                + channelId + "_"
                + streamId + "_"
                + callId;
        List<Object> scan = RedisUtil.scan(key);
        List<Object> scan = RedisUtil.scan(redisTemplate, key);
        if (scan.size() > 0) {
            return (SendRtpItem)RedisUtil.get((String)scan.get(0));
            return (SendRtpItem)redisTemplate.opsForValue().get(scan.get(0));
        }else {
            return null;
        }
@@ -427,10 +428,10 @@
                + channelId + "_"
                + streamId + "_"
                + callId;
        List<Object> scan = RedisUtil.scan(key);
        List<Object> scan = RedisUtil.scan(redisTemplate, key);
        List<SendRtpItem> result = new ArrayList<>();
        for (Object o : scan) {
            result.add((SendRtpItem) RedisUtil.get((String) o));
            result.add((SendRtpItem) redisTemplate.opsForValue().get(o));
        }
        return result;
    }
@@ -449,10 +450,10 @@
                + channelId + "_"
                + stream + "_"
                + callId;
        List<Object> scan = RedisUtil.scan(key);
        List<Object> scan = RedisUtil.scan(redisTemplate, key);
        List<SendRtpItem> result = new ArrayList<>();
        for (Object o : scan) {
            result.add((SendRtpItem) RedisUtil.get((String) o));
            result.add((SendRtpItem) redisTemplate.opsForValue().get(o));
        }
        return result;
    }
@@ -465,12 +466,12 @@
        String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX
                + userSetting.getServerId() + "_*_"
                + platformGbId + "_*" + "_*" + "_*";
        List<Object> queryResult = RedisUtil.scan(key);
        List<Object> queryResult = RedisUtil.scan(redisTemplate, key);
        List<SendRtpItem> result= new ArrayList<>();
        for (Object o : queryResult) {
            String keyItem = (String) o;
            result.add((SendRtpItem) RedisUtil.get(keyItem));
            result.add((SendRtpItem) redisTemplate.opsForValue().get(keyItem));
        }
        return result;
@@ -478,8 +479,6 @@
    /**
     * 删除RTP推送信息缓存
     * @param platformGbId
     * @param channelId
     */
    @Override
    public void deleteSendRTPServer(String platformGbId, String channelId, String callId, String streamId) {
@@ -495,10 +494,10 @@
                + channelId + "_"
                + streamId + "_"
                + callId;
        List<Object> scan = RedisUtil.scan(key);
        List<Object> scan = RedisUtil.scan(redisTemplate, key);
        if (scan.size() > 0) {
            for (Object keyStr : scan) {
                RedisUtil.del((String)keyStr);
                redisTemplate.delete(keyStr);
            }
        }
    }
@@ -507,12 +506,12 @@
    public List<SendRtpItem> queryAllSendRTPServer() {
        String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX
                + userSetting.getServerId() + "_*";
        List<Object> queryResult = RedisUtil.scan(key);
        List<Object> queryResult = RedisUtil.scan(redisTemplate, key);
        List<SendRtpItem> result= new ArrayList<>();
        for (Object o : queryResult) {
            String keyItem = (String) o;
            result.add((SendRtpItem) RedisUtil.get(keyItem));
            result.add((SendRtpItem) redisTemplate.opsForValue().get(keyItem));
        }
        return result;
@@ -520,47 +519,42 @@
    /**
     * 查询某个通道是否存在上级点播(RTP推送)
     * @param channelId
     */
    @Override
    public boolean isChannelSendingRTP(String channelId) {
        String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX
                + userSetting.getServerId() + "_*_*_"
                + channelId + "*_" + "*_";
        List<Object> RtpStreams = RedisUtil.scan(key);
        if (RtpStreams.size() > 0) {
            return true;
        } else {
            return false;
        }
        List<Object> RtpStreams = RedisUtil.scan(redisTemplate, key);
        return RtpStreams.size() > 0;
    }
    @Override
    public void clearCatchByDeviceId(String deviceId) {
        List<Object> playLeys = RedisUtil.scan(String.format("%S_%s_*_%s_*", VideoManagerConstants.PLAYER_PREFIX,
        List<Object> playLeys = RedisUtil.scan(redisTemplate, String.format("%S_%s_*_%s_*", VideoManagerConstants.PLAYER_PREFIX,
                userSetting.getServerId(),
                deviceId));
        if (playLeys.size() > 0) {
            for (Object key : playLeys) {
                RedisUtil.del(key.toString());
                redisTemplate.delete(key.toString());
            }
        }
        List<Object> playBackers = RedisUtil.scan(String.format("%S_%s_*_%s_*_*_*", VideoManagerConstants.PLAY_BLACK_PREFIX,
        List<Object> playBackers = RedisUtil.scan(redisTemplate, String.format("%S_%s_*_%s_*_*_*", VideoManagerConstants.PLAY_BLACK_PREFIX,
                userSetting.getServerId(),
                deviceId));
        if (playBackers.size() > 0) {
            for (Object key : playBackers) {
                RedisUtil.del(key.toString());
                redisTemplate.delete(key.toString());
            }
        }
        List<Object> deviceCache = RedisUtil.scan(String.format("%S%s_%s", VideoManagerConstants.DEVICE_PREFIX,
        List<Object> deviceCache = RedisUtil.scan(redisTemplate, String.format("%S%s_%s", VideoManagerConstants.DEVICE_PREFIX,
                userSetting.getServerId(),
                deviceId));
        if (deviceCache.size() > 0) {
            for (Object key : deviceCache) {
                RedisUtil.del(key.toString());
                redisTemplate.delete(key.toString());
            }
        }
    }
@@ -568,14 +562,14 @@
    @Override
    public void updateWVPInfo(JSONObject jsonObject, int time) {
        String key = VideoManagerConstants.WVP_SERVER_PREFIX + userSetting.getServerId();
        RedisUtil.set(key, jsonObject, time);
        redisTemplate.opsForValue().set(key, jsonObject, time);
    }
    @Override
    public void sendStreamChangeMsg(String type, JSONObject jsonObject) {
        String key = VideoManagerConstants.WVP_MSG_STREAM_CHANGE_PREFIX + type;
        logger.info("[redis 流变化事件] {}: {}", key, jsonObject.toString());
        RedisUtil.convertAndSend(key, jsonObject);
        redisTemplate.convertAndSend(key, jsonObject);
    }
    @Override
@@ -586,13 +580,13 @@
        if (streamAuthorityInfo != null) {
            onStreamChangedHookParam.setCallId(streamAuthorityInfo.getCallId());
        }
        RedisUtil.set(key, onStreamChangedHookParam);
        redisTemplate.opsForValue().set(key, onStreamChangedHookParam);
    }
    @Override
    public void removeStream(String mediaServerId, String type, String app, String streamId) {
        String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetting.getServerId() + "_" + type + "_"  + app + "_" + streamId + "_" + mediaServerId;
        RedisUtil.del(key);
        redisTemplate.delete(key);
    }
    @Override
@@ -619,9 +613,9 @@
                stream,
                callId
        );
        List<Object> streamInfoScan = RedisUtil.scan2(key);
        List<Object> streamInfoScan = RedisUtil.scan(redisTemplate, key);
        if (streamInfoScan.size() > 0) {
            return (StreamInfo) RedisUtil.get((String) streamInfoScan.get(0));
            return (StreamInfo) redisTemplate.opsForValue().get(streamInfoScan.get(0));
        }else {
            return null;
        }
@@ -630,15 +624,15 @@
    @Override
    public ThirdPartyGB queryMemberNoGBId(String queryKey) {
        String key = VideoManagerConstants.WVP_STREAM_GB_ID_PREFIX + queryKey;
        return JsonUtil.redisJsonToObject(key, ThirdPartyGB.class);
        return JsonUtil.redisJsonToObject(redisTemplate, key, ThirdPartyGB.class);
    }
    @Override
    public void removeStream(String mediaServerId, String type) {
        String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetting.getServerId() + "_" + type + "_*_*_" + mediaServerId;
        List<Object> streams = RedisUtil.scan(key);
        List<Object> streams = RedisUtil.scan(redisTemplate, key);
        for (Object stream : streams) {
            RedisUtil.del((String) stream);
            redisTemplate.delete(stream);
        }
    }
@@ -646,9 +640,9 @@
    public List<OnStreamChangedHookParam> getStreams(String mediaServerId, String type) {
        List<OnStreamChangedHookParam> result = new ArrayList<>();
        String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetting.getServerId() + "_" + type + "_*_*_" + mediaServerId;
        List<Object> streams = RedisUtil.scan(key);
        List<Object> streams = RedisUtil.scan(redisTemplate, key);
        for (Object stream : streams) {
            OnStreamChangedHookParam onStreamChangedHookParam = (OnStreamChangedHookParam)RedisUtil.get((String) stream);
            OnStreamChangedHookParam onStreamChangedHookParam = (OnStreamChangedHookParam)redisTemplate.opsForValue().get(stream);
            result.add(onStreamChangedHookParam);
        }
        return result;
@@ -657,21 +651,21 @@
    @Override
    public void updateDevice(Device device) {
        String key = VideoManagerConstants.DEVICE_PREFIX + userSetting.getServerId() + "_" + device.getDeviceId();
        RedisUtil.set(key, device);
        redisTemplate.opsForValue().set(key, device);
    }
    @Override
    public void removeDevice(String deviceId) {
        String key = VideoManagerConstants.DEVICE_PREFIX + userSetting.getServerId() + "_" + deviceId;
        RedisUtil.del(key);
        redisTemplate.delete(key);
    }
    @Override
    public void removeAllDevice() {
        String scanKey = VideoManagerConstants.DEVICE_PREFIX + userSetting.getServerId() + "_*";
        List<Object> keys = RedisUtil.scan(scanKey);
        List<Object> keys = RedisUtil.scan(redisTemplate, scanKey);
        for (Object key : keys) {
            RedisUtil.del((String) key);
            redisTemplate.delete(key);
        }
    }
@@ -679,12 +673,12 @@
    public List<Device> getAllDevices() {
        String scanKey = VideoManagerConstants.DEVICE_PREFIX + userSetting.getServerId() + "_*";
        List<Device> result = new ArrayList<>();
        List<Object> keys = RedisUtil.scan(scanKey);
        List<Object> keys = RedisUtil.scan(redisTemplate, scanKey);
        for (Object o : keys) {
            String key = (String) o;
            Device device = JsonUtil.redisJsonToObject(key, Device.class);
            Device device = JsonUtil.redisJsonToObject(redisTemplate, key, Device.class);
            if (Objects.nonNull(device)) { // 只取没有存过得
                result.add(JsonUtil.redisJsonToObject(key, Device.class));
                result.add(JsonUtil.redisJsonToObject(redisTemplate, key, Device.class));
            }
        }
@@ -694,31 +688,31 @@
    @Override
    public Device getDevice(String deviceId) {
        String key = VideoManagerConstants.DEVICE_PREFIX + userSetting.getServerId() + "_" + deviceId;
        return JsonUtil.redisJsonToObject(key, Device.class);
        return JsonUtil.redisJsonToObject(redisTemplate, key, Device.class);
    }
    @Override
    public void updateGpsMsgInfo(GPSMsgInfo gpsMsgInfo) {
        String key = VideoManagerConstants.WVP_STREAM_GPS_MSG_PREFIX + userSetting.getServerId() + "_" + gpsMsgInfo.getId();
        RedisUtil.set(key, gpsMsgInfo, 60); // 默认GPS消息保存1分钟
        redisTemplate.opsForValue().set(key, gpsMsgInfo, 60); // 默认GPS消息保存1分钟
    }
    @Override
    public GPSMsgInfo getGpsMsgInfo(String gbId) {
        String key = VideoManagerConstants.WVP_STREAM_GPS_MSG_PREFIX + userSetting.getServerId() + "_" + gbId;
        return JsonUtil.redisJsonToObject(key, GPSMsgInfo.class);
        return JsonUtil.redisJsonToObject(redisTemplate, key, GPSMsgInfo.class);
    }
    @Override
    public List<GPSMsgInfo> getAllGpsMsgInfo() {
        String scanKey = VideoManagerConstants.WVP_STREAM_GPS_MSG_PREFIX + userSetting.getServerId() + "_*";
        List<GPSMsgInfo> result = new ArrayList<>();
        List<Object> keys = RedisUtil.scan(scanKey);
        List<Object> keys = RedisUtil.scan(redisTemplate, scanKey);
        for (Object o : keys) {
            String key = (String) o;
            GPSMsgInfo gpsMsgInfo = JsonUtil.redisJsonToObject(key, GPSMsgInfo.class);
            GPSMsgInfo gpsMsgInfo = JsonUtil.redisJsonToObject(redisTemplate, key, GPSMsgInfo.class);
            if (Objects.nonNull(gpsMsgInfo) && !gpsMsgInfo.isStored()) { // 只取没有存过得
                result.add(JsonUtil.redisJsonToObject(key, GPSMsgInfo.class));
                result.add(JsonUtil.redisJsonToObject(redisTemplate, key, GPSMsgInfo.class));
            }
        }
@@ -728,19 +722,19 @@
    @Override
    public void updateStreamAuthorityInfo(String app, String stream, StreamAuthorityInfo streamAuthorityInfo) {
        String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream;
        RedisUtil.set(key, streamAuthorityInfo);
        redisTemplate.opsForValue().set(key, streamAuthorityInfo);
    }
    @Override
    public void removeStreamAuthorityInfo(String app, String stream) {
        String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream ;
        RedisUtil.del(key);
        redisTemplate.delete(key);
    }
    @Override
    public StreamAuthorityInfo getStreamAuthorityInfo(String app, String stream) {
        String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream ;
        return JsonUtil.redisJsonToObject(key, StreamAuthorityInfo.class);
        return JsonUtil.redisJsonToObject(redisTemplate, key, StreamAuthorityInfo.class);
    }
@@ -748,10 +742,10 @@
    public List<StreamAuthorityInfo> getAllStreamAuthorityInfo() {
        String scanKey = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_*_*" ;
        List<StreamAuthorityInfo> result = new ArrayList<>();
        List<Object> keys = RedisUtil.scan(scanKey);
        List<Object> keys = RedisUtil.scan(redisTemplate, scanKey);
        for (Object o : keys) {
            String key = (String) o;
            result.add(JsonUtil.redisJsonToObject(key, StreamAuthorityInfo.class));
            result.add(JsonUtil.redisJsonToObject(redisTemplate, key, StreamAuthorityInfo.class));
        }
        return result;
    }
@@ -762,10 +756,10 @@
        String scanKey = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX  + userSetting.getServerId() + "_*_" + app + "_" + streamId + "_" + mediaServerId;
        OnStreamChangedHookParam result = null;
        List<Object> keys = RedisUtil.scan(scanKey);
        List<Object> keys = RedisUtil.scan(redisTemplate, scanKey);
        if (keys.size() > 0) {
            String key = (String) keys.get(0);
            result = JsonUtil.redisJsonToObject(key, OnStreamChangedHookParam.class);
            result = JsonUtil.redisJsonToObject(redisTemplate, key, OnStreamChangedHookParam.class);
        }
        return result;
@@ -776,12 +770,13 @@
        String key = VideoManagerConstants.SYSTEM_INFO_CPU_PREFIX + userSetting.getServerId();
        Map<String, String> infoMap = new HashMap<>();
        infoMap.put("time", DateUtil.getNow());
        infoMap.put("data", cpuInfo + "");
        RedisUtil.lSet(key, infoMap);
        infoMap.put("data", String.valueOf(cpuInfo));
        redisTemplate.opsForList().rightPush(key, infoMap);
        // 每秒一个,最多只存30个
        if (RedisUtil.lGetListSize(key) >= 30) {
            for (int i = 0; i < RedisUtil.lGetListSize(key) - 30; i++) {
                RedisUtil.lLeftPop(key);
        Long size = redisTemplate.opsForList().size(key);
        if (size != null && size >= 30) {
            for (int i = 0; i < size - 30; i++) {
                redisTemplate.opsForList().leftPop(key);
            }
        }
    }
@@ -791,12 +786,13 @@
        String key = VideoManagerConstants.SYSTEM_INFO_MEM_PREFIX + userSetting.getServerId();
        Map<String, String> infoMap = new HashMap<>();
        infoMap.put("time", DateUtil.getNow());
        infoMap.put("data", memInfo + "");
        RedisUtil.lSet(key, infoMap);
        infoMap.put("data", String.valueOf(memInfo));
        redisTemplate.opsForList().rightPush(key, infoMap);
        // 每秒一个,最多只存30个
        if (RedisUtil.lGetListSize(key) >= 30) {
            for (int i = 0; i < RedisUtil.lGetListSize(key) - 30; i++) {
                RedisUtil.lLeftPop(key);
        Long size = redisTemplate.opsForList().size(key);
        if (size != null && size >= 30) {
            for (int i = 0; i < size - 30; i++) {
                redisTemplate.opsForList().leftPop(key);
            }
        }
    }
@@ -809,11 +805,12 @@
        for (String netKey : networkInterfaces.keySet()) {
            infoMap.put(netKey, networkInterfaces.get(netKey));
        }
        RedisUtil.lSet(key, infoMap);
        redisTemplate.opsForList().rightPush(key, infoMap);
        // 每秒一个,最多只存30个
        if (RedisUtil.lGetListSize(key) >= 30) {
            for (int i = 0; i < RedisUtil.lGetListSize(key) - 30; i++) {
                RedisUtil.lLeftPop(key);
        Long size = redisTemplate.opsForList().size(key);
        if (size != null && size >= 30) {
            for (int i = 0; i < size - 30; i++) {
                redisTemplate.opsForList().leftPop(key);
            }
        }
    }
@@ -822,7 +819,7 @@
    public void addDiskInfo(List<Map<String, Object>> diskInfo) {
        String key = VideoManagerConstants.SYSTEM_INFO_DISK_PREFIX + userSetting.getServerId();
        RedisUtil.set(key, diskInfo);
        redisTemplate.opsForValue().set(key, diskInfo);
    }
    @Override
@@ -832,11 +829,11 @@
        String netKey = VideoManagerConstants.SYSTEM_INFO_NET_PREFIX + userSetting.getServerId();
        String diskKey = VideoManagerConstants.SYSTEM_INFO_DISK_PREFIX + userSetting.getServerId();
        SystemAllInfo systemAllInfo = new SystemAllInfo();
        systemAllInfo.setCpu(RedisUtil.lGet(cpuKey, 0, -1));
        systemAllInfo.setMem(RedisUtil.lGet(memKey, 0, -1));
        systemAllInfo.setNet(RedisUtil.lGet(netKey, 0, -1));
        systemAllInfo.setCpu(redisTemplate.opsForList().range(cpuKey, 0, -1));
        systemAllInfo.setMem(redisTemplate.opsForList().range(memKey, 0, -1));
        systemAllInfo.setNet(redisTemplate.opsForList().range(netKey, 0, -1));
        systemAllInfo.setDisk(RedisUtil.get(diskKey));
        systemAllInfo.setDisk(redisTemplate.opsForValue().get(diskKey));
        systemAllInfo.setNetTotal(SystemInfoUtils.getNetworkTotal());
        return systemAllInfo;
    }
@@ -845,14 +842,14 @@
    public void sendMobilePositionMsg(JSONObject jsonObject) {
        String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_MOBILE_POSITION;
        logger.info("[redis发送通知] 移动位置 {}: {}", key, jsonObject.toString());
        RedisUtil.convertAndSend(key, jsonObject);
        redisTemplate.convertAndSend(key, jsonObject);
    }
    @Override
    public void sendStreamPushRequestedMsg(MessageForPushChannel msg) {
        String key = VideoManagerConstants.VM_MSG_STREAM_PUSH_REQUESTED;
        logger.info("[redis发送通知] 推流被请求 {}: {}/{}", key, msg.getApp(), msg.getStream());
        RedisUtil.convertAndSend(key, (JSONObject)JSON.toJSON(msg));
        redisTemplate.convertAndSend(key, JSON.toJSON(msg));
    }
    @Override
@@ -860,7 +857,7 @@
        // 此消息用于对接第三方服务下级来的消息内容
        String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM;
        logger.info("[redis发送通知] 报警{}: {}", key, JSON.toJSON(msg));
        RedisUtil.convertAndSend(key, (JSONObject)JSON.toJSON(msg));
        redisTemplate.convertAndSend(key, JSON.toJSON(msg));
    }
    @Override
@@ -875,19 +872,19 @@
        logger.info("[redis通知]获取所有推流设备的状态");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(key, key);
        RedisUtil.convertAndSend(key, jsonObject);
        redisTemplate.convertAndSend(key, jsonObject);
    }
    @Override
    public int getPushStreamCount(String id) {
        String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetting.getServerId() + "_PUSH_*_*_" + id;
        return RedisUtil.scan(key).size();
        return RedisUtil.scan(redisTemplate, key).size();
    }
    @Override
    public int getProxyStreamCount(String id) {
        String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetting.getServerId() + "_PULL_*_*_" + id;
        return RedisUtil.scan(key).size();
        return RedisUtil.scan(redisTemplate, key).size();
    }
    @Override
@@ -896,13 +893,13 @@
        String playBackKey = VideoManagerConstants.PLAY_BLACK_PREFIX + "_" + userSetting.getServerId() + "_" + id + "_*";
        String downloadKey = VideoManagerConstants.DOWNLOAD_PREFIX + "_" + userSetting.getServerId() + "_" + id + "_*";
        return RedisUtil.scan(playKey).size() + RedisUtil.scan(playBackKey).size() + RedisUtil.scan(downloadKey).size();
        return RedisUtil.scan(redisTemplate, playKey).size() + RedisUtil.scan(redisTemplate, playBackKey).size() + RedisUtil.scan(redisTemplate, downloadKey).size();
    }
    @Override
    public int getGbSendCount(String id) {
        String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX
                + userSetting.getServerId() + "_*_" + id + "_*";
        return RedisUtil.scan(key).size();
        return RedisUtil.scan(redisTemplate, key).size();
    }
}
src/main/java/com/genersoft/iot/vmp/utils/JsonUtil.java
@@ -1,8 +1,6 @@
package com.genersoft.iot.vmp.utils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.Objects;
@@ -26,8 +24,8 @@
     * @param <T>
     * @return result type
     */
    public static <T> T redisJsonToObject(String key, Class<T> clazz) {
        Object jsonObject = RedisUtil.get(key);
    public static <T> T redisJsonToObject(RedisTemplate<Object, Object> redisTemplate, String key, Class<T> clazz) {
        Object jsonObject = redisTemplate.opsForValue().get(key);
        if (Objects.isNull(jsonObject)) {
            return null;
        }
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
@@ -1,873 +1,32 @@
package com.genersoft.iot.vmp.utils.redis;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
import org.springframework.data.redis.core.*;
import org.springframework.util.CollectionUtils;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
/**
 * Redis工具类
 *
 * @author swwheihei
 * @date 2020年5月6日 下午8:27:29
 */
@SuppressWarnings(value = {"rawtypes", "unchecked"})
public class RedisUtil {
    private static RedisTemplate redisTemplate;
    static {
        redisTemplate = SpringBeanFactory.getBean("redisTemplate");
    }
    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return true / false
     */
    public static boolean expire(String key, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据 key 获取过期时间
     * @param key 键
     */
    public static long getExpire(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
    /**
     * 判断 key 是否存在
     * @param key 键
     * @return true / false
     */
    public static boolean hasKey(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除缓存
     * @SuppressWarnings("unchecked") 忽略类型转换警告
     * @param key 键(一个或者多个)
     */
    public static boolean del(String... key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            if (key != null && key.length > 0) {
                if (key.length == 1) {
                    redisTemplate.delete(key[0]);
                } else {
//                    传入一个 Collection<String> 集合
                    redisTemplate.delete(CollectionUtils.arrayToList(key));
                }
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
//    ============================== String ==============================
    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public static Object get(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }
    /**
     * 普通缓存放入
     * @param key 键
     * @param value 值
     * @return true / false
     */
    public static boolean set(String key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 普通缓存放入并设置时间
     * @param key 键
     * @param value 值
     * @param time 时间(秒),如果 time < 0 则设置无限时间
     * @return true / false
     */
    public static boolean set(String key, Object value, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 递增
     * @param key 键
     * @param delta 递增大小
     * @return
     */
    public static long incr(String key, long delta) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于 0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
    /**
     * 递减
     * @param key 键
     * @param delta 递减大小
     * @return
     */
    public static long decr(String key, long delta) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于 0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
//    ============================== Map ==============================
    /**
     * HashGet
     * @param key 键(no null)
     * @param item 项(no null)
     * @return 值
     */
    public static Object hget(String key, String item) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForHash().get(key, item);
    }
    /**
     * 获取 key 对应的 map
     * @param key 键(no null)
     * @return 对应的多个键值
     */
    public static Map<Object, Object> hmget(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * HashSet
     * @param key 键
     * @param map 值
     * @return true / false
     */
    public static boolean hmset(String key, Map<Object, Object> map) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * HashSet 并设置时间
     * @param key 键
     * @param map 值
     * @param time 时间
     * @return true / false
     */
    public static boolean hmset(String key, Map<?, ?> map, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张 Hash表 中放入数据,如不存在则创建
     * @param key 键
     * @param item 项
     * @param value 值
     * @return true / false
     */
    public static boolean hset(String key, String item, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张 Hash表 中放入数据,并设置时间,如不存在则创建
     * @param key 键
     * @param item 项
     * @param value 值
     * @param time 时间(如果原来的 Hash表 设置了时间,这里会覆盖)
     * @return true / false
     */
    public static boolean hset(String key, String item, Object value, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除 Hash表 中的值
     * @param key 键
     * @param item 项(可以多个,no null)
     */
    public static void hdel(String key, Object... item) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        redisTemplate.opsForHash().delete(key, item);
    }
    /**
     * 判断 Hash表 中是否有该键的值
     * @param key 键(no null)
     * @param item 值(no null)
     * @return true / false
     */
    public static boolean hHasKey(String key, String item) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForHash().hasKey(key, item);
    }
    /**
     * Hash递增,如果不存在则创建一个,并把新增的值返回
     * @param key 键
     * @param item 项
     * @param by 递增大小 > 0
     * @return
     */
    public static Double hincr(String key, String item, Double by) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForHash().increment(key, item, by);
    }
    /**
     * Hash递减
     * @param key 键
     * @param item 项
     * @param by 递减大小
     * @return
     */
    public static Double hdecr(String key, String item, Double by) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForHash().increment(key, item, -by);
    }
//    ============================== Set ==============================
    /**
     * 根据 key 获取 set 中的所有值
     * @param key 键
     * @return 值
     */
    public static Set<Object> sGet(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 从键为 key 的 set 中,根据 value 查询是否存在
     * @param key 键
     * @param value 值
     * @return true / false
     */
    public static boolean sHasKey(String key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将数据放入 set缓存
     * @param key 键值
     * @param values 值(可以多个)
     * @return 成功个数
     */
    public static long sSet(String key, Object... values) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 将数据放入 set缓存,并设置时间
     * @param key 键
     * @param time 时间
     * @param values 值(可以多个)
     * @return 成功放入个数
     */
    public static long sSet(String key, long time, Object... values) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 获取 set缓存的长度
     * @param key 键
     * @return 长度
     */
    public static long sGetSetSize(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 移除 set缓存中,值为 value 的
     * @param key 键
     * @param values 值
     * @return 成功移除个数
     */
    public static long setRemove(String key, Object... values) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForSet().remove(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
//    ============================== ZSet ==============================
    /**
     * 添加一个元素, zset与set最大的区别就是每个元素都有一个score,因此有个排序的辅助功能;  zadd
     *
     * @param key
     * @param value
     * @param score
     */
    public static void zAdd(Object key, Object value, double score) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        redisTemplate.opsForZSet().add(key, value, score);
    }
    /**
     * 删除元素 zrem
     *
     * @param key
     * @param value
     */
    public static void zRemove(Object key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        redisTemplate.opsForZSet().remove(key, value);
    }
    /**
     * score的增加or减少 zincrby
     *
     * @param key
     * @param value
     * @param delta -1 表示减 1 表示加1
     */
    public static Double zIncrScore(Object key, Object value, double delta) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().incrementScore(key, value, delta);
    }
    /**
     * 查询value对应的score   zscore
     *
     * @param key
     * @param value
     * @return
     */
    public static Double zScore(Object key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().score(key, value);
    }
    /**
     * 判断value在zset中的排名  zrank
     *
     * @param key
     * @param value
     * @return
     */
    public static Long zRank(Object key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().rank(key, value);
    }
    /**
     * 返回集合的长度
     *
     * @param key
     * @return
     */
    public static Long zSize(Object key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().zCard(key);
    }
    /**
     * 查询集合中指定顺序的值, 0 -1 表示获取全部的集合内容  zrange
     *
     * 返回有序的集合,score小的在前面
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public static Set<Object> zRange(Object key, int start, int end) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().range(key, start, end);
    }
    /**
     * 查询集合中指定顺序的值和score,0, -1 表示获取全部的集合内容
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public static Set<ZSetOperations.TypedTuple<String>> zRangeWithScore(Object key, int start, int end) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().rangeWithScores(key, start, end);
    }
    /**
     * 查询集合中指定顺序的值  zrevrange
     *
     * 返回有序的集合中,score大的在前面
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public static Set<String> zRevRange(Object key, int start, int end) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().reverseRange(key, start, end);
    }
    /**
     * 根据score的值,来获取满足条件的集合  zrangebyscore
     *
     * @param key
     * @param min
     * @param max
     * @return
     */
    public static Set<String> zSortRange(Object key, int min, int max) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().rangeByScore(key, min, max);
    }
//    ============================== List ==============================
    /**
     * 获取 list缓存的内容
     * @param key 键
     * @param start 开始
     * @param end 结束(0 到 -1 代表所有值)
     * @return
     */
    public static List<Object> lGet(String key, long start, long end) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 获取 list缓存的长度
     * @param key 键
     * @return 长度
     */
    public static long lGetListSize(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 根据索引 index 获取键为 key 的 list 中的元素
     * @param key 键
     * @param index 索引
     *              当 index >= 0 时 {0:表头, 1:第二个元素}
     *              当 index < 0 时 {-1:表尾, -2:倒数第二个元素}
     * @return 值
     */
    public static Object lGetIndex(String key, long index) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 将值 value 插入键为 key 的 list 中,如果 list 不存在则创建空 list
     * @param key 键
     * @param value 值
     * @return true / false
     */
    public static boolean lSet(String key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将值 value 插入键为 key 的 list 中,并设置时间
     * @param key 键
     * @param value 值
     * @param time 时间
     * @return true / false
     */
    public static boolean lSet(String key, Object value, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将 values 插入键为 key 的 list 中
     * @param key 键
     * @param values 值
     * @return true / false
     */
    public static boolean lSetList(String key, List<Object> values) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForList().rightPushAll(key, values);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将 values 插入键为 key 的 list 中,并设置时间
     * @param key 键
     * @param values 值
     * @param time 时间
     * @return true / false
     */
    public static boolean lSetList(String key, List<Object> values, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForList().rightPushAll(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据索引 index 修改键为 key 的值
     * @param key 键
     * @param index 索引
     * @param value 值
     * @return true / false
     */
    public static boolean lUpdateIndex(String key, long index, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 在键为 key 的 list 中删除值为 value 的元素
     * @param key 键
     * @param count 如果 count == 0 则删除 list 中所有值为 value 的元素
     *              如果 count > 0 则删除 list 中最左边那个值为 value 的元素
     *              如果 count < 0 则删除 list 中最右边那个值为 value 的元素
     * @param value
     * @return
     */
    public static long lRemove(String key, long count, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForList().remove(key, count, value);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 在键为 key 的 list中移除第一个元素
     * @param key 键
     * @return
     */
    public static Object lLeftPop(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForList().leftPop(key);
    }
    /**
     * 在键为 key 的 list中移除、最后一个元素
     * @param key 键
     * @return
     */
    public static Object lrightPop(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForList().rightPop(key);
    }
    /**
     * 模糊查询
     * @param key 键
     * @return true / false
     */
    public static List<Object> keys(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            Set<String> set = redisTemplate.keys(key);
            return new ArrayList<>(set);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 模糊查询
     *
     * @param query 查询参数
     * @return
     */
//    public static List<Object> scan(String query) {
//        List<Object> result = new ArrayList<>();
//        try {
//            Cursor<Map.Entry<Object,Object>> cursor = redisTemplate.opsForHash().scan("field",
//                    ScanOptions.scanOptions().match(query).count(1000).build());
//            while (cursor.hasNext()) {
//                Map.Entry<Object,Object> entry = cursor.next();
//                result.add(entry.getKey());
//                Object key = entry.getKey();
//                Object valueSet = entry.getValue();
//            }
//            //关闭cursor
//            cursor.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return result;
//    }
    public static List<Object> scan(RedisTemplate redisTemplate, String query) {
    /**
     * 模糊查询
     * @param query 查询参数
     * @return
     */
    public static List<Object> scan(String query) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        Set<String> resultKeys = (Set<String>) redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
            ScanOptions scanOptions = ScanOptions.scanOptions().match("*" + query + "*").count(1000).build();
            Cursor<byte[]> scan = connection.scan(scanOptions);
@@ -881,19 +40,7 @@
        return new ArrayList<>(resultKeys);
    }
    public static List<Object> scan2(String query) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        Set<String> keys = redisTemplate.keys(query);
        return new ArrayList<>(keys);
    }
    //    ============================== 消息发送与订阅 ==============================
    public static void convertAndSend(String channel, JSONObject msg) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        redisTemplate.convertAndSend(channel, msg);
    }
}
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil2.java
New file
@@ -0,0 +1,899 @@
package com.genersoft.iot.vmp.utils.redis;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
import org.springframework.data.redis.core.*;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
 * Redis工具类
 * @author swwheihei
 * @date 2020年5月6日 下午8:27:29
 */
@SuppressWarnings(value = {"rawtypes", "unchecked"})
public class RedisUtil2 {
    private static RedisTemplate redisTemplate;
    static {
        redisTemplate = SpringBeanFactory.getBean("redisTemplate");
    }
    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return true / false
     */
    public static boolean expire(String key, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据 key 获取过期时间
     * @param key 键
     */
    public static long getExpire(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
    /**
     * 判断 key 是否存在
     * @param key 键
     * @return true / false
     */
    public static boolean hasKey(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除缓存
     * @SuppressWarnings("unchecked") 忽略类型转换警告
     * @param key 键(一个或者多个)
     */
    public static boolean del(String... key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            if (key != null && key.length > 0) {
                if (key.length == 1) {
                    redisTemplate.delete(key[0]);
                } else {
//                    传入一个 Collection<String> 集合
                    redisTemplate.delete(CollectionUtils.arrayToList(key));
                }
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
//    ============================== String ==============================
    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public static Object get(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }
    /**
     * 普通缓存放入
     * @param key 键
     * @param value 值
     * @return true / false
     */
    public static boolean set(String key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 普通缓存放入并设置时间
     * @param key 键
     * @param value 值
     * @param time 时间(秒),如果 time < 0 则设置无限时间
     * @return true / false
     */
    public static boolean set(String key, Object value, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 递增
     * @param key 键
     * @param delta 递增大小
     * @return
     */
    public static long incr(String key, long delta) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于 0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
    /**
     * 递减
     * @param key 键
     * @param delta 递减大小
     * @return
     */
    public static long decr(String key, long delta) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于 0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
//    ============================== Map ==============================
    /**
     * HashGet
     * @param key 键(no null)
     * @param item 项(no null)
     * @return 值
     */
    public static Object hget(String key, String item) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForHash().get(key, item);
    }
    /**
     * 获取 key 对应的 map
     * @param key 键(no null)
     * @return 对应的多个键值
     */
    public static Map<Object, Object> hmget(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * HashSet
     * @param key 键
     * @param map 值
     * @return true / false
     */
    public static boolean hmset(String key, Map<Object, Object> map) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * HashSet 并设置时间
     * @param key 键
     * @param map 值
     * @param time 时间
     * @return true / false
     */
    public static boolean hmset(String key, Map<?, ?> map, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张 Hash表 中放入数据,如不存在则创建
     * @param key 键
     * @param item 项
     * @param value 值
     * @return true / false
     */
    public static boolean hset(String key, String item, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张 Hash表 中放入数据,并设置时间,如不存在则创建
     * @param key 键
     * @param item 项
     * @param value 值
     * @param time 时间(如果原来的 Hash表 设置了时间,这里会覆盖)
     * @return true / false
     */
    public static boolean hset(String key, String item, Object value, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除 Hash表 中的值
     * @param key 键
     * @param item 项(可以多个,no null)
     */
    public static void hdel(String key, Object... item) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        redisTemplate.opsForHash().delete(key, item);
    }
    /**
     * 判断 Hash表 中是否有该键的值
     * @param key 键(no null)
     * @param item 值(no null)
     * @return true / false
     */
    public static boolean hHasKey(String key, String item) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForHash().hasKey(key, item);
    }
    /**
     * Hash递增,如果不存在则创建一个,并把新增的值返回
     * @param key 键
     * @param item 项
     * @param by 递增大小 > 0
     * @return
     */
    public static Double hincr(String key, String item, Double by) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForHash().increment(key, item, by);
    }
    /**
     * Hash递减
     * @param key 键
     * @param item 项
     * @param by 递减大小
     * @return
     */
    public static Double hdecr(String key, String item, Double by) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForHash().increment(key, item, -by);
    }
//    ============================== Set ==============================
    /**
     * 根据 key 获取 set 中的所有值
     * @param key 键
     * @return 值
     */
    public static Set<Object> sGet(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 从键为 key 的 set 中,根据 value 查询是否存在
     * @param key 键
     * @param value 值
     * @return true / false
     */
    public static boolean sHasKey(String key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将数据放入 set缓存
     * @param key 键值
     * @param values 值(可以多个)
     * @return 成功个数
     */
    public static long sSet(String key, Object... values) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 将数据放入 set缓存,并设置时间
     * @param key 键
     * @param time 时间
     * @param values 值(可以多个)
     * @return 成功放入个数
     */
    public static long sSet(String key, long time, Object... values) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 获取 set缓存的长度
     * @param key 键
     * @return 长度
     */
    public static long sGetSetSize(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 移除 set缓存中,值为 value 的
     * @param key 键
     * @param values 值
     * @return 成功移除个数
     */
    public static long setRemove(String key, Object... values) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForSet().remove(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
//    ============================== ZSet ==============================
    /**
     * 添加一个元素, zset与set最大的区别就是每个元素都有一个score,因此有个排序的辅助功能;  zadd
     *
     * @param key
     * @param value
     * @param score
     */
    public static void zAdd(Object key, Object value, double score) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        redisTemplate.opsForZSet().add(key, value, score);
    }
    /**
     * 删除元素 zrem
     *
     * @param key
     * @param value
     */
    public static void zRemove(Object key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        redisTemplate.opsForZSet().remove(key, value);
    }
    /**
     * score的增加or减少 zincrby
     *
     * @param key
     * @param value
     * @param delta -1 表示减 1 表示加1
     */
    public static Double zIncrScore(Object key, Object value, double delta) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().incrementScore(key, value, delta);
    }
    /**
     * 查询value对应的score   zscore
     *
     * @param key
     * @param value
     * @return
     */
    public static Double zScore(Object key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().score(key, value);
    }
    /**
     * 判断value在zset中的排名  zrank
     *
     * @param key
     * @param value
     * @return
     */
    public static Long zRank(Object key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().rank(key, value);
    }
    /**
     * 返回集合的长度
     *
     * @param key
     * @return
     */
    public static Long zSize(Object key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().zCard(key);
    }
    /**
     * 查询集合中指定顺序的值, 0 -1 表示获取全部的集合内容  zrange
     *
     * 返回有序的集合,score小的在前面
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public static Set<Object> zRange(Object key, int start, int end) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().range(key, start, end);
    }
    /**
     * 查询集合中指定顺序的值和score,0, -1 表示获取全部的集合内容
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public static Set<ZSetOperations.TypedTuple<String>> zRangeWithScore(Object key, int start, int end) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().rangeWithScores(key, start, end);
    }
    /**
     * 查询集合中指定顺序的值  zrevrange
     *
     * 返回有序的集合中,score大的在前面
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public static Set<String> zRevRange(Object key, int start, int end) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().reverseRange(key, start, end);
    }
    /**
     * 根据score的值,来获取满足条件的集合  zrangebyscore
     *
     * @param key
     * @param min
     * @param max
     * @return
     */
    public static Set<String> zSortRange(Object key, int min, int max) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForZSet().rangeByScore(key, min, max);
    }
//    ============================== List ==============================
    /**
     * 获取 list缓存的内容
     * @param key 键
     * @param start 开始
     * @param end 结束(0 到 -1 代表所有值)
     * @return
     */
    public static List<Object> lGet(String key, long start, long end) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 获取 list缓存的长度
     * @param key 键
     * @return 长度
     */
    public static long lGetListSize(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 根据索引 index 获取键为 key 的 list 中的元素
     * @param key 键
     * @param index 索引
     *              当 index >= 0 时 {0:表头, 1:第二个元素}
     *              当 index < 0 时 {-1:表尾, -2:倒数第二个元素}
     * @return 值
     */
    public static Object lGetIndex(String key, long index) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 将值 value 插入键为 key 的 list 中,如果 list 不存在则创建空 list
     * @param key 键
     * @param value 值
     * @return true / false
     */
    public static boolean lSet(String key, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将值 value 插入键为 key 的 list 中,并设置时间
     * @param key 键
     * @param value 值
     * @param time 时间
     * @return true / false
     */
    public static boolean lSet(String key, Object value, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将 values 插入键为 key 的 list 中
     * @param key 键
     * @param values 值
     * @return true / false
     */
    public static boolean lSetList(String key, List<Object> values) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForList().rightPushAll(key, values);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将 values 插入键为 key 的 list 中,并设置时间
     * @param key 键
     * @param values 值
     * @param time 时间
     * @return true / false
     */
    public static boolean lSetList(String key, List<Object> values, long time) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForList().rightPushAll(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据索引 index 修改键为 key 的值
     * @param key 键
     * @param index 索引
     * @param value 值
     * @return true / false
     */
    public static boolean lUpdateIndex(String key, long index, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 在键为 key 的 list 中删除值为 value 的元素
     * @param key 键
     * @param count 如果 count == 0 则删除 list 中所有值为 value 的元素
     *              如果 count > 0 则删除 list 中最左边那个值为 value 的元素
     *              如果 count < 0 则删除 list 中最右边那个值为 value 的元素
     * @param value
     * @return
     */
    public static long lRemove(String key, long count, Object value) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            return redisTemplate.opsForList().remove(key, count, value);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 在键为 key 的 list中移除第一个元素
     * @param key 键
     * @return
     */
    public static Object lLeftPop(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForList().leftPop(key);
    }
    /**
     * 在键为 key 的 list中移除、最后一个元素
     * @param key 键
     * @return
     */
    public static Object lrightPop(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        return redisTemplate.opsForList().rightPop(key);
    }
    /**
     * 模糊查询
     * @param key 键
     * @return true / false
     */
    public static List<Object> keys(String key) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        try {
            Set<String> set = redisTemplate.keys(key);
            return new ArrayList<>(set);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 模糊查询
     * @param query 查询参数
     * @return
     */
//    public static List<Object> scan(String query) {
//        List<Object> result = new ArrayList<>();
//        try {
//            Cursor<Map.Entry<Object,Object>> cursor = redisTemplate.opsForHash().scan("field",
//                    ScanOptions.scanOptions().match(query).count(1000).build());
//            while (cursor.hasNext()) {
//                Map.Entry<Object,Object> entry = cursor.next();
//                result.add(entry.getKey());
//                Object key = entry.getKey();
//                Object valueSet = entry.getValue();
//            }
//            //关闭cursor
//            cursor.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return result;
//    }
    /**
     * 模糊查询
     * @param query 查询参数
     * @return
     */
    public static List<Object> scan(String query) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        Set<String> resultKeys = (Set<String>) redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
            ScanOptions scanOptions = ScanOptions.scanOptions().match("*" + query + "*").count(1000).build();
            Cursor<byte[]> scan = connection.scan(scanOptions);
            Set<String> keys = new HashSet<>();
            while (scan.hasNext()) {
                byte[] next = scan.next();
                keys.add(new String(next));
            }
            return keys;
        });
        return new ArrayList<>(resultKeys);
    }
    public static List<Object> scan2(String query) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        Set<String> keys = redisTemplate.keys(query);
        return new ArrayList<>(keys);
    }
    //    ============================== 消息发送与订阅 ==============================
    public static void convertAndSend(String channel, JSONObject msg) {
        if (redisTemplate == null) {
            redisTemplate = SpringBeanFactory.getBean("redisTemplate");
        }
        redisTemplate.convertAndSend(channel, msg);
    }
}
src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java
@@ -116,6 +116,9 @@
        if (streamInfo.getFmp4() != null) {
            this.fmp4 = streamInfo.getFmp4().getUrl();
        }
        if (streamInfo.getHttps_fmp4() != null) {
            this.https_fmp4 = streamInfo.getHttps_fmp4().getUrl();
        }
        if (streamInfo.getWs_fmp4() != null) {
            this.ws_fmp4 = streamInfo.getWs_fmp4().getUrl();
        }