diff --git a/README.md b/README.md
index 22551a054..08a058cf2 100644
--- a/README.md
+++ b/README.md
@@ -40,6 +40,7 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git



+
# 功能特性
- [X] 集成web界面
diff --git a/doc/_content/ability/_media/img_19.png b/doc/_content/ability/_media/img_19.png
new file mode 100644
index 000000000..5cf2d42a1
Binary files /dev/null and b/doc/_content/ability/_media/img_19.png differ
diff --git a/doc/_content/ability/_media/img_20.png b/doc/_content/ability/_media/img_20.png
new file mode 100644
index 000000000..387eb6947
Binary files /dev/null and b/doc/_content/ability/_media/img_20.png differ
diff --git a/doc/_content/ability/_media/img_21.png b/doc/_content/ability/_media/img_21.png
new file mode 100644
index 000000000..19c7762ab
Binary files /dev/null and b/doc/_content/ability/_media/img_21.png differ
diff --git a/doc/_content/ability/_media/img_22.png b/doc/_content/ability/_media/img_22.png
new file mode 100644
index 000000000..f6aa8c4cf
Binary files /dev/null and b/doc/_content/ability/_media/img_22.png differ
diff --git a/doc/_content/ability/_media/img_23.png b/doc/_content/ability/_media/img_23.png
new file mode 100644
index 000000000..91be357ef
Binary files /dev/null and b/doc/_content/ability/_media/img_23.png differ
diff --git a/doc/_content/ability/_media/img_24.png b/doc/_content/ability/_media/img_24.png
new file mode 100644
index 000000000..e5224819e
Binary files /dev/null and b/doc/_content/ability/_media/img_24.png differ
diff --git a/doc/_content/ability/_media/img_25.png b/doc/_content/ability/_media/img_25.png
new file mode 100644
index 000000000..35900bd83
Binary files /dev/null and b/doc/_content/ability/_media/img_25.png differ
diff --git a/doc/_content/ability/device.md b/doc/_content/ability/device.md
index cc604576f..87dd35047 100644
--- a/doc/_content/ability/device.md
+++ b/doc/_content/ability/device.md
@@ -33,6 +33,10 @@

+### 3. 宇视科技
+
+
+
### 3. 艾科威视摄像头

diff --git a/doc/_content/ability/node_manger.md b/doc/_content/ability/node_manager.md
similarity index 100%
rename from doc/_content/ability/node_manger.md
rename to doc/_content/ability/node_manager.md
diff --git a/doc/_content/introduction/compile.md b/doc/_content/introduction/compile.md
index b61d6453b..038eb315e 100644
--- a/doc/_content/introduction/compile.md
+++ b/doc/_content/introduction/compile.md
@@ -112,7 +112,7 @@ mvn package -P war
```
编译如果报错, 一般都是网络问题, 导致的依赖包下载失败
-编译完成后在target目录下出现wvp-pro-***.jar/wvp-pro-***.war。
+编译完成后在target目录下出现 `wvp-pro-VERSION.jar` 和 `wvp-pro-VERSION.war` 文件。
接下来[配置服务](./_content/introduction/config.md)
diff --git a/doc/_media/log.jpg b/doc/_media/log.jpg
new file mode 100644
index 000000000..18c57d0f5
Binary files /dev/null and b/doc/_media/log.jpg differ
diff --git a/pom.xml b/pom.xml
index 5d818fcda..53bf517fd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -107,6 +107,12 @@
org.springframework.boot
spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
org.springframework.boot
spring-boot-configuration-processor
@@ -374,6 +380,18 @@
1.18.30
provided
+
+
+
+
+
+
+
+
+ io.github.sevdokimov.logviewer
+ log-viewer-spring-boot
+ 1.0.10
+
org.springframework.boot
@@ -401,6 +419,13 @@
1.8
1.8
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+
+
diff --git a/src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java b/src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
index e838cc8eb..acd6092fd 100644
--- a/src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
+++ b/src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java
@@ -39,7 +39,7 @@ public class VManageBootstrap extends SpringBootServletInitializer {
}else {
log.info("构建版本: {}", gitUtil.getBuildVersion());
log.info("构建时间: {}", gitUtil.getBuildDate());
- log.info("GIT最后提交时间: {}", gitUtil.getCommitTime());
+ log.info("GIT信息: 分支: {}, ID: {}, 时间: {}", gitUtil.getBranch(), gitUtil.getCommitIdShort(), gitUtil.getCommitTime());
}
}
// 项目重启
diff --git a/src/main/java/com/genersoft/iot/vmp/common/ApiSaveConstant.java b/src/main/java/com/genersoft/iot/vmp/common/ApiSaveConstant.java
deleted file mode 100644
index ed1c2b9b5..000000000
--- a/src/main/java/com/genersoft/iot/vmp/common/ApiSaveConstant.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package com.genersoft.iot.vmp.common;
-
-/**
- * 为API重命名, 方便向数据库记录数据的时候展示
- * @author lin
- */
-public class ApiSaveConstant {
-
- public static String getVal(String key) {
- String[] keyItemArray = key.split("/");
- if (keyItemArray.length <= 1 || !"api".equals(keyItemArray[1])) {
- return null;
- }
- if (keyItemArray.length >= 4) {
- switch (keyItemArray[2]) {
- case "alarm":
- if ("delete".equals(keyItemArray[3])) {
- return "删除报警";
- }
- break;
- case "device":
- switch (keyItemArray[3]) {
- case "config":
- if (keyItemArray.length >= 5 && "basicParam".equals(keyItemArray[4])) {
- return "[设备配置] 基本配置设置命令";
- }
- break;
- case "control":
- switch (keyItemArray[4]) {
- case "teleboot":
- return "[设备控制] 远程启动";
- case "record":
- return "[设备控制] 录像控制";
- case "guard":
- return "[设备控制] 布防/撤防命令";
- case "reset_alarm":
- return "[设备控制] 报警复位";
- case "i_frame":
- return "[设备控制] 强制关键帧";
- case "home_position":
- return "[设备控制] 看守位控制";
- default:
- return "";
- }
- case "query":
- if (keyItemArray.length <= 5) {
- return null;
- }
- switch (keyItemArray[4]) {
- case "devices":
- if (keyItemArray.length < 7) {
- return null;
- }
- switch (keyItemArray[6]) {
- case "sync":
- return "[设备查询] 同步设备通道";
- case "delete":
- return "[设备查询] 移除设备";
- default:
- return "";
- }
- case "channel":
- return "[设备查询] 更新通道信息";
- case "transport":
- return "[设备查询] 修改数据流传输模式";
- default:
- return "";
- }
- default:
- return "";
- }
-
- break;
- case "gbStream":
- switch (keyItemArray[3]) {
- case "del":
- return "移除通道与国标的关联";
- case "add":
- return "添加通道与国标的关联";
- default:
- return "";
- }
- case "media":
- break;
- case "position":
- if ("subscribe".equals(keyItemArray[3])) {
- return "订阅位置信息";
- }
- break;
- case "platform":
- switch (keyItemArray[3]) {
- case "save":
- return "添加上级平台";
- case "delete":
- return "移除上级平台";
- case "update_channel_for_gb":
- return "向上级平台添加国标通道";
- case "del_channel_for_gb":
- return "从上级平台移除国标通道";
- default:
- return "";
- }
- case "platform_gb_stream":
- break;
- case "play":
- switch (keyItemArray[3]) {
- case "start":
- return "开始点播";
- case "stop":
- return "停止点播";
- case "convert":
- return "转码";
- case "convertStop":
- return "结束转码";
- case "broadcast":
- return "语音广播";
- default:
- return "";
- }
- case "download":
- switch (keyItemArray[3]) {
- case "start":
- return "开始历史媒体下载";
- case "stop":
- return "停止历史媒体下载";
- default:
- return "";
- }
- case "playback":
- switch (keyItemArray[3]) {
- case "start":
- return "开始视频回放";
- case "stop":
- return "停止视频回放";
- default:
- return "";
- }
- case "ptz":
- switch (keyItemArray[3]) {
- case "control":
- return "云台控制";
- case "front_end_command":
- return "通用前端控制命令";
- default:
- return "";
- }
- case "gb_record":
- break;
- case "onvif":
- break;
- case "server":
- if ("restart".equals(keyItemArray[3])) {
- return "重启流媒体服务";
- }
- break;
- case "proxy":
- switch (keyItemArray[3]) {
- case "save":
- return "保存代理";
- case "del":
- return "移除代理";
- case "start":
- return "启用代理";
- case "stop":
- return "停用代理";
- default:
- return "";
- }
- case "push":
- switch (keyItemArray[3]) {
- case "save_to_gb":
- return "将推流添加到国标";
- case "remove_form_gb":
- return "将推流移出到国标";
- default:
- return "";
- }
- case "user":
- switch (keyItemArray[3]) {
- case "login":
- return "登录";
- case "changePassword":
- return "修改密码";
- case "add":
- return "添加用户";
- case "delete":
- return "删除用户";
- default:
- return "";
- }
- default:
- return "";
- }
- }
- return null;
- }
-}
-
diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteInfo.java b/src/main/java/com/genersoft/iot/vmp/common/InviteInfo.java
index 8c91dc82a..adf9643fd 100644
--- a/src/main/java/com/genersoft/iot/vmp/common/InviteInfo.java
+++ b/src/main/java/com/genersoft/iot/vmp/common/InviteInfo.java
@@ -29,8 +29,14 @@ public class InviteInfo {
private StreamInfo streamInfo;
+ private String mediaServerId;
- public static InviteInfo getInviteInfo(String deviceId, Integer channelId, String stream, SSRCInfo ssrcInfo,
+ private Long expirationTime;
+
+ private Long createTime;
+
+
+ public static InviteInfo getInviteInfo(String deviceId, Integer channelId, String stream, SSRCInfo ssrcInfo, String mediaServerId,
String receiveIp, Integer receivePort, String streamMode,
InviteSessionType type, InviteSessionStatus status) {
InviteInfo inviteInfo = new InviteInfo();
@@ -43,6 +49,7 @@ public class InviteInfo {
inviteInfo.setStreamMode(streamMode);
inviteInfo.setType(type);
inviteInfo.setStatus(status);
+ inviteInfo.setMediaServerId(mediaServerId);
return inviteInfo;
}
diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
index 3d5597563..442709918 100644
--- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
+++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -12,58 +12,31 @@ public class VideoManagerConstants {
public static final String WVP_SERVER_STREAM_PREFIX = "VMP_SIGNALLING_STREAM_";
- public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER:";
+ public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_INFO:";
public static final String ONLINE_MEDIA_SERVERS_PREFIX = "VMP_ONLINE_MEDIA_SERVERS:";
- public static final String DEVICE_PREFIX = "VMP_DEVICE_";
+ public static final String DEVICE_PREFIX = "VMP_DEVICE_INFO";
- // 设备同步完成
- public static final String DEVICE_SYNC_PREFIX = "VMP_DEVICE_SYNC_";
-
- public static final String CACHEKEY_PREFIX = "VMP_CHANNEL_";
-
- public static final String KEEPLIVEKEY_PREFIX = "VMP_KEEPALIVE_";
-
- // TODO 此处多了一个_,暂不修改
- public static final String INVITE_PREFIX = "VMP_INVITE_INFO";
- public static final String PLAYER_PREFIX = "VMP_INVITE_PLAY_";
- public static final String PLAY_BLACK_PREFIX = "VMP_INVITE_PLAYBACK_";
- public static final String DOWNLOAD_PREFIX = "VMP_INVITE_DOWNLOAD_";
-
- public static final String PLATFORM_KEEPALIVE_PREFIX = "VMP_PLATFORM_KEEPALIVE_";
+ public static final String INVITE_PREFIX = "VMP_GB_INVITE_INFO";
public static final String PLATFORM_CATCH_PREFIX = "VMP_PLATFORM_CATCH_";
- public static final String PLATFORM_REGISTER_PREFIX = "VMP_PLATFORM_REGISTER_";
-
public static final String PLATFORM_REGISTER_INFO_PREFIX = "VMP_PLATFORM_REGISTER_INFO_";
- public static final String SEND_RTP_INFO = "VMP_SEND_RTP_INFO:";
- public static final String SEND_RTP_INFO_CALLID = "VMP_SEND_RTP_INFO:CALL_ID";
- public static final String SEND_RTP_INFO_STREAM = "VMP_SEND_RTP_INFO:STREAM";
- public static final String SEND_RTP_INFO_CHANNEL = "VMP_SEND_RTP_INFO:CHANNEL";
+ public static final String SEND_RTP_PORT = "VM_SEND_RTP_PORT:";
+ public static final String SEND_RTP_INFO_CALLID = "VMP_SEND_RTP_INFO:CALL_ID:";
+ public static final String SEND_RTP_INFO_STREAM = "VMP_SEND_RTP_INFO:STREAM:";
+ public static final String SEND_RTP_INFO_CHANNEL = "VMP_SEND_RTP_INFO:CHANNEL:";
- public static final String EVENT_ONLINE_REGISTER = "1";
+ public static final String SIP_INVITE_SESSION = "VMP_SIP_INVITE_SESSION_INFO:";
+ public static final String SIP_INVITE_SESSION_CALL_ID = SIP_INVITE_SESSION + "CALL_ID:";
+ public static final String SIP_INVITE_SESSION_STREAM = SIP_INVITE_SESSION + "STREAM:";
- public static final String EVENT_ONLINE_MESSAGE = "3";
-
- public static final String EVENT_OUTLINE_UNREGISTER = "1";
-
- public static final String EVENT_OUTLINE_TIMEOUT = "2";
-
- public static final String MEDIA_SSRC_USED_PREFIX = "VMP_MEDIA_USED_SSRC_";
-
- public static final String SIP_INVITE_SESSION = "VMP_SIP_INVITE_SESSION:";
- public static final String SIP_INVITE_SESSION_CALL_ID = SIP_INVITE_SESSION + "CALL_ID" + ":";
- public static final String SIP_INVITE_SESSION_STREAM = SIP_INVITE_SESSION + "STREAM" + ":";
-
- public static final String MEDIA_STREAM_AUTHORITY = "VMP_MEDIA_STREAM_AUTHORITY_";
+ public static final String MEDIA_STREAM_AUTHORITY = "VMP_MEDIA_STREAM_AUTHORITY:";
public static final String SIP_CSEQ_PREFIX = "VMP_SIP_CSEQ_";
- public static final String SIP_SN_PREFIX = "VMP_SIP_SN_";
-
public static final String SIP_SUBSCRIBE_PREFIX = "VMP_SIP_SUBSCRIBE_";
public static final String SYSTEM_INFO_CPU_PREFIX = "VMP_SYSTEM_INFO_CPU_";
@@ -79,7 +52,7 @@ public class VideoManagerConstants {
public static final String PUSH_STREAM_LIST = "VMP_PUSH_STREAM_LIST_";
public static final String WAITE_SEND_PUSH_STREAM = "VMP_WAITE_SEND_PUSH_STREAM:";
public static final String START_SEND_PUSH_STREAM = "VMP_START_SEND_PUSH_STREAM:";
- public static final String PUSH_STREAM_ONLINE = "VMP_PUSH_STREAM_ONLINE:";
+ public static final String SSE_TASK_KEY = "SSE_TASK_";
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java b/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
deleted file mode 100644
index e55c8ecf2..000000000
--- a/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package com.genersoft.iot.vmp.conf;
-
-import com.genersoft.iot.vmp.common.ApiSaveConstant;
-import com.genersoft.iot.vmp.conf.security.SecurityUtils;
-import com.genersoft.iot.vmp.service.ILogService;
-import com.genersoft.iot.vmp.storager.dao.dto.LogDto;
-import com.genersoft.iot.vmp.utils.DateUtil;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.stereotype.Component;
-import org.springframework.util.ObjectUtils;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.annotation.WebFilter;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * @author lin
- */
-@Slf4j
-@WebFilter(filterName = "ApiAccessFilter", urlPatterns = "/api/*", asyncSupported=true)
-@Component
-public class ApiAccessFilter extends OncePerRequestFilter {
-
- @Autowired
- private UserSetting userSetting;
-
- @Autowired
- private ILogService logService;
-
-
- @Override
- protected void doFilterInternal(HttpServletRequest servletRequest, HttpServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
- String username = null;
- if (SecurityUtils.getUserInfo() == null) {
- username = servletRequest.getParameter("username");
- }else {
- username = SecurityUtils.getUserInfo().getUsername();
- }
- long start = System.currentTimeMillis(); // 请求进入时间
- String uriName = ApiSaveConstant.getVal(servletRequest.getRequestURI());
-
- filterChain.doFilter(servletRequest, servletResponse);
-
- if (uriName != null && userSetting != null && userSetting.getLogInDatabase() != null && userSetting.getLogInDatabase()) {
-
- LogDto logDto = new LogDto();
- logDto.setName(uriName);
- if (ObjectUtils.isEmpty(username)) {
- username = "";
- }
- logDto.setUsername(username);
- logDto.setAddress(servletRequest.getRemoteAddr());
- logDto.setResult(HttpStatus.valueOf(servletResponse.getStatus()).toString());
- logDto.setTiming(System.currentTimeMillis() - start);
- logDto.setType(servletRequest.getMethod());
- logDto.setUri(servletRequest.getRequestURI());
- logDto.setCreateTime(DateUtil.getNow());
- logService.add(logDto);
-
-
- }
- }
-
- /**
- * 获取IP地址
- *
- * @param request 请求
- * @return request发起客户端的IP地址
- */
- private String getIP(HttpServletRequest request) {
- if (request == null) {
- return "0.0.0.0";
- }
-
- String Xip = request.getHeader("X-Real-IP");
- String XFor = request.getHeader("X-Forwarded-For");
-
- String UNKNOWN_IP = "unknown";
- if (StringUtils.isNotEmpty(XFor) && !UNKNOWN_IP.equalsIgnoreCase(XFor)) {
- //多次反向代理后会有多个ip值,第一个ip才是真实ip
- int index = XFor.indexOf(",");
- if (index != -1) {
- return XFor.substring(0, index);
- } else {
- return XFor;
- }
- }
-
- XFor = Xip;
- if (StringUtils.isNotEmpty(XFor) && !UNKNOWN_IP.equalsIgnoreCase(XFor)) {
- return XFor;
- }
-
- if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
- XFor = request.getHeader("Proxy-Client-IP");
- }
- if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
- XFor = request.getHeader("WL-Proxy-Client-IP");
- }
- if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
- XFor = request.getHeader("HTTP_CLIENT_IP");
- }
- if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
- XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
- }
- if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
- XFor = request.getRemoteAddr();
- }
- return XFor;
- }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaStatusTimerTask.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaStatusTimerTask.java
index 56573fe58..761250e02 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/MediaStatusTimerTask.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaStatusTimerTask.java
@@ -8,7 +8,7 @@ import org.springframework.scheduling.annotation.Scheduled;
public class MediaStatusTimerTask {
- @Scheduled(fixedRate = 2 * 1000) //每3秒执行一次
+// @Scheduled(fixedRate = 2 * 1000) //每3秒执行一次
public void execute(){
}
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/SpringDocConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/SpringDocConfig.java
index 622c419a0..55e4aff9d 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/SpringDocConfig.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/SpringDocConfig.java
@@ -50,7 +50,7 @@ public class SpringDocConfig {
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("1. 全部")
- .packagesToScan("com.genersoft.iot.vmp.vmanager", "com.genersoft.iot.vmp.jt1078.controller")
+ .packagesToScan("com.genersoft.iot.vmp")
.build();
}
@@ -58,7 +58,7 @@ public class SpringDocConfig {
public GroupedOpenApi publicApi2() {
return GroupedOpenApi.builder()
.group("2. 国标28181")
- .packagesToScan("com.genersoft.iot.vmp.vmanager.gb28181")
+ .packagesToScan("com.genersoft.iot.vmp.gb28181")
.build();
}
@@ -66,7 +66,7 @@ public class SpringDocConfig {
public GroupedOpenApi publicApi3() {
return GroupedOpenApi.builder()
.group("3. 拉流转发")
- .packagesToScan("com.genersoft.iot.vmp.vmanager.streamProxy")
+ .packagesToScan("com.genersoft.iot.vmp.streamProxy")
.build();
}
@@ -74,7 +74,7 @@ public class SpringDocConfig {
public GroupedOpenApi publicApi4() {
return GroupedOpenApi.builder()
.group("4. 推流管理")
- .packagesToScan("com.genersoft.iot.vmp.vmanager.streamPush")
+ .packagesToScan("com.genersoft.iot.vmp.streamPush")
.build();
}
@@ -82,7 +82,7 @@ public class SpringDocConfig {
public GroupedOpenApi publicApi5() {
return GroupedOpenApi.builder()
.group("4. 服务管理")
- .packagesToScan("com.genersoft.iot.vmp.vmanager.server")
+ .packagesToScan("com.genersoft.iot.vmp.server")
.build();
}
@@ -90,7 +90,7 @@ public class SpringDocConfig {
public GroupedOpenApi publicApi6() {
return GroupedOpenApi.builder()
.group("5. 用户管理")
- .packagesToScan("com.genersoft.iot.vmp.vmanager.user")
+ .packagesToScan("com.genersoft.iot.vmp.user")
.build();
}
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
index 1d4293ba6..604c8c56a 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
@@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.conf;
+import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@@ -13,326 +14,160 @@ import java.util.List;
@Component
@ConfigurationProperties(prefix = "user-settings", ignoreInvalidFields = true)
@Order(0)
+@Data
public class UserSetting {
+ /**
+ * 是否保存位置的历史记录(轨迹)
+ */
private Boolean savePositionHistory = Boolean.FALSE;
+ /**
+ * 是否开始自动点播: 请求流为未拉起的流时,自动开启点播, 需要rtp.enable=true
+ */
private Boolean autoApplyPlay = Boolean.FALSE;
+ /**
+ * [可选] 部分设备需要扩展SDP,需要打开此设置,一般设备无需打开
+ */
private Boolean seniorSdp = Boolean.FALSE;
+ /**
+ * 点播/录像回放 等待超时时间,单位:毫秒
+ */
private Integer playTimeout = 10000;
+ /**
+ * 上级点播等待超时时间,单位:毫秒
+ */
private int platformPlayTimeout = 20000;
+ /**
+ * 是否开启接口鉴权
+ */
private Boolean interfaceAuthentication = Boolean.TRUE;
- private Boolean recordPushLive = Boolean.TRUE;
-
- private Boolean recordSip = Boolean.TRUE;
-
- private Boolean logInDatabase = Boolean.FALSE;
-
- private Boolean usePushingAsStatus = Boolean.FALSE;
-
- private Boolean useSourceIpAsStreamIp = Boolean.FALSE;
-
- private Boolean sipUseSourceIpAsRemoteAddress = Boolean.FALSE;
-
- private Boolean streamOnDemand = Boolean.TRUE;
-
- private Boolean pushAuthority = Boolean.TRUE;
-
- private Boolean syncChannelOnDeviceOnline = Boolean.FALSE;
-
- private Boolean sipLog = Boolean.FALSE;
- private Boolean sqlLog = Boolean.FALSE;
- private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE;
-
- private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE;
-
- private Boolean deviceStatusNotify = Boolean.TRUE;
- private Boolean useCustomSsrcForParentInvite = Boolean.TRUE;
-
- private Boolean docEnable = Boolean.TRUE;
-
- private String serverId = "000000";
-
- private String thirdPartyGBIdReg = "[\\s\\S]*";
-
- private String broadcastForPlatform = "UDP";
-
- private String civilCodeFile = "classpath:civilCode.csv";
-
+ /**
+ * 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录
+ */
private List interfaceAuthenticationExcludes = new ArrayList<>();
+ /**
+ * 推流直播是否录制
+ */
+ private Boolean recordPushLive = Boolean.TRUE;
+
+ /**
+ * 国标是否录制
+ */
+ private Boolean recordSip = Boolean.TRUE;
+
+ /**
+ * 使用推流状态作为推流通道状态
+ */
+ private Boolean usePushingAsStatus = Boolean.FALSE;
+
+ /**
+ * 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启
+ */
+ private Boolean useSourceIpAsStreamIp = Boolean.FALSE;
+
+ /**
+ * 是否使用设备来源Ip作为回复IP, 不设置则为 false
+ */
+ private Boolean sipUseSourceIpAsRemoteAddress = Boolean.FALSE;
+
+ /**
+ * 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放
+ */
+ private Boolean streamOnDemand = Boolean.TRUE;
+
+ /**
+ * 推流鉴权, 默认开启
+ */
+ private Boolean pushAuthority = Boolean.TRUE;
+
+ /**
+ * 设备上线时是否自动同步通道
+ */
+ private Boolean syncChannelOnDeviceOnline = Boolean.FALSE;
+
+ /**
+ * 是否开启sip日志
+ */
+ private Boolean sipLog = Boolean.FALSE;
+
+ /**
+ * 是否开启mybatis-sql日志
+ */
+ private Boolean sqlLog = Boolean.FALSE;
+
+ /**
+ * 消息通道功能-缺少国标ID是否给所有上级发送消息
+ */
+ private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE;
+
+ /**
+ * 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息
+ */
+ private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE;
+
+ /**
+ * 设备/通道状态变化时发送消息
+ */
+ private Boolean deviceStatusNotify = Boolean.TRUE;
+
+ /**
+ * 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式
+ */
+ private Boolean useCustomSsrcForParentInvite = Boolean.TRUE;
+
+ /**
+ * 开启接口文档页面。 默认开启,生产环境建议关闭,遇到swagger相关的漏洞时也可以关闭
+ */
+ private Boolean docEnable = Boolean.TRUE;
+
+ /**
+ * 服务ID,不写则为000000
+ */
+ private String serverId = "000000";
+
+
+ /**
+ * 国标级联语音喊话发流模式 * UDP:udp传输 TCP-ACTIVE:tcp主动模式 TCP-PASSIVE:tcp被动模式
+ */
+ private String broadcastForPlatform = "UDP";
+
+ /**
+ * 行政区划信息文件,系统启动时会加载到系统里
+ */
+ private String civilCodeFile = "classpath:civilCode.csv";
+
+ /**
+ * 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个
+ */
private List allowedOrigins = new ArrayList<>();
+ /**
+ * 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认100000
+ */
private int maxNotifyCountQueue = 100000;
+ /**
+ * 国标级联离线后多久重试一次注册
+ */
private int registerAgainAfterTime = 60;
+ /**
+ * 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话
+ */
private boolean registerKeepIntDialog = false;
+ /**
+ * # 国标设备离线后的上线策略,
+ * # 0: 国标标准实现,设备离线后不回复心跳,直到设备重新注册上线,
+ * # 1(默认): 对于离线设备,收到心跳就把设备设置为上线,并更新注册时间为上次这次心跳的时间。防止过期时间判断异常
+ */
private int gbDeviceOnline = 1;
- public Boolean getSavePositionHistory() {
- return savePositionHistory;
- }
-
- public Boolean isSavePositionHistory() {
- return savePositionHistory;
- }
-
- public Boolean isAutoApplyPlay() {
- return autoApplyPlay;
- }
-
- public Boolean isSeniorSdp() {
- return seniorSdp;
- }
-
- public Integer getPlayTimeout() {
- return playTimeout;
- }
-
- public Boolean isInterfaceAuthentication() {
- return interfaceAuthentication;
- }
-
- public Boolean isRecordPushLive() {
- return recordPushLive;
- }
-
- public List getInterfaceAuthenticationExcludes() {
- return interfaceAuthenticationExcludes;
- }
-
- public void setSavePositionHistory(Boolean savePositionHistory) {
- this.savePositionHistory = savePositionHistory;
- }
-
- public void setAutoApplyPlay(Boolean autoApplyPlay) {
- this.autoApplyPlay = autoApplyPlay;
- }
-
- public void setSeniorSdp(Boolean seniorSdp) {
- this.seniorSdp = seniorSdp;
- }
-
- public void setPlayTimeout(Integer playTimeout) {
- this.playTimeout = playTimeout;
- }
-
- public void setInterfaceAuthentication(boolean interfaceAuthentication) {
- this.interfaceAuthentication = interfaceAuthentication;
- }
-
- public void setRecordPushLive(Boolean recordPushLive) {
- this.recordPushLive = recordPushLive;
- }
-
- public void setInterfaceAuthenticationExcludes(List interfaceAuthenticationExcludes) {
- this.interfaceAuthenticationExcludes = interfaceAuthenticationExcludes;
- }
-
- public Boolean getLogInDatabase() {
- return logInDatabase;
- }
-
- public void setLogInDatabase(Boolean logInDatabase) {
- this.logInDatabase = logInDatabase;
- }
-
- public String getServerId() {
- return serverId;
- }
-
- public void setServerId(String serverId) {
- this.serverId = serverId;
- }
-
- public String getThirdPartyGBIdReg() {
- return thirdPartyGBIdReg;
- }
-
- public void setThirdPartyGBIdReg(String thirdPartyGBIdReg) {
- this.thirdPartyGBIdReg = thirdPartyGBIdReg;
- }
-
- public Boolean getRecordSip() {
- return recordSip;
- }
-
- public void setRecordSip(Boolean recordSip) {
- this.recordSip = recordSip;
- }
-
- public int getPlatformPlayTimeout() {
- return platformPlayTimeout;
- }
-
- public void setPlatformPlayTimeout(int platformPlayTimeout) {
- this.platformPlayTimeout = platformPlayTimeout;
- }
-
- public Boolean isUsePushingAsStatus() {
- return usePushingAsStatus;
- }
-
- public void setUsePushingAsStatus(Boolean usePushingAsStatus) {
- this.usePushingAsStatus = usePushingAsStatus;
- }
-
- public Boolean getStreamOnDemand() {
- return streamOnDemand;
- }
-
- public void setStreamOnDemand(Boolean streamOnDemand) {
- this.streamOnDemand = streamOnDemand;
- }
-
- public Boolean getUseSourceIpAsStreamIp() {
- return useSourceIpAsStreamIp;
- }
-
- public void setUseSourceIpAsStreamIp(Boolean useSourceIpAsStreamIp) {
- this.useSourceIpAsStreamIp = useSourceIpAsStreamIp;
- }
-
- public Boolean getPushAuthority() {
- return pushAuthority;
- }
-
- public void setPushAuthority(Boolean pushAuthority) {
- this.pushAuthority = pushAuthority;
- }
-
- public Boolean getSyncChannelOnDeviceOnline() {
- return syncChannelOnDeviceOnline;
- }
-
- public void setSyncChannelOnDeviceOnline(Boolean syncChannelOnDeviceOnline) {
- this.syncChannelOnDeviceOnline = syncChannelOnDeviceOnline;
- }
-
- public String getBroadcastForPlatform() {
- return broadcastForPlatform;
- }
-
- public void setBroadcastForPlatform(String broadcastForPlatform) {
- this.broadcastForPlatform = broadcastForPlatform;
- }
-
- public Boolean getSipUseSourceIpAsRemoteAddress() {
- return sipUseSourceIpAsRemoteAddress;
- }
-
- public void setSipUseSourceIpAsRemoteAddress(Boolean sipUseSourceIpAsRemoteAddress) {
- this.sipUseSourceIpAsRemoteAddress = sipUseSourceIpAsRemoteAddress;
- }
-
- public Boolean getSipLog() {
- return sipLog;
- }
-
- public void setSipLog(Boolean sipLog) {
- this.sipLog = sipLog;
- }
-
- public List getAllowedOrigins() {
- return allowedOrigins;
- }
-
- public void setAllowedOrigins(List allowedOrigins) {
- this.allowedOrigins = allowedOrigins;
- }
-
- public Boolean getSendToPlatformsWhenIdLost() {
- return sendToPlatformsWhenIdLost;
- }
-
- public void setSendToPlatformsWhenIdLost(Boolean sendToPlatformsWhenIdLost) {
- this.sendToPlatformsWhenIdLost = sendToPlatformsWhenIdLost;
- }
-
- public Boolean getRefuseChannelStatusChannelFormNotify() {
- return refuseChannelStatusChannelFormNotify;
- }
-
- public void setRefuseChannelStatusChannelFormNotify(Boolean refuseChannelStatusChannelFormNotify) {
- this.refuseChannelStatusChannelFormNotify = refuseChannelStatusChannelFormNotify;
- }
-
- public int getMaxNotifyCountQueue() {
- return maxNotifyCountQueue;
- }
-
- public void setMaxNotifyCountQueue(int maxNotifyCountQueue) {
- this.maxNotifyCountQueue = maxNotifyCountQueue;
- }
-
- public Boolean getDeviceStatusNotify() {
- return deviceStatusNotify;
- }
-
- public void setDeviceStatusNotify(Boolean deviceStatusNotify) {
- this.deviceStatusNotify = deviceStatusNotify;
- }
-
- public Boolean getUseCustomSsrcForParentInvite() {
- return useCustomSsrcForParentInvite;
- }
-
- public void setUseCustomSsrcForParentInvite(Boolean useCustomSsrcForParentInvite) {
- this.useCustomSsrcForParentInvite = useCustomSsrcForParentInvite;
- }
-
- public Boolean getSqlLog() {
- return sqlLog;
- }
-
- public void setSqlLog(Boolean sqlLog) {
- this.sqlLog = sqlLog;
- }
-
- public String getCivilCodeFile() {
- return civilCodeFile;
- }
-
- public void setCivilCodeFile(String civilCodeFile) {
- this.civilCodeFile = civilCodeFile;
- }
-
- public int getRegisterAgainAfterTime() {
- return registerAgainAfterTime;
- }
-
- public void setRegisterAgainAfterTime(int registerAgainAfterTime) {
- this.registerAgainAfterTime = registerAgainAfterTime;
- }
-
- public boolean isRegisterKeepIntDialog() {
- return registerKeepIntDialog;
- }
-
- public void setRegisterKeepIntDialog(boolean registerKeepIntDialog) {
- this.registerKeepIntDialog = registerKeepIntDialog;
- }
-
- public Boolean getDocEnable() {
- return docEnable;
- }
-
- public void setDocEnable(Boolean docEnable) {
- this.docEnable = docEnable;
- }
-
- public int getGbDeviceOnline() {
- return gbDeviceOnline;
- }
-
- public void setGbDeviceOnline(int gbDeviceOnline) {
- this.gbDeviceOnline = gbDeviceOnline;
- }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/WVPTimerTask.java b/src/main/java/com/genersoft/iot/vmp/conf/WVPTimerTask.java
index 229aeabb7..6da0caf3a 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/WVPTimerTask.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/WVPTimerTask.java
@@ -19,7 +19,7 @@ public class WVPTimerTask {
@Autowired
private SipConfig sipConfig;
- @Scheduled(fixedRate = 2 * 1000) //每3秒执行一次
+ @Scheduled(fixedDelay = 2 * 1000) //每3秒执行一次
public void execute(){
JSONObject jsonObject = new JSONObject();
jsonObject.put("ip", sipConfig.getShowIp());
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/security/JwtAuthenticationFilter.java b/src/main/java/com/genersoft/iot/vmp/conf/security/JwtAuthenticationFilter.java
index ebeea987d..3246097a3 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/security/JwtAuthenticationFilter.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/security/JwtAuthenticationFilter.java
@@ -25,6 +25,8 @@ import java.util.ArrayList;
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
+ private final static String WSHeader = "sec-websocket-protocol";
+
@Autowired
private UserSetting userSetting;
@@ -44,17 +46,29 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
return;
}
- if (!userSetting.isInterfaceAuthentication()) {
+ if (!userSetting.getInterfaceAuthentication()) {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(null, null, new ArrayList<>() );
SecurityContextHolder.getContext().setAuthentication(token);
chain.doFilter(request, response);
return;
}
+
+
+
String jwt = request.getHeader(JwtUtils.getHeader());
// 这里如果没有jwt,继续往后走,因为后面还有鉴权管理器等去判断是否拥有身份凭证,所以是可以放行的
// 没有jwt相当于匿名访问,若有一些接口是需要权限的,则不能访问这些接口
+
+ // websocket 鉴权信息默认存储在这里
+ String secWebsocketProtocolHeader = request.getHeader(WSHeader);
if (StringUtils.isBlank(jwt)) {
- jwt = request.getParameter(JwtUtils.getHeader());
+
+ if (secWebsocketProtocolHeader != null) {
+ jwt = secWebsocketProtocolHeader;
+ response.setHeader(WSHeader, secWebsocketProtocolHeader);
+ }else {
+ jwt = request.getParameter(JwtUtils.getHeader());
+ }
if (StringUtils.isBlank(jwt)) {
jwt = request.getHeader(JwtUtils.getApiKeyHeader());
if (StringUtils.isBlank(jwt)) {
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
index d5642d98d..2bdad1ff3 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
@@ -25,6 +25,7 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
/**
* 配置Spring Security
@@ -62,7 +63,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
**/
@Override
public void configure(WebSecurity web) {
- if (userSetting.isInterfaceAuthentication()) {
+ if (userSetting.getInterfaceAuthentication()) {
ArrayList matchers = new ArrayList<>();
matchers.add("/");
matchers.add("/#/**");
@@ -104,6 +105,16 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
+
+ List defaultExcludes = userSetting.getInterfaceAuthenticationExcludes();
+ defaultExcludes.add("/api/user/login");
+ defaultExcludes.add("/index/hook/**");
+ defaultExcludes.add("/api/device/query/snap/**");
+ defaultExcludes.add("/index/hook/abl/**");
+ defaultExcludes.add("/swagger-ui/**");
+ defaultExcludes.add("/doc.html#/**");
+// defaultExcludes.add("/channel/log");
+
http.headers().contentTypeOptions().disable()
.and().cors().configurationSource(configurationSource())
.and().csrf().disable()
@@ -114,8 +125,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.and()
.authorizeRequests()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
- .antMatchers(userSetting.getInterfaceAuthenticationExcludes().toArray(new String[0])).permitAll()
- .antMatchers("/api/user/login", "/index/hook/**","/index/hook/abl/**", "/swagger-ui/**", "/doc.html#/**").permitAll()
+ .antMatchers(defaultExcludes.toArray(new String[0])).permitAll()
.anyRequest().authenticated()
// 异常处理器
.and()
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/webLog/LogChannel.java b/src/main/java/com/genersoft/iot/vmp/conf/webLog/LogChannel.java
new file mode 100644
index 000000000..e999b2717
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/conf/webLog/LogChannel.java
@@ -0,0 +1,65 @@
+package com.genersoft.iot.vmp.conf.webLog;
+
+import lombok.extern.slf4j.Slf4j;
+
+import javax.websocket.*;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+ @ServerEndpoint(value = "/channel/log")
+@Slf4j
+public class LogChannel {
+
+ public static final ConcurrentMap CHANNELS = new ConcurrentHashMap<>();
+
+ private Session session;
+
+ @OnMessage(maxMessageSize = 1) // MaxMessage 1 byte
+ public void onMessage(String message) {
+
+ try {
+ this.session.close(new CloseReason(CloseReason.CloseCodes.TOO_BIG, "此节点不接收任何客户端信息"));
+ } catch (IOException e) {
+ log.error("[Web-Log] 连接关闭失败: id={}, err={}", this.session.getId(), e.getMessage());
+ }
+ }
+
+ @OnOpen
+ public void onOpen(Session session, EndpointConfig endpointConfig) {
+ this.session = session;
+ this.session.setMaxIdleTimeout(0);
+ CHANNELS.put(this.session.getId(), this);
+
+ log.info("[Web-Log] 连接已建立: id={}", this.session.getId());
+ }
+
+ @OnClose
+ public void onClose(CloseReason closeReason) {
+
+ log.info("[Web-Log] 连接已断开: id={}, err={}", this.session.getId(), closeReason);
+ CHANNELS.remove(this.session.getId());
+ }
+
+ @OnError
+ public void onError(Throwable throwable) throws IOException {
+ log.info("[Web-Log] 连接错误: id={}, err= {}", this.session.getId(), throwable.getMessage());
+ if (this.session.isOpen()) {
+ this.session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, throwable.getMessage()));
+ }
+ }
+
+ /**
+ * Push messages to all clients
+ *
+ * @param message
+ */
+ public static void push(String message) {
+ CHANNELS.values().stream().forEach(endpoint -> {
+ if (endpoint.session.isOpen()) {
+ endpoint.session.getAsyncRemote().sendText(message);
+ }
+ });
+ }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/webLog/WebSocketAppender.java b/src/main/java/com/genersoft/iot/vmp/conf/webLog/WebSocketAppender.java
new file mode 100644
index 000000000..000ab86e9
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/conf/webLog/WebSocketAppender.java
@@ -0,0 +1,24 @@
+package com.genersoft.iot.vmp.conf.webLog;
+
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.AppenderBase;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.nio.charset.StandardCharsets;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class WebSocketAppender extends AppenderBase {
+
+ private PatternLayoutEncoder encoder;
+
+ @Override
+ protected void append(ILoggingEvent loggingEvent) {
+ byte[] data = this.encoder.encode(loggingEvent);
+ // Push to client.
+// LogChannel.push(DateUtil.timestampMsTo_yyyy_MM_dd_HH_mm_ss(loggingEvent.getTimeStamp()) + " " + loggingEvent.getFormattedMessage());
+ LogChannel.push(new String(data, StandardCharsets.UTF_8));
+ }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/websocket/WebSocketConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/websocket/WebSocketConfig.java
new file mode 100644
index 000000000..0ef52675d
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/conf/websocket/WebSocketConfig.java
@@ -0,0 +1,19 @@
+package com.genersoft.iot.vmp.conf.websocket;
+
+import com.genersoft.iot.vmp.conf.webLog.LogChannel;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+public class WebSocketConfig {
+
+ @Bean
+ public ServerEndpointExporter serverEndpointExporter(){
+ ServerEndpointExporter endpointExporter = new ServerEndpointExporter();
+
+ endpointExporter.setAnnotatedEndpointClasses(LogChannel.class);
+
+ return endpointExporter;
+ }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogData.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogData.java
index 4666b7070..2c37a1de5 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogData.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogData.java
@@ -1,9 +1,14 @@
package com.genersoft.iot.vmp.gb28181.bean;
import lombok.Data;
+import org.jetbrains.annotations.NotNull;
import java.time.Instant;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.TimeUnit;
/**
* @author lin
@@ -15,15 +20,16 @@ public class CatalogData {
*/
private int sn;
private int total;
- private List channelList;
- private List regionListList;
- private List groupListListList;
- private Instant lastTime;
+ private Instant time;
private Device device;
private String errorMsg;
+ private Set redisKeysForChannel = new HashSet<>();
+ private Set redisKeysForRegion = new HashSet<>();
+ private Set redisKeysForGroup = new HashSet<>();
public enum CatalogDataStatus{
ready, runIng, end
}
private CatalogDataStatus status;
+
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceAlarm.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceAlarm.java
index 371134160..22d3dd2ae 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceAlarm.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceAlarm.java
@@ -1,187 +1,269 @@
package com.genersoft.iot.vmp.gb28181.bean;
import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.HashSet;
+import java.util.Set;
/**
* @author lin
*/
@Schema(description = "报警信息")
+@Data
public class DeviceAlarm {
- /**
- * 数据库id
- */
- @Schema(description = "数据库id")
- private String id;
+ @Schema(description = "数据库id")
+ private String id;
- /**
- * 设备Id
- */
- @Schema(description = "设备的国标编号")
- private String deviceId;
+ @Schema(description = "设备的国标编号")
+ private String deviceId;
- /**
- * 通道Id
- */
- @Schema(description = "通道的国标编号")
- private String channelId;
+ @Schema(description = "设备名称")
+ private String deviceName;
- /**
- * 报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级警情
- */
- @Schema(description = "报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级警情")
- private String alarmPriority;
+ /**
+ * 通道Id
+ */
+ @Schema(description = "通道的国标编号")
+ private String channelId;
- /**
- * 报警方式 , 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,
- * 7其他报警;可以为直接组合如12为电话报警或 设备报警-
- */
- @Schema(description = "报警方式 , 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,\n" +
- "\t * 7其他报警;可以为直接组合如12为电话报警或设备报警")
- private String alarmMethod;
+ /**
+ * 报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级警情
+ */
+ @Schema(description = "报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级警情")
+ private String alarmPriority;
- /**
- * 报警时间
- */
- @Schema(description = "报警时间")
- private String alarmTime;
+ @Schema(description = "报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级警情")
+ private String alarmPriorityDescription;
- /**
- * 报警内容描述
- */
- @Schema(description = "报警内容描述")
- private String alarmDescription;
+ public String getAlarmPriorityDescription() {
+ switch (alarmPriority) {
+ case "1":
+ return "一级警情";
+ case "2":
+ return "二级警情";
+ case "3":
+ return "三级警情";
+ case "4":
+ return "四级警情";
+ default:
+ return alarmPriority;
+ }
+ }
- /**
- * 经度
- */
- @Schema(description = "经度")
- private double longitude;
-
- /**
- * 纬度
- */
- @Schema(description = "纬度")
- private double latitude;
-
- /**
- * 报警类型,
- * 报警方式为2时,不携带 AlarmType为默认的报警设备报警,
- * 携带 AlarmType取值及对应报警类型如下:
- * 1-视频丢失报警;
- * 2-设备防拆报警;
- * 3-存储设备磁盘满报警;
- * 4-设备高温报警;
- * 5-设备低温报警。
- * 报警方式为5时,取值如下:
- * 1-人工视频报警;
- * 2-运动目标检测报警;
- * 3-遗留物检测报警;
- * 4-物体移除检测报警;
- * 5-绊线检测报警;
- * 6-入侵检测报警;
- * 7-逆行检测报警;
- * 8-徘徊检测报警;
- * 9-流量统计报警;
- * 10-密度检测报警;
- * 11-视频异常检测报警;
- * 12-快速移动报警。
- * 报警方式为6时,取值下:
- * 1-存储设备磁盘故障报警;
- * 2-存储设备风扇故障报警。
- */
- @Schema(description = "报警类型")
- private String alarmType;
-
- @Schema(description = "创建时间")
- private String createTime;
+ /**
+ * 报警方式 , 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,
+ * 7其他报警;可以为直接组合如12为电话报警或 设备报警-
+ */
+ @Schema(description = "报警方式 , 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,\n" +
+ "\t * 7其他报警;可以为直接组合如12为电话报警或设备报警")
+ private String alarmMethod;
- public String getId() {
- return id;
+ private String alarmMethodDescription;
+
+ public String getAlarmMethodDescription() {
+ StringBuilder stringBuilder = new StringBuilder();
+ char[] charArray = alarmMethod.toCharArray();
+ for (char c : charArray) {
+ switch (c) {
+ case '1':
+ stringBuilder.append("-电话报警");
+ break;
+ case '2':
+ stringBuilder.append("-设备报警");
+ break;
+ case '3':
+ stringBuilder.append("-短信报警");
+ break;
+ case '4':
+ stringBuilder.append("-GPS报警");
+ break;
+ case '5':
+ stringBuilder.append("-视频报警");
+ break;
+ case '6':
+ stringBuilder.append("-设备故障报警");
+ break;
+ case '7':
+ stringBuilder.append("-其他报警");
+ break;
+ }
+ }
+ stringBuilder.delete(0, 1);
+ return stringBuilder.toString();
+ }
+
+ /**
+ * 报警时间
+ */
+ @Schema(description = "报警时间")
+ private String alarmTime;
+
+ /**
+ * 报警内容描述
+ */
+ @Schema(description = "报警内容描述")
+ private String alarmDescription;
+
+ /**
+ * 经度
+ */
+ @Schema(description = "经度")
+ private double longitude;
+
+ /**
+ * 纬度
+ */
+ @Schema(description = "纬度")
+ private double latitude;
+
+ /**
+ * 报警类型,
+ * 报警方式为2时,不携带 AlarmType为默认的报警设备报警,
+ * 携带 AlarmType取值及对应报警类型如下:
+ * 1-视频丢失报警;
+ * 2-设备防拆报警;
+ * 3-存储设备磁盘满报警;
+ * 4-设备高温报警;
+ * 5-设备低温报警。
+ * 报警方式为5时,取值如下:
+ * 1-人工视频报警;
+ * 2-运动目标检测报警;
+ * 3-遗留物检测报警;
+ * 4-物体移除检测报警;
+ * 5-绊线检测报警;
+ * 6-入侵检测报警;
+ * 7-逆行检测报警;
+ * 8-徘徊检测报警;
+ * 9-流量统计报警;
+ * 10-密度检测报警;
+ * 11-视频异常检测报警;
+ * 12-快速移动报警。
+ * 报警方式为6时,取值下:
+ * 1-存储设备磁盘故障报警;
+ * 2-存储设备风扇故障报警。
+ */
+ @Schema(description = "报警类型")
+ private String alarmType;
+
+ public String getAlarmTypeDescription() {
+ if (alarmType == null) {
+ return "";
+ }
+ char[] charArray = alarmMethod.toCharArray();
+ Set alarmMethodSet = new HashSet<>();
+ for (char c : charArray) {
+ alarmMethodSet.add(Character.toString(c));
+ }
+ String result = alarmType;
+ if (alarmMethodSet.contains("2")) {
+ switch (alarmType) {
+ case "1":
+ result = "视频丢失报警";
+ break;
+ case "2":
+ result = "设备防拆报警";
+ break;
+ case "3":
+ result = "存储设备磁盘满报警";
+ break;
+ case "4":
+ result = "设备高温报警";
+ break;
+ case "5":
+ result = "设备低温报警";
+ break;
+ }
+ }
+ if (alarmMethodSet.contains("5")) {
+ switch (alarmType) {
+ case "1":
+ result = "人工视频报警";
+ break;
+ case "2":
+ result = "运动目标检测报警";
+ break;
+ case "3":
+ result = "遗留物检测报警";
+ break;
+ case "4":
+ result = "物体移除检测报警";
+ break;
+ case "5":
+ result = "绊线检测报警";
+ break;
+ case "6":
+ result = "入侵检测报警";
+ break;
+ case "7":
+ result = "逆行检测报警";
+ break;
+ case "8":
+ result = "徘徊检测报警";
+ break;
+ case "9":
+ result = "流量统计报警";
+ break;
+ case "10":
+ result = "密度检测报警";
+ break;
+ case "11":
+ result = "视频异常检测报警";
+ break;
+ case "12":
+ result = "快速移动报警";
+ break;
+ }
+ }
+ if (alarmMethodSet.contains("6")) {
+ switch (alarmType) {
+ case "1":
+ result = "人工视频报警";
+ break;
+ case "2":
+ result = "运动目标检测报警";
+ break;
+ case "3":
+ result = "遗留物检测报警";
+ break;
+ case "4":
+ result = "物体移除检测报警";
+ break;
+ case "5":
+ result = "绊线检测报警";
+ break;
+ case "6":
+ result = "入侵检测报警";
+ break;
+ case "7":
+ result = "逆行检测报警";
+ break;
+ case "8":
+ result = "徘徊检测报警";
+ break;
+ case "9":
+ result = "流量统计报警";
+ break;
+ case "10":
+ result = "密度检测报警";
+ break;
+ case "11":
+ result = "视频异常检测报警";
+ break;
+ case "12":
+ result = "快速移动报警";
+ break;
+ }
+ }
+ return result;
}
- public void setId(String id) {
- this.id = id;
- }
+ @Schema(description = "报警类型描述")
+ private String alarmTypeDescription;
- public String getDeviceId() {
- return deviceId;
- }
+ @Schema(description = "创建时间")
+ private String createTime;
- public void setDeviceId(String deviceId) {
- this.deviceId = deviceId;
- }
-
- public String getAlarmPriority() {
- return alarmPriority;
- }
-
- public void setAlarmPriority(String alarmPriority) {
- this.alarmPriority = alarmPriority;
- }
-
- public String getAlarmMethod() {
- return alarmMethod;
- }
-
- public void setAlarmMethod(String alarmMethod) {
- this.alarmMethod = alarmMethod;
- }
-
- public String getAlarmTime() {
- return alarmTime;
- }
-
- public void setAlarmTime(String alarmTime) {
- this.alarmTime = alarmTime;
- }
-
- public String getAlarmDescription() {
- return alarmDescription;
- }
-
- public void setAlarmDescription(String alarmDescription) {
- this.alarmDescription = alarmDescription;
- }
-
- public double getLongitude() {
- return longitude;
- }
-
- public void setLongitude(double longitude) {
- this.longitude = longitude;
- }
-
- public double getLatitude() {
- return latitude;
- }
-
- public void setLatitude(double latitude) {
- this.latitude = latitude;
- }
-
- public String getAlarmType() {
- return alarmType;
- }
-
- public void setAlarmType(String alarmType) {
- this.alarmType = alarmType;
- }
-
- public String getChannelId() {
- return channelId;
- }
-
- public void setChannelId(String channelId) {
- this.channelId = channelId;
- }
-
- public String getCreateTime() {
- return createTime;
- }
-
- public void setCreateTime(String createTime) {
- this.createTime = createTime;
- }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/GroupTree.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/GroupTree.java
index 8ac1278e1..1f0f3658e 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/GroupTree.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/GroupTree.java
@@ -19,4 +19,7 @@ public class GroupTree extends Group{
@Schema(description = "类型, 行政区划:0 摄像头: 1")
private int type;
+ @Schema(description = "在线状态")
+ private String status;
+
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RegionTree.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RegionTree.java
index b771a603c..125bd3da7 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RegionTree.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RegionTree.java
@@ -18,4 +18,7 @@ public class RegionTree extends Region {
@Schema(description = "类型, 行政区划:0 摄像头: 1")
private int type;
+
+ @Schema(description = "在线状态")
+ private String status;
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java
index 398b107dc..2c09df4bc 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java
@@ -98,22 +98,40 @@ public class CommonChannelController {
return channel;
}
- @Operation(summary = "获取通道列表", security = @SecurityRequirement(name = JwtUtils.HEADER))
+ @Operation(summary = "获取关联行政区划通道列表", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "page", description = "当前页", required = true)
@Parameter(name = "count", description = "每页查询数量", required = true)
@Parameter(name = "query", description = "查询内容")
@Parameter(name = "online", description = "是否在线")
- @Parameter(name = "hasCivilCode", description = "是否分配行政区划")
- @GetMapping("/list")
- public PageInfo queryList(int page, int count,
+ @Parameter(name = "civilCode", description = "行政区划")
+ @GetMapping("/civilcode/list")
+ public PageInfo queryListByCivilCode(int page, int count,
@RequestParam(required = false) String query,
@RequestParam(required = false) Boolean online,
- @RequestParam(required = false) Boolean hasCivilCode,
- @RequestParam(required = false) Boolean hasGroup){
+ @RequestParam(required = false) Integer channelType,
+ @RequestParam(required = false) String civilCode){
if (ObjectUtils.isEmpty(query)){
query = null;
}
- return channelService.queryList(page, count, query, online, hasCivilCode, hasGroup);
+ return channelService.queryListByCivilCode(page, count, query, online, channelType, civilCode);
+ }
+
+ @Operation(summary = "获取关联业务分组通道列表", security = @SecurityRequirement(name = JwtUtils.HEADER))
+ @Parameter(name = "page", description = "当前页", required = true)
+ @Parameter(name = "count", description = "每页查询数量", required = true)
+ @Parameter(name = "query", description = "查询内容")
+ @Parameter(name = "online", description = "是否在线")
+ @Parameter(name = "groupDeviceId", description = "业务分组下的父节点ID")
+ @GetMapping("/parent/list")
+ public PageInfo queryListByParentId(int page, int count,
+ @RequestParam(required = false) String query,
+ @RequestParam(required = false) Boolean online,
+ @RequestParam(required = false) Integer channelType,
+ @RequestParam(required = false) String groupDeviceId){
+ if (ObjectUtils.isEmpty(query)){
+ query = null;
+ }
+ return channelService.queryListByParentId(page, count, query, online, channelType, groupDeviceId);
}
@Operation(summary = "通道设置行政区划", security = @SecurityRequirement(name = JwtUtils.HEADER))
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceControl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceControl.java
index 06d5fa85f..55017deb7 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceControl.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceControl.java
@@ -16,6 +16,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
+import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
@@ -80,22 +81,22 @@ public class DeviceControl {
@Parameter(name = "channelId", description = "通道国标编号", required = true)
@Parameter(name = "recordCmdStr", description = "命令, 可选值:Record(手动录像),StopRecord(停止手动录像)", required = true)
@GetMapping("/record/{deviceId}/{recordCmdStr}")
- public DeferredResult> recordApi(@PathVariable String deviceId,
- @PathVariable String recordCmdStr, String channelId) {
+ public DeferredResult>> recordApi(@PathVariable String deviceId,
+ @PathVariable String recordCmdStr, String channelId) {
if (log.isDebugEnabled()) {
log.debug("开始/停止录像API调用");
}
Device device = deviceService.getDeviceByDeviceId(deviceId);
String uuid = UUID.randomUUID().toString();
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
- DeferredResult> result = new DeferredResult>(3 * 1000L);
+ DeferredResult>> result = new DeferredResult<>(3 * 1000L);
result.onTimeout(() -> {
log.warn(String.format("开始/停止录像操作超时, 设备未返回应答指令"));
// 释放rtpserver
RequestMessage msg = new RequestMessage();
msg.setKey(key);
msg.setId(uuid);
- msg.setData("Timeout. Device did not response to this command.");
+ msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
resultHolder.invokeAllResult(msg);
});
if (resultHolder.exist(key, null)){
@@ -107,7 +108,7 @@ public class DeviceControl {
RequestMessage msg = new RequestMessage();
msg.setId(uuid);
msg.setKey(key);
- msg.setData(String.format("开始/停止录像操作失败,错误码: %s, %s", event.statusCode, event.msg));
+ msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("开始/停止录像操作失败,错误码: %s, %s", event.statusCode, event.msg)));
resultHolder.invokeAllResult(msg);
},null);
} catch (InvalidArgumentException | SipException | ParseException e) {
@@ -128,7 +129,7 @@ public class DeviceControl {
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
@Parameter(name = "guardCmdStr", description = "命令, 可选值:SetGuard(布防),ResetGuard(撤防)", required = true)
@GetMapping("/guard/{deviceId}/{guardCmdStr}")
- public DeferredResult guardApi(@PathVariable String deviceId, @PathVariable String guardCmdStr) {
+ public DeferredResult> guardApi(@PathVariable String deviceId, @PathVariable String guardCmdStr) {
if (log.isDebugEnabled()) {
log.debug("布防/撤防API调用");
}
@@ -140,14 +141,14 @@ public class DeviceControl {
RequestMessage msg = new RequestMessage();
msg.setId(uuid);
msg.setKey(key);
- msg.setData(String.format("布防/撤防操作失败,错误码: %s, %s", event.statusCode, event.msg));
+ msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("布防/撤防操作失败,错误码: %s, %s", event.statusCode, event.msg)));
resultHolder.invokeResult(msg);
},null);
} catch (InvalidArgumentException | SipException | ParseException e) {
log.error("[命令发送失败] 布防/撤防操作: {}", e.getMessage());
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage());
}
- DeferredResult result = new DeferredResult<>(3 * 1000L);
+ DeferredResult> result = new DeferredResult<>(3 * 1000L);
resultHolder.put(key, uuid, result);
result.onTimeout(() -> {
log.warn(String.format("布防/撤防操作超时, 设备未返回应答指令"));
@@ -155,7 +156,7 @@ public class DeviceControl {
RequestMessage msg = new RequestMessage();
msg.setKey(key);
msg.setId(uuid);
- msg.setData("Timeout. Device did not response to this command.");
+ msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
resultHolder.invokeResult(msg);
});
@@ -175,7 +176,7 @@ public class DeviceControl {
@Parameter(name = "alarmMethod", description = "报警方式")
@Parameter(name = "alarmType", description = "报警类型")
@GetMapping("/reset_alarm/{deviceId}")
- public DeferredResult> resetAlarmApi(@PathVariable String deviceId, String channelId,
+ public DeferredResult>> resetAlarmApi(@PathVariable String deviceId, String channelId,
@RequestParam(required = false) String alarmMethod,
@RequestParam(required = false) String alarmType) {
if (log.isDebugEnabled()) {
@@ -189,21 +190,21 @@ public class DeviceControl {
RequestMessage msg = new RequestMessage();
msg.setId(uuid);
msg.setKey(key);
- msg.setData(String.format("报警复位操作失败,错误码: %s, %s", event.statusCode, event.msg));
+ msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("操作失败,错误码: %s, %s", event.statusCode, event.msg)));
resultHolder.invokeResult(msg);
},null);
} catch (InvalidArgumentException | SipException | ParseException e) {
log.error("[命令发送失败] 报警复位: {}", e.getMessage());
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
}
- DeferredResult> result = new DeferredResult>(3 * 1000L);
+ DeferredResult>> result = new DeferredResult<>(3 * 1000L);
result.onTimeout(() -> {
log.warn(String.format("报警复位操作超时, 设备未返回应答指令"));
// 释放rtpserver
RequestMessage msg = new RequestMessage();
msg.setId(uuid);
msg.setKey(key);
- msg.setData("Timeout. Device did not response to this command.");
+ msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
resultHolder.invokeResult(msg);
});
resultHolder.put(key, uuid, result);
@@ -255,7 +256,7 @@ public class DeviceControl {
@Parameter(name = "presetIndex", description = "调用预置位编号")
@Parameter(name = "resetTime", description = "自动归位时间间隔 单位:秒")
@GetMapping("/home_position")
- public DeferredResult homePositionApi(String deviceId, String channelId, Boolean enabled,
+ public DeferredResult> homePositionApi(String deviceId, String channelId, Boolean enabled,
@RequestParam(required = false) Integer resetTime,
@RequestParam(required = false) Integer presetIndex) {
if (log.isDebugEnabled()) {
@@ -269,25 +270,21 @@ public class DeviceControl {
RequestMessage msg = new RequestMessage();
msg.setId(uuid);
msg.setKey(key);
- msg.setData(String.format("看守位控制操作失败,错误码: %s, %s", event.statusCode, event.msg));
+ msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("操作失败,错误码: %s, %s", event.statusCode, event.msg)));
resultHolder.invokeResult(msg);
},null);
} catch (InvalidArgumentException | SipException | ParseException e) {
log.error("[命令发送失败] 看守位控制: {}", e.getMessage());
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
}
- DeferredResult result = new DeferredResult<>(3 * 1000L);
+ DeferredResult> result = new DeferredResult<>(3 * 1000L);
result.onTimeout(() -> {
log.warn(String.format("看守位控制操作超时, 设备未返回应答指令"));
// 释放rtpserver
RequestMessage msg = new RequestMessage();
msg.setId(uuid);
msg.setKey(key);
- JSONObject json = new JSONObject();
- json.put("DeviceID", deviceId);
- json.put("Status", "Timeout");
- json.put("Description", "看守位控制操作超时, 设备未返回应答指令");
- msg.setData(json); //("看守位控制操作超时, 设备未返回应答指令");
+ msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答")); //("看守位控制操作超时, 设备未返回应答指令");
resultHolder.invokeResult(msg);
});
resultHolder.put(key, uuid, result);
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java
index c3ba87a48..f6febd83a 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java
@@ -243,8 +243,6 @@ public class DeviceQuery {
}
@Operation(summary = "修改通道的码流类型", security = @SecurityRequirement(name = JwtUtils.HEADER))
- @Parameter(name = "deviceId", description = "设备国标编号", required = true)
- @Parameter(name = "channel", description = "通道信息", required = true)
@PostMapping("/channel/stream/identification/update/")
public void updateChannelStreamIdentification(DeviceChannel channel){
deviceChannelService.updateChannelStreamIdentification(channel);
@@ -298,13 +296,10 @@ public class DeviceQuery {
@Parameter(name = "device", description = "设备", required = true)
@PostMapping("/device/update/")
public void updateDevice(Device device){
-
- if (device != null && device.getDeviceId() != null) {
- if (device.getSubscribeCycleForMobilePosition() > 0 && device.getMobilePositionSubmissionInterval() <= 0) {
- device.setMobilePositionSubmissionInterval(5);
- }
- deviceService.updateCustomDevice(device);
+ if (device == null || device.getDeviceId() == null || device.getId() <= 0) {
+ throw new ControllerException(ErrorCode.ERROR400);
}
+ deviceService.updateCustomDevice(device);
}
/**
@@ -469,7 +464,7 @@ public class DeviceQuery {
in.close();
outputStream.close();
} catch (IOException e) {
- resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/GroupController.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/GroupController.java
index ef30624c9..1284477af 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/GroupController.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/GroupController.java
@@ -40,12 +40,13 @@ public class GroupController {
@GetMapping("/tree/list")
public List queryForTree(
@RequestParam(required = false) String query,
- @RequestParam(required = false) Integer parent
+ @RequestParam(required = false) Integer parent,
+ @RequestParam(required = false) Boolean hasChannel
){
if (ObjectUtils.isEmpty(query)) {
query = null;
}
- return groupService.queryForTree(query, parent);
+ return groupService.queryForTree(query, parent, hasChannel);
}
@Operation(summary = "更新分组")
@@ -68,6 +69,14 @@ public class GroupController {
}
}
+ @Operation(summary = "获取所属的行政区划下的行政区划")
+ @Parameter(name = "deviceId", description = "当前的行政区划", required = false)
+ @ResponseBody
+ @GetMapping("/path")
+ public List getPath(String deviceId, String businessGroup){
+ return groupService.getPath(deviceId, businessGroup);
+ }
+
// @Operation(summary = "根据分组Id查询分组")
// @Parameter(name = "groupDeviceId", description = "分组节点编号", required = true)
// @ResponseBody
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/PlayController.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/PlayController.java
index 8c53ca629..e7a8b1c87 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/PlayController.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/PlayController.java
@@ -211,7 +211,7 @@ public class PlayController {
if (device == null) {
throw new ControllerException(ErrorCode.ERROR400.getCode(), "未找到设备: " + deviceId);
}
- DeviceChannel channel = deviceChannelService.getOneForSource(device.getId(), channelId);
+ DeviceChannel channel = deviceChannelService.getOne(deviceId, channelId);
if (channel == null) {
throw new ControllerException(ErrorCode.ERROR400.getCode(), "未找到通道: " + channelId);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/RegionController.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/RegionController.java
index 7da244893..3fd7f79a3 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/RegionController.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/RegionController.java
@@ -57,12 +57,13 @@ public class RegionController {
@GetMapping("/tree/list")
public List queryForTree(
@RequestParam(required = false) String query,
- @RequestParam(required = false) Integer parent
+ @RequestParam(required = false) Integer parent,
+ @RequestParam(required = false) Boolean hasChannel
){
if (ObjectUtils.isEmpty(query)) {
query = null;
}
- return regionService.queryForTree(query, parent);
+ return regionService.queryForTree(query, parent, hasChannel);
}
@Operation(summary = "更新区域")
@@ -109,6 +110,14 @@ public class RegionController {
return regionService.getAllChild(parent);
}
+ @Operation(summary = "获取所属的行政区划下的行政区划")
+ @Parameter(name = "deviceId", description = "当前的行政区划", required = false)
+ @ResponseBody
+ @GetMapping("/path")
+ public List getPath(String deviceId){
+ return regionService.getPath(deviceId);
+ }
+
@Operation(summary = "从通道中同步行政区划")
@ResponseBody
@GetMapping("/sync")
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/SseController.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/SseController.java
index 2ca1a4dba..08cb88579 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/SseController.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/SseController.java
@@ -1,16 +1,16 @@
package com.genersoft.iot.vmp.gb28181.controller;
-import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEventListener;
+import com.genersoft.iot.vmp.gb28181.session.SseSessionManager;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
-import java.io.PrintWriter;
/**
@@ -26,30 +26,17 @@ import java.io.PrintWriter;
public class SseController {
@Resource
- private AlarmEventListener alarmEventListener;
+ private SseSessionManager sseSessionManager;
/**
* SSE 推送.
*
- * @param response 响应
* @param browserId 浏览器ID
- * @throws IOException IOEXCEPTION
- * @author xiaoQQya
- * @since 2023/11/06
*/
@GetMapping("/emit")
- public void emit(HttpServletResponse response, @RequestParam String browserId) throws IOException, InterruptedException {
- response.setContentType("text/event-stream");
- response.setCharacterEncoding("utf-8");
-
- PrintWriter writer = response.getWriter();
- alarmEventListener.addSseEmitter(browserId, writer);
-
- while (!writer.checkError()) {
- Thread.sleep(1000);
- writer.write(":keep alive\n\n");
- writer.flush();
- }
- alarmEventListener.removeSseEmitter(browserId, writer);
+ public SseEmitter emit(HttpServletResponse response, @RequestParam String browserId) throws IOException, InterruptedException {
+// response.setContentType("text/event-stream");
+// response.setCharacterEncoding("utf-8");
+ return sseSessionManager.conect(browserId);
}
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java
index 52213d641..caa8fa08b 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java
@@ -255,10 +255,17 @@ public interface CommonGBChannelMapper {
@SelectProvider(type = ChannelProvider.class, method = "queryByStreamProxyId")
CommonGBChannel queryByStreamProxyId(@Param("streamProxyId") Integer streamProxyId);
- @SelectProvider(type = ChannelProvider.class, method = "queryList")
- List queryList(@Param("query") String query, @Param("online") Boolean online,
- @Param("hasCivilCode") Boolean hasCivilCode,
- @Param("hasGroup") Boolean hasGroup);
+ @SelectProvider(type = ChannelProvider.class, method = "queryListByCivilCode")
+ List queryListByCivilCode(@Param("query") String query, @Param("online") Boolean online,
+ @Param("channelType") Integer channelType, @Param("civilCode") String civilCode);
+
+
+
+ @SelectProvider(type = ChannelProvider.class, method = "queryListByParentId")
+ List queryListByParentId(@Param("query") String query, @Param("online") Boolean online,
+ @Param("channelType") Integer channelType, @Param("groupDeviceId") String groupDeviceId);
+
+
@Select(""})
+ void updateGpsByDeviceIdForStreamPush(List channels);
+
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java
index e5c65c416..ea4b97174 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java
@@ -5,11 +5,13 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelReduce;
import com.genersoft.iot.vmp.gb28181.dao.provider.DeviceChannelProvider;
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
+import com.genersoft.iot.vmp.streamPush.bean.StreamPush;
import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.List;
+import java.util.Map;
/**
* 用于存储设备通道信息
@@ -85,7 +87,10 @@ public interface DeviceChannelMapper {
int update(DeviceChannel channel);
@SelectProvider(type = DeviceChannelProvider.class, method = "queryChannels")
- List queryChannels(@Param("deviceDbId") int deviceDbId, @Param("parentChannelId") String parentChannelId, @Param("query") String query, @Param("hasSubChannel") Boolean hasSubChannel, @Param("online") Boolean online, @Param("channelIds") List channelIds);
+ List queryChannels(@Param("deviceDbId") int deviceDbId, @Param("civilCode") String civilCode,
+ @Param("businessGroupId") String businessGroupId, @Param("parentChannelId") String parentChannelId,
+ @Param("query") String query, @Param("hasSubChannel") Boolean hasSubChannel,
+ @Param("online") Boolean online, @Param("channelIds") List channelIds);
@SelectProvider(type = DeviceChannelProvider.class, method = "queryChannelsByDeviceDbId")
List queryChannelsByDeviceDbId(@Param("deviceDbId") int deviceDbId);
@@ -148,9 +153,6 @@ public interface DeviceChannelMapper {
" "})
List queryChannelsWithDeviceInfo(@Param("deviceId") String deviceId, @Param("parentChannelId") String parentChannelId, @Param("query") String query, @Param("hasSubChannel") Boolean hasSubChannel, @Param("online") Boolean online, @Param("channelIds") List channelIds);
- @Update(value = {"UPDATE wvp_device_channel SET stream_id=null WHERE device_db_id=#{deviceId} AND device_id=#{channelId}"})
- void stopPlay(@Param("deviceId") int deviceId, @Param("channelId") String channelId);
-
@Update(value = {"UPDATE wvp_device_channel SET stream_id=#{streamId} WHERE id=#{channelId}"})
void startPlay(@Param("channelId") Integer channelId, @Param("streamId") String streamId);
@@ -206,7 +208,7 @@ public interface DeviceChannelMapper {
int batchAdd(@Param("addChannels") List addChannels);
- @Update(value = {"UPDATE wvp_device_channel SET status='OFF' WHERE id=#{id}"})
+ @Update(value = {"UPDATE wvp_device_channel SET status='ON' WHERE id=#{id}"})
void online(@Param("id") int id);
@Update({""})
void updateChannelForNotify(DeviceChannel channel);
+
+
+ @Select(value = {" "})
+ DeviceChannel getOneBySourceChannelId(int deviceDbId, String channelId);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java
index cca4d84ff..3df8b8878 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java
@@ -2,9 +2,7 @@ package com.genersoft.iot.vmp.gb28181.dao;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
-import com.github.pagehelper.PageInfo;
import org.apache.ibatis.annotations.*;
-import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@@ -59,6 +57,7 @@ public interface DeviceMapper {
"firmware, " +
"transport," +
"stream_mode," +
+ "media_server_id," +
"ip," +
"sdp_ip," +
"local_ip," +
@@ -88,6 +87,7 @@ public interface DeviceMapper {
"#{firmware}," +
"#{transport}," +
"#{streamMode}," +
+ "#{mediaServerId}," +
"#{ip}," +
"#{sdpIp}," +
"#{localIp}," +
@@ -246,24 +246,12 @@ public interface DeviceMapper {
@Update(value = {" "})
void updateCustom(Device device);
@@ -280,6 +268,7 @@ public interface DeviceMapper {
"broadcast_push_after_ack,"+
"geo_coord_sys,"+
"on_line,"+
+ "stream_mode," +
"media_server_id"+
") VALUES (" +
"#{deviceId}," +
@@ -294,6 +283,7 @@ public interface DeviceMapper {
"#{broadcastPushAfterAck}," +
"#{geoCoordSys}," +
"#{onLine}," +
+ "#{streamMode}," +
"#{mediaServerId}" +
")")
void addCustomDevice(Device device);
@@ -340,7 +330,7 @@ public interface DeviceMapper {
" FROM wvp_device de" +
" where 1 = 1 "+
" AND de.on_line=${status}"+
- " AND (coalesce(custom_name, name) LIKE '%${query}%' OR device_id LIKE '%${query}%') " +
+ " AND (coalesce(custom_name, name) LIKE '%${query}%' OR device_id LIKE '%${query}%' OR ip LIKE '%${query}%') " +
" order by create_time desc "+
" ")
List getDeviceList(@Param("query") String query, @Param("status") Boolean status);
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/GroupMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/GroupMapper.java
index 5fb644680..1c89a4689 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/GroupMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/GroupMapper.java
@@ -69,7 +69,8 @@ public interface GroupMapper {
" * , " +
" concat('group', id) as tree_id," +
" 0 as type," +
- " false as is_leaf" +
+ " false as is_leaf," +
+ " 'ON' as status" +
" from wvp_common_group " +
" where 1=1 " +
" and parent_id = #{parentId} " +
@@ -153,7 +154,7 @@ public interface GroupMapper {
" SELECT " +
" wcg.device_id as gb_device_id," +
" wcg.name as gb_name," +
- " wcg.business_group as gb_business_group," +
+ " wcg.business_group as gb_business_group_id," +
" 1 as gb_parental," +
" wcg.parent_device_id as gb_parent_id" +
" from wvp_common_group wcg" +
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/PlatformChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/PlatformChannelMapper.java
index 3311a249c..d23eec4ba 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/PlatformChannelMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/PlatformChannelMapper.java
@@ -540,4 +540,12 @@ public interface PlatformChannelMapper {
" ")
Set queryShareGroup(@Param("platformId") Integer platformId);
+ @Select(" ")
+ Set queryShareRegion(Integer id);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/RegionMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/RegionMapper.java
index 42db7bbf9..9021916a6 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/RegionMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/RegionMapper.java
@@ -1,7 +1,6 @@
package com.genersoft.iot.vmp.gb28181.dao;
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
-import com.genersoft.iot.vmp.gb28181.bean.Group;
import com.genersoft.iot.vmp.gb28181.bean.Region;
import com.genersoft.iot.vmp.gb28181.bean.RegionTree;
import org.apache.ibatis.annotations.*;
@@ -74,6 +73,7 @@ public interface RegionMapper {
" *, " +
" concat('region', id) as tree_id," +
" 0 as type," +
+ " 'ON' as status," +
" false as is_leaf" +
" from wvp_common_region " +
" where " +
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java
index d4f5ce73f..2fe3dc5ef 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java
@@ -117,7 +117,7 @@ public class ChannelProvider {
}
- public String queryList(Map params ){
+ public String queryListByCivilCode(Map params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL);
sqlBuild.append(" where channel_type = 0 ");
@@ -132,18 +132,53 @@ public class ChannelProvider {
if (params.get("online") != null && !(Boolean)params.get("online")) {
sqlBuild.append(" AND coalesce(gb_status, status) = 'OFF'");
}
- if (params.get("hasCivilCode") != null && (Boolean)params.get("hasCivilCode")) {
- sqlBuild.append(" AND coalesce(gb_civil_code, civil_code) is not null");
- }
- if (params.get("hasCivilCode") != null && !(Boolean)params.get("hasCivilCode")) {
+ if (params.get("civilCode") != null) {
+ sqlBuild.append(" AND coalesce(gb_civil_code, civil_code) = #{civilCode}");
+ }else {
sqlBuild.append(" AND coalesce(gb_civil_code, civil_code) is null");
}
- if (params.get("hasGroup") != null && (Boolean)params.get("hasGroup")) {
- sqlBuild.append(" AND coalesce(gb_parent_id, parent_id) is not null");
+ if (params.get("channelType") != null) {
+ if ((Integer)params.get("channelType") == 0) {
+ sqlBuild.append(" AND device_db_id is not null");
+ }else if ((Integer)params.get("channelType") == 1) {
+ sqlBuild.append(" AND stream_push_id is not null");
+ }else if ((Integer)params.get("channelType") == 2) {
+ sqlBuild.append(" AND stream_proxy_id is not null");
+ }
}
- if (params.get("hasGroup") != null && !(Boolean)params.get("hasGroup")) {
+ return sqlBuild.toString();
+ }
+
+ public String queryListByParentId(Map params ){
+ StringBuilder sqlBuild = new StringBuilder();
+ sqlBuild.append(BASE_SQL);
+ sqlBuild.append(" where channel_type = 0 ");
+ if (params.get("query") != null) {
+ sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%')" +
+ " OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') )")
+ ;
+ }
+ if (params.get("online") != null && (Boolean)params.get("online")) {
+ sqlBuild.append(" AND coalesce(gb_status, status) = 'ON'");
+ }
+ if (params.get("online") != null && !(Boolean)params.get("online")) {
+ sqlBuild.append(" AND coalesce(gb_status, status) = 'OFF'");
+ }
+ if (params.get("groupDeviceId") != null) {
+ sqlBuild.append(" AND coalesce(gb_parent_id, parent_id) = #{groupDeviceId}");
+ }else {
sqlBuild.append(" AND coalesce(gb_parent_id, parent_id) is null");
}
+
+ if (params.get("channelType") != null) {
+ if ((Integer)params.get("channelType") == 0) {
+ sqlBuild.append(" AND device_db_id is not null");
+ }else if ((Integer)params.get("channelType") == 1) {
+ sqlBuild.append(" AND stream_push_id is not null");
+ }else if ((Integer)params.get("channelType") == 2) {
+ sqlBuild.append(" AND stream_proxy_id is not null");
+ }
+ }
return sqlBuild.toString();
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/DeviceChannelProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/DeviceChannelProvider.java
index e21b7729d..dc29280e2 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/DeviceChannelProvider.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/DeviceChannelProvider.java
@@ -1,5 +1,7 @@
package com.genersoft.iot.vmp.gb28181.dao.provider;
+import org.springframework.util.ObjectUtils;
+
import java.util.List;
import java.util.Map;
@@ -58,14 +60,20 @@ public class DeviceChannelProvider {
public String queryChannels(Map params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(getBaseSelectSql());
- sqlBuild.append(" where dc.device_db_id = #{deviceDbId}");
- if (params.get("query") != null) {
- sqlBuild.append(" AND coalesce(dc.gb_device_id, dc.device_id) LIKE concat('%',#{query},'%')" +
- " OR coalesce(dc.gb_name, dc.name) LIKE concat('%',#{query},'%')")
- ;
+ sqlBuild.append(" where dc.device_db_id = #{deviceDbId} ");
+ if (params.get("businessGroupId") != null ) {
+ sqlBuild.append(" AND coalesce(dc.gb_business_group_id, dc.business_group_id)=#{businessGroupId} AND coalesce(dc.gb_parent_id, dc.parent_id) is null");
+ }else if (params.get("parentChannelId") != null ) {
+ sqlBuild.append(" AND coalesce(dc.gb_parent_id, dc.parent_id)=#{parentChannelId}");
}
- if (params.get("parentChannelId") != null ) {
- sqlBuild.append(" AND (dc.parent_id=#{parentChannelId} OR coalesce(dc.gb_civil_code, dc.civil_code) = #{parentChannelId})");
+ if (params.get("civilCode") != null ) {
+ sqlBuild.append(" AND (coalesce(dc.gb_civil_code, dc.civil_code) = #{civilCode} " +
+ "OR (LENGTH(coalesce(dc.gb_device_id, dc.device_id))=LENGTH(#{civilCode}) + 2) AND coalesce(dc.gb_device_id, dc.device_id) LIKE concat(#{civilCode},'%'))");
+ }
+ if (params.get("query") != null && !ObjectUtils.isEmpty(params.get("query"))) {
+ sqlBuild.append(" AND (coalesce(dc.gb_device_id, dc.device_id) LIKE concat('%',#{query},'%')" +
+ " OR coalesce(dc.gb_name, dc.name) LIKE concat('%',#{query},'%'))")
+ ;
}
if (params.get("online") != null && (Boolean)params.get("online")) {
sqlBuild.append(" AND coalesce(gb_status, status) = 'ON'");
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
index 8355f2a99..7d4c876a9 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
@@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.event.device.RequestTimeoutEvent;
import com.genersoft.iot.vmp.gb28181.event.record.RecordEndEvent;
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
import com.genersoft.iot.vmp.gb28181.event.subscribe.mobilePosition.MobilePositionEvent;
+import com.genersoft.iot.vmp.media.bean.MediaServer;
import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOfflineEvent;
import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOnlineEvent;
import org.springframework.beans.factory.annotation.Autowired;
@@ -39,15 +40,15 @@ public class EventPublisher {
applicationEventPublisher.publishEvent(alarmEvent);
}
- public void mediaServerOfflineEventPublish(String mediaServerId){
+ public void mediaServerOfflineEventPublish(MediaServer mediaServer){
MediaServerOfflineEvent outEvent = new MediaServerOfflineEvent(this);
- outEvent.setMediaServerId(mediaServerId);
+ outEvent.setMediaServer(mediaServer);
applicationEventPublisher.publishEvent(outEvent);
}
- public void mediaServerOnlineEventPublish(String mediaServerId) {
+ public void mediaServerOnlineEventPublish(MediaServer mediaServer) {
MediaServerOnlineEvent outEvent = new MediaServerOnlineEvent(this);
- outEvent.setMediaServerId(mediaServerId);
+ outEvent.setMediaServer(mediaServer);
applicationEventPublisher.publishEvent(outEvent);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
index 455be8df0..a2034c726 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
@@ -29,7 +29,7 @@ public class SipSubscribe {
private final DelayQueue delayQueue = new DelayQueue<>();
- @Scheduled(fixedRate = 200) //每200毫秒执行
+ @Scheduled(fixedDelay = 200) //每200毫秒执行
public void execute(){
if (delayQueue.isEmpty()) {
return;
@@ -180,4 +180,8 @@ public class SipSubscribe {
public boolean isEmpty(){
return subscribes.isEmpty();
}
+
+ public Integer size() {
+ return subscribes.size();
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEventListener.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEventListener.java
index 317683d61..a5ffc1a1e 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEventListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/alarm/AlarmEventListener.java
@@ -1,14 +1,12 @@
package com.genersoft.iot.vmp.gb28181.event.alarm;
+import com.genersoft.iot.vmp.gb28181.session.SseSessionManager;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
-import java.io.PrintWriter;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.Resource;
/**
* 报警事件监听器.
@@ -21,48 +19,14 @@ import java.util.concurrent.ConcurrentHashMap;
@Component
public class AlarmEventListener implements ApplicationListener {
- private static final Map SSE_CACHE = new ConcurrentHashMap<>();
-
- public void addSseEmitter(String browserId, PrintWriter writer) {
- SSE_CACHE.put(browserId, writer);
- log.info("SSE 在线数量: {}", SSE_CACHE.size());
- }
-
- public void removeSseEmitter(String browserId, PrintWriter writer) {
- SSE_CACHE.remove(browserId, writer);
- log.info("SSE 在线数量: {}", SSE_CACHE.size());
- }
+ @Resource
+ private SseSessionManager sseSessionManager;
@Override
public void onApplicationEvent(@NotNull AlarmEvent event) {
if (log.isDebugEnabled()) {
log.debug("设备报警事件触发, deviceId: {}, {}", event.getAlarmInfo().getDeviceId(), event.getAlarmInfo().getAlarmDescription());
}
-
- String msg = "设备编号: " + event.getAlarmInfo().getDeviceId() + ""
- + "
通道编号: " + event.getAlarmInfo().getChannelId() + ""
- + "
报警描述: " + event.getAlarmInfo().getAlarmDescription() + ""
- + "
报警时间: " + event.getAlarmInfo().getAlarmTime() + "";
-
- for (Iterator> it = SSE_CACHE.entrySet().iterator(); it.hasNext(); ) {
- Map.Entry response = it.next();
- log.info("推送到 SSE 连接, 浏览器 ID: {}", response.getKey());
- try {
- PrintWriter writer = response.getValue();
-
- if (writer.checkError()) {
- it.remove();
- continue;
- }
-
- String sseMsg = "event:message\n" +
- "data:" + msg + "\n" +
- "\n";
- writer.write(sseMsg);
- writer.flush();
- } catch (Exception e) {
- it.remove();
- }
- }
+ sseSessionManager.sendForAll("message", event.getAlarmInfo());
}
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/sip/SipEvent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/sip/SipEvent.java
index 45b2626f0..e6af35caf 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/sip/SipEvent.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/sip/SipEvent.java
@@ -23,7 +23,7 @@ public class SipEvent implements Delayed {
private SipSubscribe.Event errorEvent;
/**
- * 超时时间
+ * 超时时间(单位: 毫秒)
*/
private long delay;
@@ -38,7 +38,7 @@ public class SipEvent implements Delayed {
@Override
public long getDelay(@NotNull TimeUnit unit) {
- return unit.convert(delay - System.currentTimeMillis(),TimeUnit.MILLISECONDS);
+ return unit.convert(delay, TimeUnit.MILLISECONDS);
}
@Override
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IDeviceChannelService.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IDeviceChannelService.java
index 8b5a8abbd..81d9f9aff 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IDeviceChannelService.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IDeviceChannelService.java
@@ -119,4 +119,7 @@ public interface IDeviceChannelService {
void updateChannelForNotify(DeviceChannel channel);
DeviceChannel getOneForSource(int deviceDbId, String channelId);
+
+ DeviceChannel getOneBySourceId(int deviceDbId, String channelId);
+
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelService.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelService.java
index ac13ffa09..2d8f95315 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelService.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelService.java
@@ -41,7 +41,9 @@ public interface IGbChannelService {
void reset(int id);
- PageInfo queryList(int page, int count, String query, Boolean online, Boolean hasCivilCode, Boolean hasGroup);
+ PageInfo queryListByCivilCode(int page, int count, String query, Boolean online, Integer channelType, String civilCode);
+
+ PageInfo queryListByParentId(int page, int count, String query, Boolean online, Integer channelType, String groupDeviceId);
void removeCivilCode(List allChildren);
@@ -81,4 +83,5 @@ public interface IGbChannelService {
List queryListByStreamPushList(List streamPushList);
+ void updateGpsByDeviceIdForStreamPush(List channels);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGroupService.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGroupService.java
index a3265bd6d..f1ff825c6 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGroupService.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGroupService.java
@@ -14,11 +14,13 @@ public interface IGroupService {
Group queryGroupByDeviceId(String regionDeviceId);
- List queryForTree(String query, Integer parent);
+ List queryForTree(String query, Integer parent, Boolean hasChannel);
void syncFromChannel();
boolean delete(int id);
boolean batchAdd(List groupList);
+
+ List getPath(String deviceId, String businessGroup);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IInviteStreamService.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IInviteStreamService.java
index 9903d59bc..e8e4d3c62 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IInviteStreamService.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IInviteStreamService.java
@@ -39,7 +39,7 @@ public interface IInviteStreamService {
*/
void removeInviteInfoByDeviceAndChannel(InviteSessionType inviteSessionType, Integer channelId);
- List getAllInviteInfo(InviteSessionType type, Integer channelId, String stream);
+ List getAllInviteInfo();
/**
* 获取点播的状态信息
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IPlatformChannelService.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IPlatformChannelService.java
index c862b6653..e03e0907e 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IPlatformChannelService.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IPlatformChannelService.java
@@ -1,9 +1,6 @@
package com.genersoft.iot.vmp.gb28181.service;
-import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
-import com.genersoft.iot.vmp.gb28181.bean.Group;
-import com.genersoft.iot.vmp.gb28181.bean.Platform;
-import com.genersoft.iot.vmp.gb28181.bean.PlatformChannel;
+import com.genersoft.iot.vmp.gb28181.bean.*;
import com.github.pagehelper.PageInfo;
import java.util.List;
@@ -45,4 +42,8 @@ public interface IPlatformChannelService {
List queryPlatFormListByChannelDeviceId(Integer channelId, List platforms);
CommonGBChannel queryChannelByPlatformIdAndChannelId(Integer platformId, Integer channelId);
+
+ void checkRegionAdd(List channelList);
+
+ void checkRegionRemove(List channelList, List regionList);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IPlayService.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IPlayService.java
index 7f8bc0142..aa2ca3ab6 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IPlayService.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IPlayService.java
@@ -30,13 +30,13 @@ public interface IPlayService {
MediaServer getNewMediaServerItem(Device device);
void playBack(Device device, DeviceChannel channel, String startTime, String endTime, ErrorCallback callback);
- void zlmServerOffline(String mediaServerId);
+ void zlmServerOffline(MediaServer mediaServer);
void download(Device device, DeviceChannel channel, String startTime, String endTime, int downloadSpeed, ErrorCallback callback);
StreamInfo getDownLoadInfo(Device device, DeviceChannel channel, String stream);
- void zlmServerOnline(String mediaServerId);
+ void zlmServerOnline(MediaServer mediaServer);
AudioBroadcastResult audioBroadcast(Device device, DeviceChannel deviceChannel, Boolean broadcastMode);
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IRegionService.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IRegionService.java
index 3fe220748..0bd8700db 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IRegionService.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IRegionService.java
@@ -27,11 +27,13 @@ public interface IRegionService {
Region queryRegionByDeviceId(String regionDeviceId);
- List queryForTree(String query, Integer parent);
+ List queryForTree(String query, Integer parent, Boolean hasChannel);
void syncFromChannel();
boolean delete(int id);
boolean batchAdd(List regionList);
+
+ List getPath(String deviceId);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceChannelServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceChannelServiceImpl.java
index 9f0d67278..198d65d10 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceChannelServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceChannelServiceImpl.java
@@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.conf.exception.ControllerException;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
+import com.genersoft.iot.vmp.gb28181.bean.GbCode;
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelReduce;
import com.genersoft.iot.vmp.gb28181.dao.DeviceChannelMapper;
@@ -36,7 +37,6 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
/**
* @author lin
@@ -272,6 +272,11 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
return channelMapper.getOneByDeviceIdForSource(deviceDbId, channelId);
}
+ @Override
+ public DeviceChannel getOneBySourceId(int deviceDbId, String channelId) {
+ return channelMapper.getOneBySourceChannelId(deviceDbId, channelId);
+ }
+
@Override
@Transactional
public synchronized void batchUpdateChannelForNotify(List channels) {
@@ -326,7 +331,6 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
@Override
public void updateChannelStreamIdentification(DeviceChannel channel) {
- Assert.isTrue(channel.getId() > 0, "通道ID必须存在");
Assert.hasLength(channel.getStreamIdentification(), "码流标识必须存在");
if (ObjectUtils.isEmpty(channel.getStreamIdentification())) {
log.info("[重置通道码流类型] 设备: {}, 码流: {}", channel.getDeviceId(), channel.getStreamIdentification());
@@ -466,7 +470,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
return false;
}
List allChannels = channelMapper.queryAllChannelsForRefresh(deviceDbId);
- Map allChannelMap = new ConcurrentHashMap<>();
+ Map allChannelMap = new HashMap<>();
if (!allChannels.isEmpty()) {
for (DeviceChannel deviceChannel : allChannels) {
allChannelMap.put(deviceChannel.getDeviceDbId() + deviceChannel.getDeviceId(), deviceChannel);
@@ -481,15 +485,8 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
StringBuilder stringBuilder = new StringBuilder();
Map subContMap = new HashMap<>();
- // 数据去重
- Set gbIdSet = new HashSet<>();
for (DeviceChannel deviceChannel : deviceChannelList) {
- if (gbIdSet.contains(deviceDbId + deviceChannel.getDeviceId())) {
- stringBuilder.append(deviceChannel.getDeviceId()).append(",");
- continue;
- }
- gbIdSet.add(deviceDbId + deviceChannel.getDeviceId());
- DeviceChannel channelInDb = allChannelMap.get(deviceDbId + deviceChannel.getDeviceId());
+ DeviceChannel channelInDb = allChannelMap.get(deviceChannel.getDeviceDbId() + deviceChannel.getDeviceId());
if (channelInDb != null) {
deviceChannel.setStreamId(channelInDb.getStreamId());
deviceChannel.setHasAudio(channelInDb.isHasAudio());
@@ -540,7 +537,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
log.info("通道重设,数据为空={}" , deviceChannelList);
return false;
}
- int limitCount = 50;
+ int limitCount = 500;
if (!addChannels.isEmpty()) {
if (addChannels.size() > limitCount) {
for (int i = 0; i < addChannels.size(); i += limitCount) {
@@ -599,7 +596,20 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
@Override
public PageInfo getSubChannels(int deviceDbId, String channelId, String query, Boolean channelType, Boolean online, int page, int count) {
PageHelper.startPage(page, count);
- List all = channelMapper.queryChannels(deviceDbId, channelId, query, channelType, online,null);
+ String civilCode = null;
+ String parentId = null;
+ String businessGroupId = null;
+ if (channelId.length() <= 8) {
+ civilCode = channelId;
+ }else {
+ GbCode decode = GbCode.decode(channelId);
+ if (Integer.parseInt(decode.getTypeCode()) == 215) {
+ businessGroupId = channelId;
+ }else {
+ parentId = channelId;
+ }
+ }
+ List all = channelMapper.queryChannels(deviceDbId, civilCode, businessGroupId, parentId, query, channelType, online,null);
return new PageInfo<>(all);
}
@@ -616,7 +626,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
}
// 获取到所有正在播放的流
PageHelper.startPage(page, count);
- List all = channelMapper.queryChannels(device.getId(), null, query, hasSubChannel, online,null);
+ List all = channelMapper.queryChannels(device.getId(), null,null, null, query, hasSubChannel, online,null);
return new PageInfo<>(all);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceServiceImpl.java
index cbef7b5fc..f731ce70b 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceServiceImpl.java
@@ -168,15 +168,13 @@ public class DeviceServiceImpl implements IDeviceService {
}
}else {
- if (deviceChannelMapper.queryChannelsByDeviceDbId(device.getId()).isEmpty()) {
- log.info("[设备上线]: {},通道数为0,查询通道信息", device.getDeviceId());
- sync(device);
- }
-
deviceMapper.update(device);
redisCatchStorage.updateDevice(device);
}
-
+ if (deviceChannelMapper.queryChannelsByDeviceDbId(device.getId()).isEmpty()) {
+ log.info("[设备上线]: {},通道数为0,查询通道信息", device.getDeviceId());
+ sync(device);
+ }
}
// 刷新过期任务
@@ -337,12 +335,12 @@ public class DeviceServiceImpl implements IDeviceService {
try {
sipCommander.catalogQuery(device, sn, event -> {
String errorMsg = String.format("同步通道失败,错误码: %s, %s", event.statusCode, event.msg);
- catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg);
+ catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), sn, errorMsg);
});
} catch (SipException | InvalidArgumentException | ParseException e) {
log.error("[同步通道], 信令发送失败:{}", e.getMessage() );
String errorMsg = String.format("同步通道失败,信令发送失败: %s", e.getMessage());
- catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg);
+ catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), sn, errorMsg);
}
}
@@ -415,39 +413,19 @@ public class DeviceServiceImpl implements IDeviceService {
device.setOnLine(false);
device.setCreateTime(DateUtil.getNow());
device.setUpdateTime(DateUtil.getNow());
+ if(device.getStreamMode() == null) {
+ device.setStreamMode("UDP");
+ }
deviceMapper.addCustomDevice(device);
}
@Override
public void updateCustomDevice(Device device) {
- Device deviceInStore = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
+ Device deviceInStore = deviceMapper.query(device.getId());
if (deviceInStore == null) {
log.warn("更新设备时未找到设备信息");
return;
}
-
- if (!ObjectUtils.isEmpty(device.getName())) {
- deviceInStore.setName(device.getName());
- }
- if (!ObjectUtils.isEmpty(device.getCharset())) {
- deviceInStore.setCharset(device.getCharset());
- }
- if (!ObjectUtils.isEmpty(device.getMediaServerId())) {
- deviceInStore.setMediaServerId(device.getMediaServerId());
- }
- if (!ObjectUtils.isEmpty(device.getCharset())) {
- deviceInStore.setCharset(device.getCharset());
- }
- if (!ObjectUtils.isEmpty(device.getSdpIp())) {
- deviceInStore.setSdpIp(device.getSdpIp());
- }
- if (!ObjectUtils.isEmpty(device.getPassword())) {
- deviceInStore.setPassword(device.getPassword());
- }
- if (!ObjectUtils.isEmpty(device.getStreamMode())) {
- deviceInStore.setStreamMode(device.getStreamMode());
- }
- deviceInStore.setBroadcastPushAfterAck(device.isBroadcastPushAfterAck());
// 目录订阅相关的信息
if (deviceInStore.getSubscribeCycleForCatalog() != device.getSubscribeCycleForCatalog()) {
if (device.getSubscribeCycleForCatalog() > 0) {
@@ -512,13 +490,9 @@ public class DeviceServiceImpl implements IDeviceService {
if (device.getCharset() == null) {
deviceInStore.setCharset("GB2312");
}
- //SSRC校验
- deviceInStore.setSsrcCheck(device.isSsrcCheck());
- //作为消息通道
- deviceInStore.setAsMessageChannel(device.isAsMessageChannel());
- deviceMapper.updateCustom(deviceInStore);
- redisCatchStorage.updateDevice(deviceInStore);
+ deviceMapper.updateCustom(device);
+ redisCatchStorage.updateDevice(device);
}
@Override
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java
index 62be902bd..38e3bd125 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java
@@ -156,7 +156,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
}
List onlineChannelList = commonGBChannelMapper.queryInListByStatus(commonGBChannelList, "ON");
if (onlineChannelList.isEmpty()) {
- log.warn("[多个通道离线] 更新失败, 参数内通道已经离线, 无需更新");
+ log.info("[多个通道离线] 更新失败, 参数内通道已经离线, 无需更新");
return 0;
}
int limitCount = 1000;
@@ -388,10 +388,16 @@ public class GbChannelServiceImpl implements IGbChannelService {
}
@Override
- public PageInfo queryList(int page, int count, String query, Boolean online, Boolean hasCivilCode,
- Boolean hasGroup) {
+ public PageInfo queryListByCivilCode(int page, int count, String query, Boolean online, Integer channelType, String civilCode) {
PageHelper.startPage(page, count);
- List all = commonGBChannelMapper.queryList(query, online, hasCivilCode, hasGroup);
+ List all = commonGBChannelMapper.queryListByCivilCode(query, online, channelType, civilCode);
+ return new PageInfo<>(all);
+ }
+
+ @Override
+ public PageInfo queryListByParentId(int page, int count, String query, Boolean online, Integer channelType, String groupDeviceId) {
+ PageHelper.startPage(page, count);
+ List all = commonGBChannelMapper.queryListByParentId(query, online, channelType, groupDeviceId);
return new PageInfo<>(all);
}
@@ -414,6 +420,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
int result = commonGBChannelMapper.updateRegion(civilCode, channelList);
// 发送通知
if (result > 0) {
+ platformChannelService.checkRegionAdd(channelList);
try {
// 发送catalog
eventPublisher.catalogEventPublish(null, channelList, CatalogEvent.UPDATE);
@@ -441,6 +448,14 @@ public class GbChannelServiceImpl implements IGbChannelService {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "所有通道Id不存在");
}
int result = commonGBChannelMapper.removeCivilCodeByChannels(channelList);
+ Region region = regionMapper.queryByDeviceId(civilCode);
+ if (region == null) {
+ platformChannelService.checkRegionRemove(channelList, null);
+ }else {
+ List regionList = new ArrayList<>();
+ regionList.add(region);
+ platformChannelService.checkRegionRemove(channelList, regionList);
+ }
// TODO 发送通知
// if (result > 0) {
// try {
@@ -459,6 +474,8 @@ public class GbChannelServiceImpl implements IGbChannelService {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "所有通道Id不存在");
}
int result = commonGBChannelMapper.removeCivilCodeByChannels(channelList);
+
+ platformChannelService.checkRegionRemove(channelList, null);
// TODO 发送通知
// if (result > 0) {
// try {
@@ -498,6 +515,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "所有通道Id不存在");
}
int result = commonGBChannelMapper.removeCivilCodeByChannels(channelList);
+ platformChannelService.checkRegionRemove(channelList, null);
}
@Override
@@ -681,4 +699,9 @@ public class GbChannelServiceImpl implements IGbChannelService {
public List queryListByStreamPushList(List streamPushList) {
return commonGBChannelMapper.queryListByStreamPushList(streamPushList);
}
+
+ @Override
+ public void updateGpsByDeviceIdForStreamPush(List channels) {
+ commonGBChannelMapper.updateGpsByDeviceIdForStreamPush(channels);
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GroupServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GroupServiceImpl.java
index ebb631cbf..3e79f7c4a 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GroupServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GroupServiceImpl.java
@@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.gb28181.service.impl;
+import com.genersoft.iot.vmp.conf.exception.ControllerException;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.dao.CommonGBChannelMapper;
import com.genersoft.iot.vmp.gb28181.dao.GroupMapper;
@@ -8,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
import com.genersoft.iot.vmp.gb28181.service.IGbChannelService;
import com.genersoft.iot.vmp.gb28181.service.IGroupService;
import com.genersoft.iot.vmp.utils.DateUtil;
+import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -15,10 +17,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
* 区域管理类
@@ -154,7 +153,7 @@ public class GroupServiceImpl implements IGroupService {
}
@Override
- public List queryForTree(String query, Integer parentId) {
+ public List queryForTree(String query, Integer parentId, Boolean hasChannel) {
List groupTrees = groupManager.queryForTree(query, parentId);
if (parentId == null) {
@@ -162,7 +161,7 @@ public class GroupServiceImpl implements IGroupService {
}
// 查询含有的通道
Group parentGroup = groupManager.queryOne(parentId);
- if (parentGroup != null ) {
+ if (parentGroup != null && hasChannel != null && hasChannel) {
List groupTreesForChannel = commonGBChannelMapper.queryForGroupTreeByParentId(query, parentGroup.getDeviceId());
if (!ObjectUtils.isEmpty(groupTreesForChannel)) {
groupTrees.addAll(groupTreesForChannel);
@@ -247,4 +246,37 @@ public class GroupServiceImpl implements IGroupService {
return true;
}
+
+ @Override
+ public List getPath(String deviceId, String businessGroup) {
+ Group businessGroupInDb = groupManager.queryBusinessGroup(businessGroup);
+ if (businessGroupInDb == null) {
+ throw new ControllerException(ErrorCode.ERROR100.getCode(), "业务分组不存在");
+ }
+ List groupList = new LinkedList<>();
+ groupList.add(businessGroupInDb);
+ Group group = groupManager.queryOneByDeviceId(deviceId, businessGroup);
+ if (group == null) {
+ throw new ControllerException(ErrorCode.ERROR100.getCode(), "虚拟组织不存在");
+ }
+ groupList.add(group);
+ List allParent = getAllParent(group);
+ groupList.addAll(allParent);
+ return groupList;
+ }
+
+ private List getAllParent(Group group) {
+ if (group.getParentId() == null || group.getBusinessGroup() == null) {
+ return new ArrayList<>();
+ }
+
+ List groupList = new ArrayList<>();
+ Group parent = groupManager.queryOneByDeviceId(group.getParentDeviceId(), group.getBusinessGroup());
+ if (parent == null) {
+ return groupList;
+ }
+ List allParent = getAllParent(parent);
+ allParent.add(parent);
+ return allParent;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/InviteStreamServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/InviteStreamServiceImpl.java
index 3ca087065..4338bbfe5 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/InviteStreamServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/InviteStreamServiceImpl.java
@@ -10,12 +10,14 @@ import com.genersoft.iot.vmp.gb28181.dao.DeviceMapper;
import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent;
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
-import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
+import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ScanOptions;
import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@@ -23,7 +25,6 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.TimeUnit;
@Slf4j
@Service
@@ -61,11 +62,12 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
}
}
}
+
@Override
public void updateInviteInfo(InviteInfo inviteInfo) {
if (InviteSessionStatus.ready == inviteInfo.getStatus()) {
updateInviteInfo(inviteInfo, Long.valueOf(userSetting.getPlayTimeout()) * 2);
- }else {
+ } else {
updateInviteInfo(inviteInfo, null);
}
}
@@ -79,10 +81,8 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
InviteInfo inviteInfoForUpdate;
if (InviteSessionStatus.ready == inviteInfo.getStatus()) {
- if (inviteInfo.getDeviceId() == null
- || inviteInfo.getChannelId() == null
- || inviteInfo.getType() == null
- || inviteInfo.getStream() == null
+ if (inviteInfo.getDeviceId() == null || inviteInfo.getChannelId() == null
+ || inviteInfo.getType() == null || inviteInfo.getStream() == null
) {
return;
}
@@ -116,17 +116,17 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
inviteInfoForUpdate = inviteInfoInRedis;
}
- String key = VideoManagerConstants.INVITE_PREFIX +
- ":" + inviteInfoForUpdate.getType() +
- ":" + inviteInfoForUpdate.getDeviceId() +
- ":" + inviteInfoForUpdate.getChannelId() +
- ":" + inviteInfoForUpdate.getStream()+
- ":" + inviteInfoForUpdate.getSsrcInfo().getSsrc();
- if (time != null && time > 0) {
- redisTemplate.opsForValue().set(key, inviteInfoForUpdate, time, TimeUnit.SECONDS);
- }else {
- redisTemplate.opsForValue().set(key, inviteInfoForUpdate);
+ if (inviteInfoForUpdate.getCreateTime() == null) {
+ inviteInfoForUpdate.setCreateTime(System.currentTimeMillis());
}
+ String key = VideoManagerConstants.INVITE_PREFIX;
+ String objectKey = inviteInfoForUpdate.getType() +
+ ":" + inviteInfoForUpdate.getChannelId() +
+ ":" + inviteInfoForUpdate.getStream();
+ if (time != null && time > 0) {
+ inviteInfoForUpdate.setExpirationTime(time);
+ }
+ redisTemplate.opsForHash().put(key, objectKey, inviteInfoForUpdate);
}
@Override
@@ -137,59 +137,54 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
return null;
}
removeInviteInfo(inviteInfoInDb);
- String key = VideoManagerConstants.INVITE_PREFIX +
- ":" + inviteInfo.getType() +
- ":" + inviteInfo.getDeviceId() +
+ String key = VideoManagerConstants.INVITE_PREFIX;
+ String objectKey = inviteInfo.getType() +
":" + inviteInfo.getChannelId() +
- ":" + stream +
- ":" + inviteInfo.getSsrcInfo().getSsrc();
+ ":" + stream;
inviteInfoInDb.setStream(stream);
if (inviteInfoInDb.getSsrcInfo() != null) {
inviteInfoInDb.getSsrcInfo().setStream(stream);
}
if (InviteSessionStatus.ready == inviteInfo.getStatus()) {
- redisTemplate.opsForValue().set(key, inviteInfoInDb, userSetting.getPlayTimeout() * 2, TimeUnit.SECONDS);
- }else {
- redisTemplate.opsForValue().set(key, inviteInfoInDb);
+ inviteInfoInDb.setExpirationTime((long) (userSetting.getPlayTimeout() * 2));
}
-
+ if (inviteInfoInDb.getCreateTime() == null) {
+ inviteInfoInDb.setCreateTime(System.currentTimeMillis());
+ }
+ redisTemplate.opsForHash().put(key, objectKey, inviteInfoInDb);
return inviteInfoInDb;
}
@Override
public InviteInfo getInviteInfo(InviteSessionType type, Integer channelId, String stream) {
- String key = VideoManagerConstants.INVITE_PREFIX +
- ":" + (type != null ? type : "*") +
- ":*" +
+ String key = VideoManagerConstants.INVITE_PREFIX;
+ String keyPattern = (type != null ? type : "*") +
":" + (channelId != null ? channelId : "*") +
- ":" + (stream != null ? stream : "*")
- + ":*";
- List