spring boot 结合redis监听 实现消息超时处理

**项目有个功能,要监听某个服务是否在线。**
*该服务会每5秒给后端传送“心跳”(心跳可以是某个字符串、某个数值等),一旦该服务超多30秒没有给后端传送“心跳”时,后端处理判断,该服务已下线。*

废话少说,直接上代码。

接口(用于接收前端传送过来的心跳)

package com.yingxiao.microservice.gongdan.controller;

import com.yingxiao.microservice.gongdan.entity.Sensor;
import com.yingxiao.microservice.gongdan.model.ApiResult;
import com.yingxiao.microservice.gongdan.service.impl.SensorServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @Auther : xiaobao
 * @Date : 2019/7/18 11:08
 * @Description :
 */
@Api(tags = "身份证传感器心跳验证接口")
@RestController
@RequestMapping(value = "sensor/beat")
public class SensorBeatController {

    private Logger logger = LoggerFactory.getLogger(getClass().getName());

    @Resource
    SensorServiceImpl sensorService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @ApiOperation(value = "验证方法",notes = "每5秒接受心跳,超过30秒未接受的话,则传感器下线")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "beat",value = "字符串",required = true,paramType = "query")
    })
    @PostMapping(value = "accept")
    public ApiResult SensorBeat(String beat){
        //第一次接受 存入当前时间
        //取出  <>30
        //判断字符串是否为空
        if (beat != null && beat != ""){
            //判断字符串是否为hello
            if ("hello".equals(beat)){
                redisTemplate.opsForValue().set("beat",beat,30, TimeUnit.SECONDS);
                Sensor sensor = new Sensor();
                sensor.setName("身份证传感器");
                sensor.setStatus("1");
                sensor.setSysTime(new Date());
                sensorService.insert(sensor);
            }
        }
        return new ApiResult(200,"already accept");
    }
}


redis监听器配置文件

package com.yingxiao.microservice.gongdan.config;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

/**
 * @Auther : xiaobao
 * @Date : 2019/7/18 15:01
 * @Description : redis监听器配置文件
 */
@Configuration
public class RedisListenerConfig {

    @Bean
    @Primary
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        //下面这种方式是灵活配置,针对每个库的失效key做处理
        //container.addMessageListener(new RedisExpiredListener(), new PatternTopic("__keyevent@0__:expired"));
        return container;
    }
}

定义监听器

package com.yingxiao.microservice.gongdan.constant;

import com.yingxiao.microservice.gongdan.entity.Sensor;
import com.yingxiao.microservice.gongdan.service.impl.SensorServiceImpl;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @Auther : xiaobao
 * @Date : 2019/7/18 15:09
 * @Description : redis监听器
 */
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    @Resource
    SensorServiceImpl sensorService;

    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    /**
     * 针对redis数据失效事件,进行数据处理
     * @param message
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
        String expiredKey = message.toString();
        if(expiredKey.startsWith("beat")){
            System.out.println("身份证传感器下线");
            Sensor sensor = new Sensor();
            sensor.setSysTime(new Date());
            sensor.setStatus("0");
            sensor.setName("身份证传感器");
            sensorService.insert(sensor);
        }
    }
}

实体类,Service和Mapper接口就不写,结合数据库,将某服务的状态持久化到数据库中。不得不说redis数据库很强大,订阅、捕捉、监听,和大家一起学习,get新技能。

上一篇:如何在android中启用传感器模拟器?


下一篇:android – 通过Bluemix将TI SensorTag连接到IBM IoT Foundation时无效的userID()