diff --git a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/aiot/service/impl/AiEdgeDeviceServiceImpl.java b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/aiot/service/impl/AiEdgeDeviceServiceImpl.java index 441c8685..83d16054 100644 --- a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/aiot/service/impl/AiEdgeDeviceServiceImpl.java +++ b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/aiot/service/impl/AiEdgeDeviceServiceImpl.java @@ -10,7 +10,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.viewsh.framework.common.pojo.PageResult; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.time.LocalDateTime; @@ -79,7 +78,6 @@ public class AiEdgeDeviceServiceImpl implements IAiEdgeDeviceService { } @Override - @Scheduled(fixedRate = 90000) // 每90秒检查一次 public void checkOffline() { LocalDateTime now = LocalDateTime.now(); LocalDateTime threshold = LocalDateTime.now().minusSeconds(90); diff --git a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/AiEdgeDeviceOfflineCheckJob.java b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/AiEdgeDeviceOfflineCheckJob.java new file mode 100644 index 00000000..c2c83f86 --- /dev/null +++ b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/AiEdgeDeviceOfflineCheckJob.java @@ -0,0 +1,35 @@ +package com.viewsh.module.video.framework.job; + +import cn.hutool.core.util.StrUtil; +import com.viewsh.module.video.aiot.service.IAiEdgeDeviceService; +import com.xxl.job.core.handler.annotation.XxlJob; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * AI 边缘设备离线标记 Job + * + *
检查超过90秒未上报心跳的边缘设备,将其状态标记为离线。 + * 建议 xxl-job 配置:每90秒执行一次(CRON: 0 * * * * ?,即每分钟;或按需自定义) + * + * @author lzh + */ +@Component +@Slf4j +public class AiEdgeDeviceOfflineCheckJob { + + @Resource + private IAiEdgeDeviceService aiEdgeDeviceService; + + @XxlJob("aiEdgeDeviceOfflineCheckJob") + public String execute() { + try { + aiEdgeDeviceService.checkOffline(); + return "AI 边缘设备离线检查完成"; + } catch (Exception e) { + log.error("AI 边缘设备离线检查失败", e); + return StrUtil.format("失败: {}", e.getMessage()); + } + } +} diff --git a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/DeviceStatusLostCheckJob.java b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/DeviceStatusLostCheckJob.java new file mode 100644 index 00000000..ba80c4a1 --- /dev/null +++ b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/DeviceStatusLostCheckJob.java @@ -0,0 +1,35 @@ +package com.viewsh.module.video.framework.job; + +import cn.hutool.core.util.StrUtil; +import com.viewsh.module.video.gb28181.service.IDeviceService; +import com.xxl.job.core.handler.annotation.XxlJob; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 设备状态丢失检查 Job + * + *
检测设备状态任务是否存活,丢失则执行设备离线。 + * 建议 xxl-job 配置:每30秒执行一次(CRON: 0/30 * * * * ?) + * + * @author lzh + */ +@Component +@Slf4j +public class DeviceStatusLostCheckJob { + + @Resource + private IDeviceService deviceService; + + @XxlJob("deviceStatusLostCheckJob") + public String execute() { + try { + deviceService.lostCheckForStatus(); + return "设备状态丢失检查完成"; + } catch (Exception e) { + log.error("设备状态丢失检查失败", e); + return StrUtil.format("失败: {}", e.getMessage()); + } + } +} diff --git a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/DeviceSubscribeLostCheckJob.java b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/DeviceSubscribeLostCheckJob.java new file mode 100644 index 00000000..cfeda5bc --- /dev/null +++ b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/DeviceSubscribeLostCheckJob.java @@ -0,0 +1,35 @@ +package com.viewsh.module.video.framework.job; + +import cn.hutool.core.util.StrUtil; +import com.viewsh.module.video.gb28181.service.IDeviceService; +import com.xxl.job.core.handler.annotation.XxlJob; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 设备目录/移动位置订阅丢失检查 Job + * + *
检测目录订阅和移动位置订阅任务是否存活,丢失则重新发起订阅。 + * 建议 xxl-job 配置:每10秒执行一次(CRON: 0/10 * * * * ?) + * + * @author lzh + */ +@Component +@Slf4j +public class DeviceSubscribeLostCheckJob { + + @Resource + private IDeviceService deviceService; + + @XxlJob("deviceSubscribeLostCheckJob") + public String execute() { + try { + deviceService.lostCheckForSubscribe(); + return "设备订阅丢失检查完成"; + } catch (Exception e) { + log.error("设备订阅丢失检查失败", e); + return StrUtil.format("失败: {}", e.getMessage()); + } + } +} diff --git a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/InviteStreamCleanupJob.java b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/InviteStreamCleanupJob.java new file mode 100644 index 00000000..16678528 --- /dev/null +++ b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/InviteStreamCleanupJob.java @@ -0,0 +1,35 @@ +package com.viewsh.module.video.framework.job; + +import cn.hutool.core.util.StrUtil; +import com.viewsh.module.video.gb28181.service.IInviteStreamService; +import com.xxl.job.core.handler.annotation.XxlJob; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 清理 Invite 会话缓存中的错误数据 Job + * + *
防止错误的 Redis Invite 数据导致点播不可用。 + * 建议 xxl-job 配置:每10秒执行一次(CRON: 0/10 * * * * ?) + * + * @author lzh + */ +@Component +@Slf4j +public class InviteStreamCleanupJob { + + @Resource + private IInviteStreamService inviteStreamService; + + @XxlJob("inviteStreamCleanupJob") + public String execute() { + try { + inviteStreamService.cleanInvalidInviteCache(); + return "清理 Invite 缓存成功"; + } catch (Exception e) { + log.error("清理 Invite 缓存失败", e); + return StrUtil.format("失败: {}", e.getMessage()); + } + } +} diff --git a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/PlatformAutoRegisterJob.java b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/PlatformAutoRegisterJob.java new file mode 100644 index 00000000..0d7b2810 --- /dev/null +++ b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/PlatformAutoRegisterJob.java @@ -0,0 +1,35 @@ +package com.viewsh.module.video.framework.job; + +import cn.hutool.core.util.StrUtil; +import com.viewsh.module.video.gb28181.service.IPlatformService; +import com.xxl.job.core.handler.annotation.XxlJob; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 级联平台自动注册监听 Job + * + *
监听国标级联所在的 WVP 服务是否正常,异常时选择新节点接管注册。 + * 建议 xxl-job 配置:每2秒执行一次(CRON: 0/2 * * * * ?) + * + * @author lzh + */ +@Component +@Slf4j +public class PlatformAutoRegisterJob { + + @Resource + private IPlatformService platformService; + + @XxlJob("platformAutoRegisterJob") + public String execute() { + try { + platformService.cascadePlatformAutoRegister(); + return "级联平台自动注册监听完成"; + } catch (Exception e) { + log.error("级联平台自动注册监听失败", e); + return StrUtil.format("失败: {}", e.getMessage()); + } + } +} diff --git a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/PlatformStatusLostCheckJob.java b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/PlatformStatusLostCheckJob.java new file mode 100644 index 00000000..9acabaa3 --- /dev/null +++ b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/framework/job/PlatformStatusLostCheckJob.java @@ -0,0 +1,35 @@ +package com.viewsh.module.video.framework.job; + +import cn.hutool.core.util.StrUtil; +import com.viewsh.module.video.gb28181.service.IPlatformService; +import com.xxl.job.core.handler.annotation.XxlJob; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 上级级联平台注册状态丢失检查 Job + * + *
检测启用但未注册的平台,发现后重新发起注册。
+ * 建议 xxl-job 配置:每20秒执行一次(CRON: 0/20 * * * * ?)
+ *
+ * @author lzh
+ */
+@Component
+@Slf4j
+public class PlatformStatusLostCheckJob {
+
+ @Resource
+ private IPlatformService platformService;
+
+ @XxlJob("platformStatusLostCheckJob")
+ public String execute() {
+ try {
+ platformService.statusLostCheck();
+ return "平台注册状态检查完成";
+ } catch (Exception e) {
+ log.error("平台注册状态检查失败", e);
+ return StrUtil.format("失败: {}", e.getMessage());
+ }
+ }
+}
diff --git a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/gb28181/service/IDeviceService.java b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/gb28181/service/IDeviceService.java
index 1bf49109..102e4e74 100644
--- a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/gb28181/service/IDeviceService.java
+++ b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/gb28181/service/IDeviceService.java
@@ -91,6 +91,16 @@ public interface IDeviceService {
List 高频 SIP 消息队列消费(200ms 轮询),不适合 xxl-job 调度,
+ * 保持本机 @Scheduled 轮询;独立为无接口的 @Component 以避免 JDK 代理问题。
+ *
+ * @author lzh
+ */
+@Component
+@Slf4j
+public class AlarmNotifyMessageQueueScheduler {
+
+ @Autowired
+ private AlarmNotifyMessageHandler alarmNotifyMessageHandler;
+
+ @Scheduled(fixedDelay = 200)
+ public void consume() {
+ alarmNotifyMessageHandler.executeTaskQueue();
+ }
+}
diff --git a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
index aa2983ab..55cb93b0 100644
--- a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
+++ b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
@@ -19,7 +19,6 @@ import lombok.extern.slf4j.Slf4j;
import org.dom4j.Element;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.sip.InvalidArgumentException;
@@ -72,7 +71,6 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
taskQueue.offer(new SipMsgInfo(evt, device, rootElement));
}
- @Scheduled(fixedDelay = 100)
public void executeTaskQueue() {
if (taskQueue.isEmpty()) {
return;
diff --git a/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageQueueScheduler.java b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageQueueScheduler.java
new file mode 100644
index 00000000..32d39b18
--- /dev/null
+++ b/viewsh-module-video/viewsh-module-video-server/src/main/java/com/viewsh/module/video/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageQueueScheduler.java
@@ -0,0 +1,27 @@
+package com.viewsh.module.video.gb28181.transmit.event.request.impl.message.notify.cmd;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * 心跳消息队列消费调度器
+ *
+ * 高频 SIP 消息队列消费(100ms 轮询),不适合 xxl-job 调度,
+ * 保持本机 @Scheduled 轮询;独立为无接口的 @Component 以避免 JDK 代理问题。
+ *
+ * @author lzh
+ */
+@Component
+@Slf4j
+public class KeepaliveNotifyMessageQueueScheduler {
+
+ @Autowired
+ private KeepaliveNotifyMessageHandler keepaliveNotifyMessageHandler;
+
+ @Scheduled(fixedDelay = 100)
+ public void consume() {
+ keepaliveNotifyMessageHandler.executeTaskQueue();
+ }
+}