From 6e33e3f0ee952d768026fda82dc0000204e21c72 Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Tue, 18 Feb 2025 09:46:05 +0800
Subject: [PATCH] 222
---
ard-work/src/main/java/com/ard/tianyu/netty/TyNettyTcpClient.java | 3
ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java | 29 ++++++-
ard-framework/src/main/java/com/ard/framework/security/handle/LogoutSuccessHandlerImpl.java | 2
ard-work/src/main/java/com/ard/tianyu/http/TyClient.java | 20 ++--
ard-framework/src/main/java/com/ard/framework/web/service/SysLoginService.java | 16 ++++
ard-work/src/main/java/com/ard/tianyu/service/ITyService.java | 6 +
ard-admin/src/main/resources/application-dev.yml | 31 +++++--
ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java | 22 +++++
ard-common/src/main/java/com/ard/common/constant/Constants.java | 5 +
ard-work/src/main/java/com/ard/tianyu/controller/UavVideoController.java | 34 ++++++++
ard-admin/src/main/resources/application.yml | 3
ard-work/src/main/java/com/ard/tianyu/http/TokenInterceptor.java | 34 ++++++++
12 files changed, 176 insertions(+), 29 deletions(-)
diff --git a/ard-admin/src/main/resources/application-dev.yml b/ard-admin/src/main/resources/application-dev.yml
index dd65f2e..0a10dd4 100644
--- a/ard-admin/src/main/resources/application-dev.yml
+++ b/ard-admin/src/main/resources/application-dev.yml
@@ -1,8 +1,11 @@
# 开发环境配置
server:
# 服务器的HTTP端口,默认为8080
- port: 8081
-
+ port: 8080
+# token配置
+token:
+ # 是否允许账户多终端同时登录(true允许 false不允许)
+ soloLogin: false
# 日志配置
logging:
level:
@@ -22,14 +25,24 @@
password: ardkj12345
# 天宇服务器配置
+#tianyu:
+# # 天宇http服务器地址
+# endpoint: 112.98.106.22:12000
+# accesskeyid: qmfmd3Ws7M4dMcylnrTU
+# accesskeysecret: 5WBU2uEhHZaVefpZdaxpFh4LJW9fZZaa
+# # 天宇tcp服务器地址
+# tcpserver: 123.56.170.94
+# tcpport: 12345
+
+# 天宇服务器配置
tianyu:
- # 天宇http服务器地址
- endpoint: 112.98.106.22:12000
- accesskeyid: qmfmd3Ws7M4dMcylnrTU
- accesskeysecret: 5WBU2uEhHZaVefpZdaxpFh4LJW9fZZaa
- # 天宇tcp服务器地址
- tcpserver: 123.56.170.94
- tcpport: 12345
+ # 天宇http服务器地址
+ endpoint: 59.110.237.99:8060
+ accesskeyid: wuwuwu
+ accesskeysecret: 9c9f139f63b343b0a9ef42e05ed29b0b
+ # 天宇tcp服务器地址
+ tcpserver: 59.110.237.99
+ tcpport: 8124
#流媒体配置
mediamtx:
# 流媒体服务器地址
diff --git a/ard-admin/src/main/resources/application.yml b/ard-admin/src/main/resources/application.yml
index d8182d6..bf86b5e 100644
--- a/ard-admin/src/main/resources/application.yml
+++ b/ard-admin/src/main/resources/application.yml
@@ -51,7 +51,8 @@
secret: abcdefghijklmnopqrstuvwxyz
# 令牌有效期(默认30分钟)
expireTime: 720
-
+ # 是否允许账户多终端同时登录(true允许 false不允许)
+ soloLogin: false
# MyBatis配置
mybatis:
# 搜索指定包别名
diff --git a/ard-common/src/main/java/com/ard/common/constant/Constants.java b/ard-common/src/main/java/com/ard/common/constant/Constants.java
index bddbfa1..2addc7a 100644
--- a/ard-common/src/main/java/com/ard/common/constant/Constants.java
+++ b/ard-common/src/main/java/com/ard/common/constant/Constants.java
@@ -170,4 +170,9 @@
*/
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.ard.common.utils.file", "com.ard.common.config", "com.ard.generator" };
+
+ /**
+ * 登录用户编号 redis key
+ */
+ public static final String LOGIN_USERID_KEY = "login_userid:";
}
diff --git a/ard-framework/src/main/java/com/ard/framework/security/handle/LogoutSuccessHandlerImpl.java b/ard-framework/src/main/java/com/ard/framework/security/handle/LogoutSuccessHandlerImpl.java
index a7c4243..e67220f 100644
--- a/ard-framework/src/main/java/com/ard/framework/security/handle/LogoutSuccessHandlerImpl.java
+++ b/ard-framework/src/main/java/com/ard/framework/security/handle/LogoutSuccessHandlerImpl.java
@@ -44,7 +44,7 @@
{
String userName = loginUser.getUsername();
// 删除用户缓存记录
- tokenService.delLoginUser(loginUser.getToken());
+ tokenService.delLoginUser(loginUser.getToken(), loginUser.getUser().getUserId());
// 记录用户退出日志
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message("user.logout.success")));
}
diff --git a/ard-framework/src/main/java/com/ard/framework/web/service/SysLoginService.java b/ard-framework/src/main/java/com/ard/framework/web/service/SysLoginService.java
index d380f42..fd63a77 100644
--- a/ard-framework/src/main/java/com/ard/framework/web/service/SysLoginService.java
+++ b/ard-framework/src/main/java/com/ard/framework/web/service/SysLoginService.java
@@ -2,6 +2,7 @@
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -37,6 +38,10 @@
@Component
public class SysLoginService
{
+ // 是否允许账户多终端同时登录(true允许 false不允许)
+ @Value("${token.soloLogin}")
+ private boolean soloLogin;
+
@Autowired
private TokenService tokenService;
@@ -96,6 +101,17 @@
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
recordLoginInfo(loginUser.getUserId());
+ if (!soloLogin)
+ {
+ // 如果用户不允许多终端同时登录,清除缓存信息
+ String userIdKey = Constants.LOGIN_USERID_KEY + loginUser.getUser().getUserId();
+ String userKey = redisCache.getCacheObject(userIdKey);
+ if (StringUtils.isNotEmpty(userKey))
+ {
+ redisCache.deleteObject(userIdKey);
+ redisCache.deleteObject(userKey);
+ }
+ }
// 生成token
return tokenService.createToken(loginUser);
}
diff --git a/ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java b/ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java
index 5250cf1..cf08c40 100644
--- a/ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java
+++ b/ard-framework/src/main/java/com/ard/framework/web/service/TokenService.java
@@ -45,6 +45,10 @@
@Value("${token.expireTime}")
private int expireTime;
+ // 是否允许账户多终端同时登录(true允许 false不允许)
+ @Value("${token.soloLogin}")
+ private boolean soloLogin;
+
protected static final long MILLIS_SECOND = 1000;
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
@@ -96,12 +100,17 @@
/**
* 删除用户身份信息
*/
- public void delLoginUser(String token)
+ public void delLoginUser(String token, Long userId)
{
if (StringUtils.isNotEmpty(token))
{
String userKey = getTokenKey(token);
redisCache.deleteObject(userKey);
+ }
+ if (!soloLogin && StringUtils.isNotNull(userId))
+ {
+ String userIdKey = getUserIdKey(userId);
+ redisCache.deleteObject(userIdKey);
}
}
@@ -151,6 +160,12 @@
// 根据uuid将loginUser缓存
String userKey = getTokenKey(loginUser.getToken());
redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
+ if (!soloLogin)
+ {
+ // 缓存用户唯一标识,防止同一帐号,同时登录
+ String userIdKey = getUserIdKey(loginUser.getUser().getUserId());
+ redisCache.setCacheObject(userIdKey, userKey, expireTime, TimeUnit.MINUTES);
+ }
}
/**
@@ -228,4 +243,9 @@
{
return CacheConstants.LOGIN_TOKEN_KEY + uuid;
}
+
+ private String getUserIdKey(Long userId)
+ {
+ return Constants.LOGIN_USERID_KEY + userId;
+ }
}
diff --git a/ard-work/src/main/java/com/ard/tianyu/controller/UavVideoController.java b/ard-work/src/main/java/com/ard/tianyu/controller/UavVideoController.java
new file mode 100644
index 0000000..b67e762
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/controller/UavVideoController.java
@@ -0,0 +1,34 @@
+package com.ard.tianyu.controller;
+
+import com.ard.common.core.domain.AjaxResult;
+import com.ard.tianyu.model.receiver.BoxStreamUrlReceiver;
+import com.ard.tianyu.service.ITyService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * @ClassName: UavVideoController
+ * @Description: 无人机视频控制器
+ * @Author: liusuyi
+ * @Date: 2025年02月18日9:16
+ **/
+@Api(tags = "无人机视频控制器接口")
+@RequestMapping("/uav/video")
+@RestController
+public class UavVideoController {
+
+ @Resource
+ private ITyService tyService;
+
+ @ApiOperation("点播")
+ @PostMapping("/play/{boxSn}")
+ public AjaxResult play(@PathVariable("boxSn") String boxSn) {
+ return AjaxResult.success(tyService.play(boxSn));
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/http/TokenInterceptor.java b/ard-work/src/main/java/com/ard/tianyu/http/TokenInterceptor.java
new file mode 100644
index 0000000..8d664ef
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/http/TokenInterceptor.java
@@ -0,0 +1,34 @@
+package com.ard.tianyu.http;
+
+import com.ard.tianyu.config.TyConfiguration;
+import com.ard.tianyu.model.receiver.AccessTokenReceiver;
+import com.dtflys.forest.http.ForestRequest;
+import com.dtflys.forest.interceptor.Interceptor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import javax.annotation.Resource;
+
+@Component
+@Slf4j
+public class TokenInterceptor<T> implements Interceptor<T> {
+ @Resource
+ private TyConfiguration tyConfiguration;
+
+ /**
+ * 该方法在请求发送之前被调用, 若返回false则不会继续发送请求
+ *
+ * @Param request Forest请求对象
+ */
+ @Override
+ public boolean beforeExecute(ForestRequest req) {
+ log.info("invoke Simple beforeExecute");
+ // 执行在发送请求之前处理的代码
+ // 从缓存里获取token
+ AccessTokenReceiver accessToken = tyConfiguration.getAccessToken();
+ req.addHeader("x-cid", accessToken.getCompanyId());
+ req.addHeader("x-token", accessToken.getAccessToken());
+ // req.addHeader("Authorization", "")); // 添加Header
+ // req.addQuery("username", "foo"); // 添加URL的Query参数
+ return true; // 继续执行请求返回true
+ }
+}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/http/TyClient.java b/ard-work/src/main/java/com/ard/tianyu/http/TyClient.java
index b67b86f..fbfba5a 100644
--- a/ard-work/src/main/java/com/ard/tianyu/http/TyClient.java
+++ b/ard-work/src/main/java/com/ard/tianyu/http/TyClient.java
@@ -29,30 +29,30 @@
/**
* 获取云盒列表
*/
- @Get(TyConst.GET_BOX_LIST)
- TyHttpCommonReceiver<List<BoxInfoReceiver>> getBoxList(@Header Map<String, String> headers);
+ @Get(value = TyConst.GET_BOX_LIST,interceptor = TokenInterceptor.class)
+ TyHttpCommonReceiver<List<BoxInfoReceiver>> getBoxList();
/**
* 获取直播地址
*/
- @Get(TyConst.GET_BOX_LIVE_URL)
- TyHttpCommonReceiver<BoxStreamUrlReceiver> getBoxLiveUrl(@Var("boxSn") String boxSn, @Header Map<String, String> headers);
+ @Get(value =TyConst.GET_BOX_LIVE_URL,interceptor = TokenInterceptor.class)
+ TyHttpCommonReceiver<BoxStreamUrlReceiver> getBoxLiveUrl(@Var("boxSn") String boxSn);
/**
* 获取飞行历史
*/
- @Post(TyConst.POST_BOX_HISTORY)
- TyHttpCommonReceiver<List<BoxHistoryReceiver>> getBoxHistory(@JSONBody BoxHistoryDTO boxHistoryDTO, @Header Map<String, String> headers);
+ @Post(value =TyConst.POST_BOX_HISTORY,interceptor = TokenInterceptor.class)
+ TyHttpCommonReceiver<List<BoxHistoryReceiver>> getBoxHistory(@JSONBody BoxHistoryDTO boxHistoryDTO);
/**
* 获取任务照片
*/
- @Post(TyConst.POST_BOX_PHOTOS)
- TyHttpCommonReceiver<List<BoxPhotosReceiver>> getBoxPhotos(@JSONBody BoxPhotosDTO boxPhotosDTO, @Header Map<String, String> headers);
+ @Post(value =TyConst.POST_BOX_PHOTOS,interceptor = TokenInterceptor.class)
+ TyHttpCommonReceiver<List<BoxPhotosReceiver>> getBoxPhotos(@JSONBody BoxPhotosDTO boxPhotosDTO);
/**
* 修改云盒设置
*/
- @Post(TyConst.POST_BOX_UPDATE)
- TyHttpCommonReceiver<?> updateBoxSettings(@JSONBody BoxSettingsDTO boxSettingsDTO, @Header Map<String, String> headers);
+ @Post(value =TyConst.POST_BOX_UPDATE,interceptor = TokenInterceptor.class)
+ TyHttpCommonReceiver<?> updateBoxSettings(@JSONBody BoxSettingsDTO boxSettingsDTO);
}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/TyNettyTcpClient.java b/ard-work/src/main/java/com/ard/tianyu/netty/TyNettyTcpClient.java
index e226263..430fe92 100644
--- a/ard-work/src/main/java/com/ard/tianyu/netty/TyNettyTcpClient.java
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/TyNettyTcpClient.java
@@ -13,7 +13,6 @@
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
-
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
@@ -84,7 +83,7 @@
} catch (Exception e) {
e.printStackTrace();
}
- }, 5, TimeUnit.SECONDS);
+ }, 10, TimeUnit.SECONDS);
}
});
//将连接存入集合
diff --git a/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java b/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
index 0d13271..d1342fa 100644
--- a/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
+++ b/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
@@ -279,4 +279,10 @@
* 处理回复消息
*/
void processReplyMessage(String key, BaseCmd tyMessage);
+
+ /**
+ * 点播
+ */
+ String play(String boxSn);
+
}
diff --git a/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java b/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
index 6f6cdb6..b3a1f2c 100644
--- a/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
+++ b/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
@@ -49,6 +49,8 @@
import com.ard.tianyu.netty.protobuf.TelemetryDataPB;
import com.ard.tianyu.service.ITyService;
import com.ard.tianyu.websocket.utils.WebSocketUtil;
+import com.ard.vtdu.domain.ArdVtdu;
+import com.ard.vtdu.service.IMediaService;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import lombok.extern.slf4j.Slf4j;
@@ -76,6 +78,8 @@
@Resource
private TyConfiguration tyConfiguration;
+ @Resource
+ private IMediaService mediaService;
/**
* 获取天宇token信息
@@ -96,7 +100,7 @@
public List<BoxInfoReceiver> getBoxList() {
//请求云盒列表
try {
- TyHttpCommonReceiver<List<BoxInfoReceiver>> boxListReveiver = tyClient.getBoxList(tyConfiguration.getAccessToken().convertFromDTO());
+ TyHttpCommonReceiver<List<BoxInfoReceiver>> boxListReveiver = tyClient.getBoxList();
return boxListReveiver.getContent();
} catch (Exception e) {
log.error("获取云盒列表失败:{}", e.getMessage());
@@ -112,7 +116,7 @@
@Override
public BoxStreamUrlReceiver getBoxLiveUrl(String boxSn) {
- TyHttpCommonReceiver<BoxStreamUrlReceiver> boxLiveUrl = tyClient.getBoxLiveUrl(boxSn, tyConfiguration.getAccessToken().convertFromDTO());
+ TyHttpCommonReceiver<BoxStreamUrlReceiver> boxLiveUrl = tyClient.getBoxLiveUrl(boxSn);
return boxLiveUrl.getContent();
}
@@ -123,7 +127,7 @@
*/
@Override
public List<BoxHistoryReceiver> getBoxHistory(BoxHistoryDTO boxHistoryDTO) {
- TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(boxHistoryDTO, tyConfiguration.getAccessToken().convertFromDTO());
+ TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(boxHistoryDTO);
return boxHistory.getContent();
}
@@ -134,7 +138,7 @@
*/
@Override
public List<BoxPhotosReceiver> getBoxPhotos(BoxPhotosDTO boxPhotosDTO) {
- TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(boxPhotosDTO, tyConfiguration.getAccessToken().convertFromDTO());
+ TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(boxPhotosDTO);
return boxPhotos.getContent();
}
@@ -143,7 +147,7 @@
*/
@Override
public Boolean updateBoxSettings(BoxSettingsDTO boxSettingsDTO) {
- TyHttpCommonReceiver<?> result = tyClient.updateBoxSettings(boxSettingsDTO, tyConfiguration.getAccessToken().convertFromDTO());
+ TyHttpCommonReceiver<?> result = tyClient.updateBoxSettings(boxSettingsDTO);
return result.getState() == 1;
}
@@ -561,6 +565,20 @@
}
/**
+ * 点播
+ */
+ @Override
+ public String play(String boxSn) {
+ BoxStreamUrlReceiver boxLiveUrl = getBoxLiveUrl(boxSn);
+ if(boxLiveUrl == null||boxLiveUrl.getRtsp() == null) {
+ return "";
+ }
+ ArdVtdu ardVtdu = ArdVtdu.builder().name(boxSn).rtspSource(boxLiveUrl.getRtsp()).build();
+ ardVtdu = mediaService.addPath(ardVtdu);
+ return ardVtdu.getWebrtcUrl();
+ }
+
+ /**
* 处理天宇服务器返回的消息
*/
@Override
@@ -783,4 +801,5 @@
log.error("发送消息异常:{}", e.getMessage());
}
}
+
}
\ No newline at end of file
--
Gitblit v1.9.3