diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..ee2c34b
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index e2fb029..22ee9d4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -55,6 +55,11 @@
2.0.46
+
+ com.alibaba
+ fastjson
+ 1.2.83
+
org.apache.commons
@@ -74,6 +79,40 @@
5.1.8
+
+
+ org.apache.poi
+ poi-ooxml
+ 4.1.2
+
+
+ org.eclipse.paho
+ org.eclipse.paho.client.mqttv3
+ 1.2.5
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.5.1
+
+
+
+ com.baomidou
+ dynamic-datasource-spring-boot-starter
+ 2.5.8
+
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.33
+
diff --git a/src/main/java/com/mobai/controller/StayTimeController.java b/src/main/java/com/mobai/controller/StayTimeController.java
new file mode 100644
index 0000000..1f8ea9c
--- /dev/null
+++ b/src/main/java/com/mobai/controller/StayTimeController.java
@@ -0,0 +1,17 @@
+package com.mobai.controller;
+
+import com.mobai.service.StayTimeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @ClassName StayTimeController
+ * @Description 描述
+ * @Author SaiSai.Liu
+ * @Date 2024/6/4 9:54
+ */
+@RestController
+public class StayTimeController {
+ @Autowired
+ private StayTimeService stayTimeService;
+}
diff --git a/src/main/java/com/mobai/domain/StayTime.java b/src/main/java/com/mobai/domain/StayTime.java
new file mode 100644
index 0000000..c07b46c
--- /dev/null
+++ b/src/main/java/com/mobai/domain/StayTime.java
@@ -0,0 +1,37 @@
+package com.mobai.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @ClassName StayTime
+ * @Description 描述
+ * @Author SaiSai.Liu
+ * @Date 2024/6/4 9:28
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class StayTime {
+
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+ private String vin;
+ private String ip;
+ private Long upTime;
+ private Long downTime;
+ private String remark;
+ private String createBy;
+ private Date createTime;
+ private String updateBy;
+ private Date updateTime;
+
+
+}
diff --git a/src/main/java/com/mobai/mapper/StayTimeMapper.java b/src/main/java/com/mobai/mapper/StayTimeMapper.java
new file mode 100644
index 0000000..83948b6
--- /dev/null
+++ b/src/main/java/com/mobai/mapper/StayTimeMapper.java
@@ -0,0 +1,15 @@
+package com.mobai.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.mobai.domain.StayTime;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @ClassName StayTimeMapper
+ * @Description 描述
+ * @Author SaiSai.Liu
+ * @Date 2024/6/4 9:57
+ */
+@Mapper
+public interface StayTimeMapper extends BaseMapper {
+}
diff --git a/src/main/java/com/mobai/mq/rabbitmq/Custom.java b/src/main/java/com/mobai/mq/rabbitmq/Custom.java
deleted file mode 100644
index b60dbb0..0000000
--- a/src/main/java/com/mobai/mq/rabbitmq/Custom.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.mobai.mq.rabbitmq;
-
-import com.rabbitmq.client.Channel;
-import org.springframework.amqp.core.ExchangeTypes;
-import org.springframework.amqp.core.Message;
-import org.springframework.amqp.rabbit.annotation.Exchange;
-import org.springframework.amqp.rabbit.annotation.Queue;
-import org.springframework.amqp.rabbit.annotation.QueueBinding;
-import org.springframework.amqp.rabbit.annotation.RabbitListener;
-import org.springframework.stereotype.Component;
-
-import java.io.IOException;
-
-/**
- * @ClassName Custom
- * @Description 描述
- * @Author SaiSai.Liu
- * @Date 2024/5/26 15:25
- */
-@Component
-public class Custom {
-
-// @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "send_sms_queue"),
-// exchange = @Exchange(value = "null",type = ExchangeTypes.DIRECT)))
-// public void mqCustom(Object data, Message message, Channel channel){
-// System.out.println(data.toString());
-// try {
-// channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
-// } catch (IOException e) {
-// throw new RuntimeException(e);
-// }
-//
-// }
-
-}
diff --git a/src/main/java/com/mobai/mq/rabbitmq/api/MqttPublishSample.java b/src/main/java/com/mobai/mq/rabbitmq/api/MqttPublishSample.java
new file mode 100644
index 0000000..e229e6e
--- /dev/null
+++ b/src/main/java/com/mobai/mq/rabbitmq/api/MqttPublishSample.java
@@ -0,0 +1,44 @@
+package com.mobai.mq.rabbitmq.api;
+
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
+
+public class MqttPublishSample {
+
+ public static void main(String[] args) {
+
+ String topic = "MQTT Examples";
+ String content = "Message from MqttPublishSample";
+ int qos = 2;
+ String broker = "tcp://iot.eclipse.org:1883";
+ String clientId = "JavaSample";
+ MemoryPersistence persistence = new MemoryPersistence();
+
+ try {
+ MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
+ MqttConnectOptions connOpts = new MqttConnectOptions();
+ connOpts.setCleanSession(true);
+ System.out.println("Connecting to broker: "+broker);
+ sampleClient.connect(connOpts);
+ System.out.println("Connected");
+ System.out.println("Publishing message: "+content);
+ MqttMessage message = new MqttMessage(content.getBytes());
+ message.setQos(qos);
+ sampleClient.publish(topic, message);
+ System.out.println("Message published");
+ sampleClient.disconnect();
+ System.out.println("Disconnected");
+ System.exit(0);
+ } catch(MqttException me) {
+ System.out.println("reason "+me.getReasonCode());
+ System.out.println("msg "+me.getMessage());
+ System.out.println("loc "+me.getLocalizedMessage());
+ System.out.println("cause "+me.getCause());
+ System.out.println("excep "+me);
+ me.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/com/mobai/mq/rabbitmq/api/SubscribeSample.java b/src/main/java/com/mobai/mq/rabbitmq/api/SubscribeSample.java
new file mode 100644
index 0000000..cac0d7c
--- /dev/null
+++ b/src/main/java/com/mobai/mq/rabbitmq/api/SubscribeSample.java
@@ -0,0 +1,33 @@
+package com.mobai.mq.rabbitmq.api;
+
+import com.mobai.mq.rabbitmq.cofig.MqttFactory;
+import com.mobai.mq.rabbitmq.cofig.MqttProperties;
+import com.mobai.mq.rabbitmq.domian.GetOptions;
+import com.mobai.mq.rabbitmq.domian.MqttCallBackServiceImpl;
+import org.eclipse.paho.client.mqttv3.*;
+
+public class SubscribeSample {
+ public static void main(String[] args) {
+ MqttProperties mqttProperties = MqttProperties.configBuild("39.98.69.92", "topic0");
+// MqttProperties mqttProperties = new MqttProperties();
+// mqttProperties.setBroker("tcp://39.98.69.92:1883");
+// mqttProperties.setTopic("mqtt/test");
+ mqttProperties.setUsername("emqx");
+ mqttProperties.setPassword("public");
+// mqttProperties.setClientid("subscribe_client");
+
+ int qos = 0;
+ try {
+ MqttClient client = new MqttFactory(new MqttCallBackServiceImpl()).buildOptions(mqttProperties);
+ // 连接参数
+ MqttConnectOptions options = GetOptions.getMqttOptionas(mqttProperties);
+ // 设置回调
+ client.setCallback(new MqttCallBackServiceImpl());
+ // 进行连接
+ client.connect(options);
+ client.subscribe(mqttProperties.getTopic(), qos);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/com/mobai/mq/rabbitmq/cofig/MqttFactory.java b/src/main/java/com/mobai/mq/rabbitmq/cofig/MqttFactory.java
new file mode 100644
index 0000000..a989e64
--- /dev/null
+++ b/src/main/java/com/mobai/mq/rabbitmq/cofig/MqttFactory.java
@@ -0,0 +1,44 @@
+package com.mobai.mq.rabbitmq.cofig;
+
+import com.mobai.mq.rabbitmq.domian.GetOptions;
+import com.mobai.mq.rabbitmq.domian.MqttCallBackServiceImpl;
+import lombok.AllArgsConstructor;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
+import org.springframework.stereotype.Service;
+
+/**
+ * @ClassName MqttFactory
+ * @Description 描述
+ * @Author SaiSai.Liu
+ * @Date 2024/5/31 11:35
+ */
+
+@Service
+@AllArgsConstructor
+public class MqttFactory {
+
+ private final MqttCallBackServiceImpl mqttCallBackService;
+
+ public MqttClient buildOptions( MqttProperties mqttProperties) {
+ MqttClient client = null;
+ try {
+ client = new MqttClient(
+ mqttProperties.getBroker(),
+ mqttProperties.getClientid(),
+ new MemoryPersistence());
+ MqttConnectOptions options = GetOptions.getMqttOptionas(mqttProperties);
+ client.connect(options);
+ client.setCallback(mqttCallBackService);
+ // 事件订阅
+ client.subscribe(mqttProperties.getTopic(), 0);
+
+ } catch (MqttException e) {
+ throw new RuntimeException(e);
+ }
+
+ return client;
+ }
+}
diff --git a/src/main/java/com/mobai/mq/rabbitmq/cofig/MqttProperties.java b/src/main/java/com/mobai/mq/rabbitmq/cofig/MqttProperties.java
new file mode 100644
index 0000000..d6f0421
--- /dev/null
+++ b/src/main/java/com/mobai/mq/rabbitmq/cofig/MqttProperties.java
@@ -0,0 +1,33 @@
+package com.mobai.mq.rabbitmq.cofig;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @ClassName MqttProperties
+ * @Description 描述
+ * @Author SaiSai.Liu
+ * @Date 2024/5/30 20:05
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MqttProperties {
+ private String broker ;
+ private String topic ;
+ private String username;
+ private String password;
+ private String clientid;
+
+ public static MqttProperties configBuild(String ip,String topic){
+// "tcp://39.98.69.92:1883"
+ return MqttProperties.builder()
+ .broker("tcp://"+ip+":1883")
+ .topic(topic)
+ .clientid("mobai-mq")
+ .build();
+ }
+}
diff --git a/src/main/java/com/mobai/mq/rabbitmq/cofig/RabbitConfig.java b/src/main/java/com/mobai/mq/rabbitmq/cofig/RabbitConfig.java
new file mode 100644
index 0000000..2133385
--- /dev/null
+++ b/src/main/java/com/mobai/mq/rabbitmq/cofig/RabbitConfig.java
@@ -0,0 +1,46 @@
+package com.mobai.mq.rabbitmq.cofig;
+
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.DirectExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @ClassName RabbitConfig
+ * @Description 描述
+ * @Author SaiSai.Liu
+ * @Date 2024/5/31 21:47
+ */
+@Configuration
+public class RabbitConfig {
+
+ @Bean
+ public Queue initQueue(){
+ return new Queue("create.topic",true);
+ }
+
+ /**
+ * 创建主题队列
+ * @return
+ */
+ @Bean
+ public DirectExchange direct() {
+ return new DirectExchange("mobai-mq");
+ }
+
+ /**
+ * 绑定交换机
+ * @param direct
+ * @param initQueue
+ * @return
+ */
+ @Bean
+ public Binding binding1a(DirectExchange direct,
+ Queue initQueue) {
+ return BindingBuilder.bind(initQueue)
+ .to(direct)
+ .with("mobai-mq");
+ }
+}
diff --git a/src/main/java/com/mobai/mq/rabbitmq/domian/GetOptions.java b/src/main/java/com/mobai/mq/rabbitmq/domian/GetOptions.java
new file mode 100644
index 0000000..88380c2
--- /dev/null
+++ b/src/main/java/com/mobai/mq/rabbitmq/domian/GetOptions.java
@@ -0,0 +1,28 @@
+package com.mobai.mq.rabbitmq.domian;
+
+import com.mobai.mq.rabbitmq.cofig.MqttProperties;
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+
+/**
+ * @ClassName GetOptions
+ * @Description 描述
+ * @Author SaiSai.Liu
+ * @Date 2024/5/31 14:26
+ */
+
+public class GetOptions {
+
+ public static MqttConnectOptions getMqttOptionas(MqttProperties mqttProperties){
+ // 连接参数
+ MqttConnectOptions options = new MqttConnectOptions();
+ if (!StringUtils.isAllBlank(mqttProperties.getUsername(),
+ mqttProperties.getPassword())){
+ options.setUserName(mqttProperties.getUsername());
+ options.setPassword(mqttProperties.getPassword().toCharArray());
+ }
+ options.setConnectionTimeout(60);
+ options.setKeepAliveInterval(60);
+ return options;
+ }
+}
diff --git a/src/main/java/com/mobai/mq/rabbitmq/domian/MqttCallBackServiceImpl.java b/src/main/java/com/mobai/mq/rabbitmq/domian/MqttCallBackServiceImpl.java
new file mode 100644
index 0000000..91ba885
--- /dev/null
+++ b/src/main/java/com/mobai/mq/rabbitmq/domian/MqttCallBackServiceImpl.java
@@ -0,0 +1,35 @@
+package com.mobai.mq.rabbitmq.domian;
+
+import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
+import org.eclipse.paho.client.mqttv3.MqttCallback;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.springframework.stereotype.Service;
+
+/**
+ * 回执消息类
+ * @ClassName MqttCallBackServiceImpl
+ * @Description 回执消息类
+ * @Author SaiSai.Liu
+ * @Date 2024/5/30 20:02
+ */
+@Service
+public class MqttCallBackServiceImpl implements MqttCallback {
+ @Override
+ public void connectionLost(Throwable cause) {
+ System.out.println("connectionLost: " + cause.getMessage());
+ }
+
+ @Override
+ public void messageArrived(String topic, MqttMessage message) {
+ System.out.println("topic: " + topic);
+ System.out.println("Qos: " + message.getQos());
+ System.out.println("message content: " + new String(message.getPayload()));
+
+ }
+
+ @Override
+ public void deliveryComplete(IMqttDeliveryToken token) {
+ System.out.println("deliveryComplete---------" + token.isComplete());
+ }
+
+}
diff --git a/src/main/java/com/mobai/mq/rabbitmq/rabbitMq/MessageHandler.java b/src/main/java/com/mobai/mq/rabbitmq/rabbitMq/MessageHandler.java
new file mode 100644
index 0000000..17ea15c
--- /dev/null
+++ b/src/main/java/com/mobai/mq/rabbitmq/rabbitMq/MessageHandler.java
@@ -0,0 +1,163 @@
+package com.mobai.mq.rabbitmq.rabbitMq;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.mobai.domain.StayTime;
+import com.mobai.mq.rabbitmq.cofig.MqttFactory;
+import com.mobai.mq.rabbitmq.cofig.MqttProperties;
+import com.mobai.service.StayTimeService;
+import com.mobai.util.RedisService;
+import com.rabbitmq.client.Channel;
+import lombok.extern.log4j.Log4j2;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 消费者:消息处理器
+ *
+ * @ClassName MessageHandler
+ * @Description 描述
+ * @Author SaiSai.Liu
+ * @Date 2024/5/31 14:37
+ */
+@Log4j2
+@Component
+public class MessageHandler {
+
+ @Autowired
+ private MqttFactory mqttFactory;
+
+ @Autowired
+ private StayTimeService stayTimeService;
+
+ @Autowired
+ private RedisService redisService;
+
+ @RabbitListener(queues = {"create.topic"})
+ private void message(String msg) {
+ log.info("消息内容:{}", msg);
+ MqttProperties topic0 = MqttProperties.configBuild(
+ "39.98.69.92",
+ "topic0");
+ log.info("接收到消息:{}", topic0);
+ MqttClient client = mqttFactory.buildOptions(topic0);
+ log.info("client创建:{}", client);
+ log.info("clientID创建:{}", client.getClientId());
+ }
+
+
+ /**
+ * 上线事件
+ *
+ * @param msg
+ */
+ @RabbitListener(queues = {"event"})
+ private void trainUp(String msg, Message message, Channel channel) {
+ log.info("event:{}", msg);
+ // 链接事件
+// event:{
+// "protocol":"MQTT",
+// "clientIp":"39.144.107.165",
+// "nodeIp":"127.0.0.1",
+// "clientId":"VIN123456789DIJE4",
+// "version":"MQTT_3_1_1",
+// "keepalive":20,
+// "cleanSession":true,
+// "timestamp":1717466764797,
+// "auth":{
+ // "username":"6D7A546314155D43A339EE4C0410613D86C821299316ADECDB871E08",
+ // "password":"VklOMTIzNDU2Nzg5RElKRTQxNzE3NDY2NzY1MDg3NTgyNDI4QThEQjA0RkU2OTkzNTM5NDIyNTQ2ODIwQzFFNzc3NDUzQTA4NzIzRTU4NUQyNDRBNjY="
+ // },
+// "messageId":0}
+
+ JSONObject jsonObject = JSON.parseObject(msg);
+ String vin = JSON.to(String.class, jsonObject.get("clientId"));
+ long timestamp = JSON.to(Long.class, jsonObject.get("timestamp"));
+ if (jsonObject.get("auth") != null) {
+ try {
+ log.info("上线事件");
+ String ip = redisService.getValue(vin);
+ log.info("上线车辆vin:{}\n\t上线时ip:{}", vin, ip);
+ if (ip == null) {
+ throw new ServletException("上线时ip为空");
+ }
+ // 方法内有判断,有则自增,无则创建
+ redisService.increment("onlineCar-" + ip, 1);
+ boolean save = stayTimeService.save(new StayTime() {{
+ setIp(ip);
+ setVin(vin);
+ setUpTime(timestamp);
+ }});
+ log.info(save ? vin + "上线记录成功" : vin + "上线记录失败");
+ // 消息消费成功则确认
+ channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+ } catch (IOException | ServletException e) {
+ log.error("上线失败");
+ try {
+ channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ } else {
+ // event:{
+ // "protocol":"MQTT",
+ // "messageId":0,
+ // "timestamp":1717466777367,
+ // "reason":"normal",
+ // "clientId":"VIN123456789DIJE4",
+ // "nodeIp":"127.0.0.1",
+ // "id":354,
+ // "clientIp":"39.144.107.165"
+ // }
+ log.info("下线事件");
+ String ip = redisService.getValue(vin);
+ try {
+ log.info("下线车辆vin:{}\n\t下线时ip:{}", vin, ip);
+ if (ip == null) {
+ throw new ServletException("下线时ip为空");
+ }
+ // 方法内有判断,有则自减,无则创建
+ redisService.decrement("onlineCar-" + ip, 1);
+ StayTime vinStayTime = stayTimeService.getOne(new LambdaQueryWrapper<>() {{
+ eq(StayTime::getVin, vin);
+ eq(StayTime::getDownTime, null);
+ }});
+ vinStayTime.setDownTime(timestamp);
+ boolean update = stayTimeService.update(vinStayTime, new LambdaUpdateWrapper<>() {{
+ eq(StayTime::getVin, vin);
+ eq(StayTime::getDownTime, null);
+ }});
+
+ // 输出在线时长
+ log.info("车辆在线时长为:{}", new SimpleDateFormat("HH时mm分ss秒").format(new Date(vinStayTime.getUpTime() - timestamp)));
+ log.info(update ? vin + "上线记录成功" : vin + "上线记录失败");
+
+ channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+ } catch (ServletException | IOException e) {
+ log.error("下线失败");
+ try {
+ channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ }
+
+
+}
diff --git a/src/main/java/com/mobai/openApi/SelectInstances.java b/src/main/java/com/mobai/openApi/SelectInstances.java
index 90434ca..53e5b56 100644
--- a/src/main/java/com/mobai/openApi/SelectInstances.java
+++ b/src/main/java/com/mobai/openApi/SelectInstances.java
@@ -6,9 +6,9 @@ import com.alibaba.fastjson2.JSON;
import com.aliyun.ecs20140526.models.DescribeInstancesResponse;
import com.aliyun.ecs20140526.models.DescribeInstancesResponseBody;
import com.aliyun.tea.TeaException;
-import com.mobai.domain.flux.ApifoxModel;
import com.mobai.domain.MqttServerModel;
import com.mobai.domain.Result;
+import com.mobai.domain.flux.ApifoxModel;
import com.mobai.service.FluxGetInfoService;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -21,6 +21,7 @@ import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.*;
+import java.util.concurrent.TimeUnit;
@Log4j2
@Component
@@ -71,7 +72,7 @@ public class SelectInstances {
//10分钟
-// @Scheduled(cron = "0 0/10 * * * ? ")
+// @Scheduled(cron = "0 0/5 * * * ? ")
//10秒
@Scheduled(cron = "0/10 * * * * ? ")
public void saveIps() throws Exception {
@@ -124,7 +125,8 @@ public class SelectInstances {
for (String ip : ips) {
Result info = fluxGetInfoService.getInfo(ip);
//连接总数
- long connectSize = Long.parseLong(redisTemplate.opsForValue().get("onlineCar-"+ip));
+ String string = redisTemplate.opsForValue().get("onlineCar-" + ip);
+ long connectSize = Long.parseLong(string == null ? "0" : string);
log.info("{}::{}", ip, connectSize);
//添加到一个容器
nodes.add(new SmallNode(ip, connectSize));
diff --git a/src/main/java/com/mobai/service/StayTimeService.java b/src/main/java/com/mobai/service/StayTimeService.java
new file mode 100644
index 0000000..423bab3
--- /dev/null
+++ b/src/main/java/com/mobai/service/StayTimeService.java
@@ -0,0 +1,14 @@
+package com.mobai.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.mobai.domain.StayTime;
+import com.mobai.mapper.StayTimeMapper;
+
+/**
+ * @ClassName StayTimeService
+ * @Description 描述
+ * @Author SaiSai.Liu
+ * @Date 2024/6/4 9:54
+ */
+public interface StayTimeService extends IService {
+}
diff --git a/src/main/java/com/mobai/service/impl/FluxGetInfoServiceImpl.java b/src/main/java/com/mobai/service/impl/FluxGetInfoServiceImpl.java
index d3bdcd3..28a8bdc 100644
--- a/src/main/java/com/mobai/service/impl/FluxGetInfoServiceImpl.java
+++ b/src/main/java/com/mobai/service/impl/FluxGetInfoServiceImpl.java
@@ -77,6 +77,7 @@ public class FluxGetInfoServiceImpl implements FluxGetInfoService {
String string = redis.opsForList().range("fluxMq", 0, -1).get(0);
List mqtts = JSON.parseArray(string, MqttServerModel.class);
log.info("集合:{}",mqtts);
+ // tcp://192.168.1.1:1883
if (redis.hasKey("fluxMqIndex")) {
redis.opsForValue().increment("fluxMqIndex", 1);
} else {
diff --git a/src/main/java/com/mobai/service/impl/StayTimeServiceImpl.java b/src/main/java/com/mobai/service/impl/StayTimeServiceImpl.java
new file mode 100644
index 0000000..ab1e44e
--- /dev/null
+++ b/src/main/java/com/mobai/service/impl/StayTimeServiceImpl.java
@@ -0,0 +1,24 @@
+package com.mobai.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.mobai.domain.StayTime;
+import com.mobai.mapper.StayTimeMapper;
+import com.mobai.service.StayTimeService;
+import com.mobai.util.RedisService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @ClassName StayTimeServiceImpl
+ * @Description 描述
+ * @Author SaiSai.Liu
+ * @Date 2024/6/4 9:54
+ */
+
+@Service
+public class StayTimeServiceImpl extends ServiceImpl implements StayTimeService{
+ @Autowired
+ private RedisService redisService;
+
+
+}
diff --git a/src/main/java/com/mobai/util/RedisService.java b/src/main/java/com/mobai/util/RedisService.java
new file mode 100644
index 0000000..16ef5bf
--- /dev/null
+++ b/src/main/java/com/mobai/util/RedisService.java
@@ -0,0 +1,297 @@
+package com.mobai.util;
+
+import com.alibaba.fastjson2.JSON;
+import org.apache.poi.ss.formula.functions.T;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.data.redis.core.BoundSetOperations;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * spring redis 工具类
+ *
+ * @author muyu
+ **/
+@SuppressWarnings(value = {"unchecked", "rawtypes"})
+@Component
+@Lazy
+public class RedisService {
+ @Autowired
+ public RedisTemplate redisTemplate;
+
+ /**
+ * 缓存基本的对象,Integer、String、实体类等
+ *
+ * @param key 缓存的键值
+ * @param value 缓存的值
+ */
+ public void setCacheObject(final String key, final T value) {
+ redisTemplate.opsForValue().set(key, value);
+ }
+
+ /**
+ * 缓存基本的对象,Integer、String、实体类等
+ *
+ * @param key 缓存的键值
+ * @param value 缓存的值
+ * @param timeout 时间
+ * @param timeUnit 时间颗粒度
+ */
+ public void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) {
+ redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
+ }
+
+ /**
+ * 设置有效时间
+ *
+ * @param key Redis键
+ * @param timeout 超时时间
+ * @return true=设置成功;false=设置失败
+ */
+ public boolean expire(final String key, final long timeout) {
+ return expire(key, timeout, TimeUnit.SECONDS);
+ }
+
+ /**
+ * 设置有效时间
+ *
+ * @param key Redis键
+ * @param timeout 超时时间
+ * @param unit 时间单位
+ * @return true=设置成功;false=设置失败
+ */
+ public boolean expire(final String key, final long timeout, final TimeUnit unit) {
+ return redisTemplate.expire(key, timeout, unit);
+ }
+
+ /**
+ * 获取有效时间
+ *
+ * @param key Redis键
+ * @return 有效时间
+ */
+ public long getExpire(final String key) {
+ return redisTemplate.getExpire(key);
+ }
+
+ /**
+ * 判断 key是否存在
+ *
+ * @param key 键
+ * @return true 存在 false不存在
+ */
+ public Boolean hasKey(String key) {
+ return redisTemplate.hasKey(key);
+ }
+
+ /**
+ * 获得缓存的基本对象。
+ *
+ * @param key 缓存键值
+ * @return 缓存键值对应的数据
+ */
+ public T getCacheObject(final String key) {
+ ValueOperations operation = redisTemplate.opsForValue();
+ return operation.get(key);
+ }
+
+ /**
+ * 删除单个对象
+ *
+ * @param key
+ */
+ public boolean deleteObject(final String key) {
+ return redisTemplate.delete(key);
+ }
+
+ /**
+ * 删除集合对象
+ *
+ * @param collection 多个对象
+ * @return
+ */
+ public boolean deleteObject(final Collection collection) {
+ return redisTemplate.delete(collection) > 0;
+ }
+
+ /**
+ * 缓存List数据
+ *
+ * @param key 缓存的键值
+ * @param dataList 待缓存的List数据
+ * @return 缓存的对象
+ */
+ public long setCacheList(final String key, final List dataList) {
+ Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
+ return count == null ? 0 : count;
+ }
+
+ /**
+ * 获得缓存的list对象
+ *
+ * @param key 缓存的键值
+ * @return 缓存键值对应的数据
+ */
+ public List getCacheList(final String key) {
+ return redisTemplate.opsForList().range(key, 0, -1);
+ }
+
+ /**
+ * 缓存Set
+ *
+ * @param key 缓存键值
+ * @param dataSet 缓存的数据
+ * @return 缓存数据的对象
+ */
+ public BoundSetOperations setCacheSet(final String key, final Set dataSet) {
+ BoundSetOperations setOperation = redisTemplate.boundSetOps(key);
+ Iterator it = dataSet.iterator();
+ while (it.hasNext()) {
+ setOperation.add(it.next());
+ }
+ return setOperation;
+ }
+
+ /**
+ * 获得缓存的set
+ *
+ * @param key
+ * @return
+ */
+ public Set getCacheSet(final String key) {
+ return redisTemplate.opsForSet().members(key);
+ }
+
+ /**
+ * 缓存Map
+ *
+ * @param key
+ * @param dataMap
+ */
+ public void setCacheMap(final String key, final Map dataMap) {
+ if (dataMap != null) {
+ redisTemplate.opsForHash().putAll(key, dataMap);
+ }
+ }
+
+ /**
+ * 获得缓存的Map
+ *
+ * @param key
+ * @return
+ */
+ public Map getCacheMap(final String key) {
+ return redisTemplate.opsForHash().entries(key);
+ }
+
+ /**
+ * 往Hash中存入数据
+ *
+ * @param key Redis键
+ * @param hKey Hash键
+ * @param value 值
+ */
+ public void setCacheMapValue(final String key, final String hKey, final T value) {
+ redisTemplate.opsForHash().put(key, hKey, value);
+ }
+
+ /**
+ * 获取Hash中的数据
+ *
+ * @param key Redis键
+ * @param hKey Hash键
+ * @return Hash中的对象
+ */
+ public T getCacheMapValue(final String key, final String hKey) {
+ HashOperations opsForHash = redisTemplate.opsForHash();
+ return opsForHash.get(key, hKey);
+ }
+
+ /**
+ * 获取多个Hash中的数据
+ *
+ * @param key Redis键
+ * @param hKeys Hash键集合
+ * @return Hash对象集合
+ */
+ public List getMultiCacheMapValue(final String key, final Collection