Java通过线程实现Redis监听事件实现遥控器记录功能,Redis监听事件需要开启事务

redis监控,在docker容器内找到redis下(你的端口)18628文件,修改配置,打开配置config set notify-keyspace-events $E

E表示监控事件

redis监控命令:

config set notify-keyspace-events $E

config get notify-keyspace-events

psubscribe '__key*__:*'(本地测试)

1.KeyExpiredListener

@Slf4j
@Component("keyExpiredListener")
public class KeyExpiredListener extends JedisPubSub {

    @Autowired
    private RemoteControlOperate remoteControlOperate;

    @Override
    public void onPSubscribe(String pattern, int subscribedChannels) {
//        System.out.println("onPSubscribe "
//                + pattern + " " + subscribedChannels);
        log.info("redis事件监听连接成功!");

    }

    @Override
    public void onPMessage(String pattern, String channel, String message) {

//        System.out.println("onPMessage pattern测试:   "
//                + pattern + "————" + channel + "————" + message);
        remoteControlOperate.ykqOperate(message);

    }

    @Override
    public void onMessage(String channel, String message) {

        System.out.println("onMessage pattern "
                + "-" + channel + "-" + message);
    }



}

2.RedisListenerExecution

@Component
public class RedisListenerExecution {

    @Autowired
    private KeyExpiredListener keyExpiredListener;

    public void RedisListenerStart(){
        try {
            RedisListenerRunnable run = new RedisListenerRunnable(keyExpiredListener);
            ThreadPoolExecutorUtil.getPoll().execute(run);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

3.RedisListenerRunnable

public class RedisListenerRunnable implements Runnable{

    private KeyExpiredListener keyExpiredListener = null;


    public RedisListenerRunnable(KeyExpiredListener keyExpiredListener){
        this.keyExpiredListener = keyExpiredListener;
    }

    @Override
    public void run(){
        int i=0;
        while (true){
            try {
                Jedis jedis = RedisPoolUtil.getJedis();
                jedis.psubscribe(keyExpiredListener, "__key*__:*");
            }catch (Exception e){
                e.printStackTrace();
                System.out.println("线程重启次数:"+(++i));
            }
        }
    }
}

4.RedisPoolUtil

Slf4j
public class RedisPoolUtil {
    private static JedisPool jedisPool = null;
    //连接Redis连接池
    public static Boolean ConnRedis(String RedisUrl) throws Exception{
        Boolean connFlag=false;
        try{
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxIdle(8);
            config.setMaxTotal(8);
            config.setMinIdle(0);
            String[] lstParas=RedisUrl.split(":",-1);
            String redisHost=lstParas[0];
            int redisPort=Integer.parseInt(lstParas[1]);
            jedisPool = new JedisPool(config, redisHost, redisPort);
            connFlag=true;
        }
        catch (Exception e){
            CloseRedis();
            log.error("连接Redis发生异常:"+e.getMessage());
        }
        return connFlag;
    }
    //关闭RedsPool
    public static void CloseRedis(){
        try{
            if(jedisPool!=null){
                jedisPool.close();
                jedisPool.destroy();
                jedisPool=null;
            }
        }
        catch (Exception e){
            log.error("关闭Redis发生异常:"+e.getMessage());
        }
    }
    //获取Redis连接
    public synchronized static Jedis getJedis() throws Exception {
        try {
            if (jedisPool != null) {
                Jedis resource = jedisPool.getResource();
                return resource;
            }
        } catch (Exception e) {
            log.error("获取Redis实例发生异常:"+e.getMessage());
        }
        return null;
    }
    //释放Redis连接
    public static void close(final Jedis jedis) {
        try{
            if (jedis != null) {
                jedis.close();
            }
        }
        catch(Exception e){
        }
    }
    //读取Redis值
    public static String Read(String redisKey) throws Exception{
        String readVal="";
        try{
            Jedis jedis = getJedis();
            if(jedis!=null){
                try{
                    readVal=jedis.get(redisKey);
                }
                catch (Exception e){
                    log.error("获取Redis标签="+redisKey+"值失败:"+e.getMessage());
                }
                close(jedis);
            }
        }
        catch (Exception e){
            log.error("获取Redis标签="+redisKey+"值异常:"+e.getMessage());
        }
        return readVal;
    }
}

5.RemoteControlOperate


@Slf4j
@Component("remoteControlOperate")
public class RemoteControlOperate {
    @Autowired
    private CommonSqlMapper commonSqlMapper;
    @Autowired
    private SqlDataResolve sqlDataResolve;
    @Autowired
    private SysCommonFunc sysCommonFunc;


    private Map<String,Object> remoteControlMap= new HashMap<>();

    @PostConstruct
    public void initRemoteControl() throws Exception{
        try{
            String sql = "select tag_addr from e_iot_me_device_remote_control order BY remote_control_id";


            List<Map<String, Object>> itemList=commonSqlMapper.ExecSelectSql(sql);
            for(Map<String,Object> map:itemList){
                remoteControlMap.put(map.get("tag_addr").toString(),null);
            }

            log.info("初始化启动:"+remoteControlMap);
        }
        catch (Exception ex){
            throw ex;
        }
    }

    public void ykqOperate(String tag_addr){
//        log.info("监听到遥控器点位:"+tag_addr);
        if(!remoteControlMap.containsKey(tag_addr))
            return;
        try{
            String TagValue = String.valueOf(ScadaClientApi.ReadScadaTagValue(tag_addr)==null? 0:ScadaClientApi.ReadScadaTagValue(tag_addr));
            String TagNowValue = String.valueOf(remoteControlMap.get(tag_addr)==null? 0:remoteControlMap.get(tag_addr));
//            String TagValue = String.valueOf(ScadaClientApi.ReadScadaTagValue(tag_addr));
//            String TagNowValue = String.valueOf(remoteControlMap.get(tag_addr));
            if(!TagNowValue.equals(TagValue)){
                String alarmMsgSql = "select dev.device_des,dev.attribute3 as device_code,con.tag_des\n" +
                        "from e_iot_fmod_device dev,e_iot_me_device_remote_control con\n" +
                        "where dev.device_id = con.device_id\n" +
                        "and con.tag_addr='"+tag_addr+"'";
                List<Map<String, Object>> itemList=commonSqlMapper.ExecSelectSql(alarmMsgSql);
                for(Map<String,Object> map:itemList){
                    String device_des = map.get("device_des").toString();
                    String device_code = map.get("device_code").toString();
                    String tag_des = map.get("tag_des").toString();
                    if(TagValue.equals("1")){
                        Long alarm_id = sqlDataResolve.GetIncreaseID("e_iot_me_device_alarm_id_seq");
                        String insertSql="insert into e_iot_me_device_alarm "+"(alarm_id,func_code,func_des,device_code,device_des,alarm_part," +
                                "alarm_msg,alarm_reason,creation_date,reset_flag,solution,ykq_flag) " +
                                "values (" +alarm_id+"," +
                                "'"+device_code+"-ALARM'," +
                                "'"+device_code+"报警'," +
                                "'"+device_des+"'," +
                                "'"+device_code+"报警'," +
                                "'遥控器组'," +
                                "'"+tag_des+"'," +
                                "'1等于1'," +
                                "'"+sysCommonFunc.GetNowDateTime() +"'," +
                                "'N'," +
                                "'遥控器触发',"+
                                "'N')";
                        commonSqlMapper.ExecUpdateSql(insertSql);
//                        log.info("准备插入遥控器报警的执行sql :"+insertSql);
                    }
                    if(TagValue.equals("0")){
                        String updateSql="update e_iot_me_device_alarm set " +
                                "reset_date='"+sysCommonFunc.GetNowDateTime()+"'," +
                                "reset_flag='Y'," +
                                "reset_by='"+"遥控器报警自动解除"+"' " +
                                "where reset_flag='N' and alarm_msg='"+tag_des+"' and device_code='"+device_des+"' and ykq_flag ='N' ";
                        commonSqlMapper.ExecUpdateSql(updateSql);
//                        log.info("准备解除遥控器报警的执行sql :"+updateSql);
                    }
                }
                remoteControlMap.put(tag_addr,TagValue);
            }
            return;
        }
        catch (Exception ex){
            ex.printStackTrace();
        }
    }
}

6.JobRunner

@Slf4j
@Component
@RequiredArgsConstructor
public class JobRunner implements ApplicationRunner {

    @Autowired
    private CommonSqlMapper commonSqlMapper;

    private final QuartzManage quartzManage;
    @Autowired
    private RedisListenerExecution redisListenerExecution;
    /**
     * 项目启动时重新激活启用的定时任务
     *
     * @param applicationArguments /
     */
    @Override
    public void run(ApplicationArguments applicationArguments) {
        log.info("--------------------注入定时任务---------------------");
        try {
          

            log.info("-----注入redis监听任务-----");

            redisListenerExecution.RedisListenerStart();

            log.info("-------redis监听件务注人完成----------- -");



        } catch (Exception e) {
            log.error("定时任务启动发生异常,直接退出:"+e.getMessage());
            System.exit(0);
        }
    }
}

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Jedis库实现Java代码监听Redis指定key前缀的过期事件。具体实现步骤如下: 1. 首先,你需要使用`PSubscribe`命令订阅指定key前缀的事件。例如,你可以执行以下代码来订阅所有以`prefix:`开头的键的过期事件: ```java Jedis jedis = new Jedis("localhost"); jedis.psubscribe(new KeyExpiredListener(), "__keyspace@0__:prefix:*"); ``` 在这个代码中,`KeyExpiredListener`是一个实现了`JedisPubSub`接口的类,用于处理收到的事件。 2. 然后,在`KeyExpiredListener`类中,你需要实现`onPMessage`方法,用于处理收到的事件。例如,你可以执行以下代码来输出过期的键名: ```java public class KeyExpiredListener extends JedisPubSub { @Override public void onPMessage(String pattern, String channel, String message) { System.out.println("Key expired: " + message.substring(message.indexOf(':') + 1)); } } ``` 在这个代码中,`message`参数包含了过期键的完整名称,例如`__keyspace@0__:prefix:mykey`,你需要使用`substring`方法来提取出键名`mykey`。 注意,你需要在程序结束时调用`jedis.close()`方法来释放Jedis连接。完整的代码示例如下: ```java import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPubSub; public class RedisKeyExpiredListener { public static void main(String[] args) { Jedis jedis = new Jedis("localhost"); jedis.psubscribe(new KeyExpiredListener(), "__keyspace@0__:prefix:*"); jedis.close(); } } class KeyExpiredListener extends JedisPubSub { @Override public void onPMessage(String pattern, String channel, String message) { System.out.println("Key expired: " + message.substring(message.indexOf(':') + 1)); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值