init
This commit is contained in:
@@ -3,6 +3,7 @@ package com.ruoyi;
|
|||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
|
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动程序
|
* 启动程序
|
||||||
@@ -11,6 +12,7 @@ import org.springframework.boot.context.metrics.buffering.BufferingApplicationSt
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
@EnableScheduling
|
||||||
public class RuoYiApplication {
|
public class RuoYiApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ spring:
|
|||||||
username: admin # 账号
|
username: admin # 账号
|
||||||
password: 383200134 # 密码
|
password: 383200134 # 密码
|
||||||
port: 5672
|
port: 5672
|
||||||
virtual-host: /cai
|
virtual-host: /cai-dev
|
||||||
agora:
|
agora:
|
||||||
app-id: app
|
app-id: app
|
||||||
key: 627b8e17b0c616c1346cba2d87e10251
|
key: 627b8e17b0c616c1346cba2d87e10251
|
||||||
|
|||||||
@@ -187,7 +187,6 @@ mybatis-plus:
|
|||||||
updateStrategy: NOT_NULL
|
updateStrategy: NOT_NULL
|
||||||
# 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件
|
# 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件
|
||||||
where-strategy: NOT_NULL
|
where-strategy: NOT_NULL
|
||||||
|
|
||||||
# 数据加密
|
# 数据加密
|
||||||
mybatis-encryptor:
|
mybatis-encryptor:
|
||||||
# 是否开启加密
|
# 是否开启加密
|
||||||
@@ -233,7 +232,8 @@ thread-pool:
|
|||||||
queueCapacity: 128
|
queueCapacity: 128
|
||||||
# 线程池维护线程所允许的空闲时间
|
# 线程池维护线程所允许的空闲时间
|
||||||
keepAliveSeconds: 300
|
keepAliveSeconds: 300
|
||||||
|
websocket:
|
||||||
|
enabled: true
|
||||||
--- # 分布式锁 lock4j 全局配置
|
--- # 分布式锁 lock4j 全局配置
|
||||||
lock4j:
|
lock4j:
|
||||||
# 获取分布式锁超时时间,默认为 3000 毫秒
|
# 获取分布式锁超时时间,默认为 3000 毫秒
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.ruoyi.cai.chat;
|
package com.ruoyi.cai.chat;
|
||||||
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
import com.ruoyi.cai.domain.Account;
|
||||||
import com.ruoyi.cai.config.CaiProperties;
|
|
||||||
import com.ruoyi.cai.domain.Anchor;
|
import com.ruoyi.cai.domain.Anchor;
|
||||||
import com.ruoyi.cai.domain.User;
|
import com.ruoyi.cai.domain.User;
|
||||||
import com.ruoyi.cai.domain.UserCall;
|
import com.ruoyi.cai.domain.UserCall;
|
||||||
@@ -12,10 +11,7 @@ import com.ruoyi.cai.dto.app.vo.chat.GetRoomResp;
|
|||||||
import com.ruoyi.cai.enums.SystemConfigEnum;
|
import com.ruoyi.cai.enums.SystemConfigEnum;
|
||||||
import com.ruoyi.cai.manager.IdManager;
|
import com.ruoyi.cai.manager.IdManager;
|
||||||
import com.ruoyi.cai.manager.SystemConfigManager;
|
import com.ruoyi.cai.manager.SystemConfigManager;
|
||||||
import com.ruoyi.cai.service.AnchorService;
|
import com.ruoyi.cai.service.*;
|
||||||
import com.ruoyi.cai.service.GuardTotalService;
|
|
||||||
import com.ruoyi.cai.service.UserCallService;
|
|
||||||
import com.ruoyi.cai.service.UserService;
|
|
||||||
import com.ruoyi.cai.ws.bean.Room;
|
import com.ruoyi.cai.ws.bean.Room;
|
||||||
import com.ruoyi.cai.ws.constant.RedisConstant;
|
import com.ruoyi.cai.ws.constant.RedisConstant;
|
||||||
import com.ruoyi.cai.ws.dto.WsToken;
|
import com.ruoyi.cai.ws.dto.WsToken;
|
||||||
@@ -23,15 +19,16 @@ import com.ruoyi.cai.ws.manager.WebSocketManager;
|
|||||||
import com.ruoyi.cai.ws.util.MapGetUtil;
|
import com.ruoyi.cai.ws.util.MapGetUtil;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import com.ruoyi.common.helper.LoginHelper;
|
import com.ruoyi.common.helper.LoginHelper;
|
||||||
|
import org.redisson.api.RMap;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -48,11 +45,11 @@ public class ChatManager {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SystemConfigManager systemConfigManager;
|
private SystemConfigManager systemConfigManager;
|
||||||
@Autowired
|
@Autowired
|
||||||
private CaiProperties properties;
|
|
||||||
@Autowired
|
|
||||||
private GuardTotalService guardTotalService;
|
private GuardTotalService guardTotalService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private StringRedisTemplate redisTemplate;
|
private RedissonClient redissonClient;
|
||||||
|
@Autowired
|
||||||
|
private AccountService accountService;
|
||||||
|
|
||||||
private String setWsToken(Long roomId,Long fromUid,Long toUid,Long userId){
|
private String setWsToken(Long roomId,Long fromUid,Long toUid,Long userId){
|
||||||
String token = IdManager.nextIdStr();
|
String token = IdManager.nextIdStr();
|
||||||
@@ -62,14 +59,16 @@ public class ChatManager {
|
|||||||
map.put("fromUid",fromUid);
|
map.put("fromUid",fromUid);
|
||||||
map.put("toUid",toUid);
|
map.put("toUid",toUid);
|
||||||
map.put("userId",userId);
|
map.put("userId",userId);
|
||||||
redisTemplate.opsForHash().putAll(tokenKey,map);
|
RMap<Object, Object> mapRedis = redissonClient.getMap(tokenKey);
|
||||||
redisTemplate.expire(tokenKey,1, TimeUnit.DAYS);
|
mapRedis.putAll(map);
|
||||||
|
mapRedis.expire(Duration.ofDays(1));
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WsToken getToken(String token){
|
public WsToken getToken(String token){
|
||||||
String tokenKey = String.format(RedisConstant.WS_TOKEN, token);
|
String tokenKey = String.format(RedisConstant.WS_TOKEN, token);
|
||||||
Map<Object, Object> entries = redisTemplate.opsForHash().entries(tokenKey);
|
RMap<Object, Object> mapRedis = redissonClient.getMap(tokenKey);
|
||||||
|
Map<Object, Object> entries = mapRedis.readAllMap();
|
||||||
if(entries.isEmpty()){
|
if(entries.isEmpty()){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -85,6 +84,9 @@ public class ChatManager {
|
|||||||
Long userId = LoginHelper.getUserId();
|
Long userId = LoginHelper.getUserId();
|
||||||
User fromUser = userService.getById(userId);
|
User fromUser = userService.getById(userId);
|
||||||
User toUser = userService.getById(callReq.getToUid());
|
User toUser = userService.getById(callReq.getToUid());
|
||||||
|
if(toUser == null){
|
||||||
|
throw new ServiceException("主播不存在");
|
||||||
|
}
|
||||||
if(toUser.getIsAnchor() != 1){
|
if(toUser.getIsAnchor() != 1){
|
||||||
throw new ServiceException("对方未通过女神认证,不能接听视频");
|
throw new ServiceException("对方未通过女神认证,不能接听视频");
|
||||||
}
|
}
|
||||||
@@ -95,11 +97,21 @@ public class ChatManager {
|
|||||||
if(anchor == null){
|
if(anchor == null){
|
||||||
throw new ServiceException("主播技能不存在");
|
throw new ServiceException("主播技能不存在");
|
||||||
}
|
}
|
||||||
|
Account account = accountService.getByUserId(userId);
|
||||||
|
if(account == null){
|
||||||
|
throw new ServiceException("账户异常,请联系客服");
|
||||||
|
}
|
||||||
|
long coin = account.getIncomeCoin() + account.getCoin();
|
||||||
|
if(coin < anchor.getPrice()*2){
|
||||||
|
throw new ServiceException("您的余额不足,请充值");
|
||||||
|
}
|
||||||
Long roomId = null;
|
Long roomId = null;
|
||||||
Room room = webSocketManager.checkOnlineRoom(fromUser.getId(), toUser.getId());
|
Room room = webSocketManager.checkOnlineRoom(fromUser.getId(), toUser.getId());
|
||||||
if(room == null){
|
if(room == null){
|
||||||
UserCall call = userCallService.createCall(fromUser, toUser, anchor);
|
UserCall call = userCallService.createCall(fromUser, toUser, anchor);
|
||||||
roomId = webSocketManager.createRoom(call.getId());
|
roomId = webSocketManager.createRoom(call.getId());
|
||||||
|
}else{
|
||||||
|
roomId = room.getRoomId();
|
||||||
}
|
}
|
||||||
String wsSocketUrlFormat = systemConfigManager.getSystemConfig(SystemConfigEnum.WS_SOCKET_URL);
|
String wsSocketUrlFormat = systemConfigManager.getSystemConfig(SystemConfigEnum.WS_SOCKET_URL);
|
||||||
String token = setWsToken(roomId, fromUser.getId(), toUser.getId(),userId);
|
String token = setWsToken(roomId, fromUser.getId(), toUser.getId(),userId);
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.ruoyi.cai.controller.admin;
|
||||||
|
|
||||||
|
import com.ruoyi.cai.mq.AmqpProducer;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/cai/mq/test")
|
||||||
|
public class MqControllerTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AmqpProducer amqpProducer;
|
||||||
|
|
||||||
|
@GetMapping("/send")
|
||||||
|
public void send(String message,Integer time){
|
||||||
|
amqpProducer.sendCheckTimeOut(message,time);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/send2")
|
||||||
|
public void send(String message){
|
||||||
|
amqpProducer.sendCalculateSales(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,7 +48,6 @@ public class UserCall implements Serializable {
|
|||||||
* 结束通话时间
|
* 结束通话时间
|
||||||
*/
|
*/
|
||||||
private LocalDateTime endTime;
|
private LocalDateTime endTime;
|
||||||
private String skillName;
|
|
||||||
/**
|
/**
|
||||||
* 通话时长
|
* 通话时长
|
||||||
*/
|
*/
|
||||||
@@ -87,6 +86,8 @@ public class UserCall implements Serializable {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
private Integer freeNum;
|
private Integer freeNum;
|
||||||
|
|
||||||
|
private Long traceId;
|
||||||
|
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public enum SystemConfigEnum {
|
|||||||
SMS_CODE_ADMIN("", "万能验证码",SystemConfigGroupEnum.SYSTEM),
|
SMS_CODE_ADMIN("", "万能验证码",SystemConfigGroupEnum.SYSTEM),
|
||||||
PASSWORD_ADMIN("", "公用密码",SystemConfigGroupEnum.SYSTEM),
|
PASSWORD_ADMIN("", "公用密码",SystemConfigGroupEnum.SYSTEM),
|
||||||
SYSTEM_CUSTOMER_SERVICE("", "系统客服",SystemConfigGroupEnum.SYSTEM),
|
SYSTEM_CUSTOMER_SERVICE("", "系统客服",SystemConfigGroupEnum.SYSTEM),
|
||||||
WS_SOCKET_URL("ws://localhost:8080?token=%s&room_id=%s", "ws通讯地址",SystemConfigGroupEnum.SYSTEM),
|
WS_SOCKET_URL("ws://localhost:8080/ws?token=%s&room_id=%s", "ws通讯地址",SystemConfigGroupEnum.SYSTEM),
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ public class AmqpProducer {
|
|||||||
CommonDelayDto dto = new CommonDelayDto();
|
CommonDelayDto dto = new CommonDelayDto();
|
||||||
dto.setType(type);
|
dto.setType(type);
|
||||||
dto.setRoomId(roomId);
|
dto.setRoomId(roomId);
|
||||||
rabbitTemplate.convertAndSend(CheckTimeOutMqConfig.EXCHANGE_NAME,
|
rabbitTemplate.convertAndSend(CommonDelayMqConfig.EXCHANGE_NAME,
|
||||||
CheckTimeOutMqConfig.ROUTING_KEY,
|
CommonDelayMqConfig.ROUTING_KEY,
|
||||||
JSON.toJSONString(dto),
|
JSON.toJSONString(dto),
|
||||||
messagePostProcessor -> {
|
messagePostProcessor -> {
|
||||||
messagePostProcessor.getMessageProperties().setDelay(timeout*1000); // 设置延迟时间,单位毫秒
|
messagePostProcessor.getMessageProperties().setDelay(timeout*1000); // 设置延迟时间,单位毫秒
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class CheckTimeOutMqConfig {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding delayedBinding(Queue delayedQueue,CustomExchange delayedExchange) {
|
public Binding delayedBinding(Queue delayedQueue,CustomExchange delayedExchange) {
|
||||||
return BindingBuilder.bind(delayedQueue()).to(delayedExchange()).with(ROUTING_KEY).noargs();
|
return BindingBuilder.bind(delayedQueue).to(delayedExchange).with(ROUTING_KEY).noargs();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class CommonDelayMqConfig {
|
|||||||
public static final String ROUTING_KEY = "commonDelayRouting";
|
public static final String ROUTING_KEY = "commonDelayRouting";
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public CustomExchange delayedExchange() {
|
public CustomExchange commonDelayedExchange() {
|
||||||
HashMap<String,Object> args = new HashMap<>();
|
HashMap<String,Object> args = new HashMap<>();
|
||||||
args.put("x-delayed-type", "direct");
|
args.put("x-delayed-type", "direct");
|
||||||
return new CustomExchange(EXCHANGE_NAME,
|
return new CustomExchange(EXCHANGE_NAME,
|
||||||
@@ -26,15 +26,15 @@ public class CommonDelayMqConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Queue delayedQueue() {
|
public Queue commonDelayedQueue() {
|
||||||
return QueueBuilder.durable(QUEUE_NAME)
|
return QueueBuilder.durable(QUEUE_NAME)
|
||||||
.withArgument("x-delayed-type", "direct")
|
.withArgument("x-delayed-type", "direct")
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Binding delayedBinding(Queue delayedQueue,CustomExchange delayedExchange) {
|
public Binding commonDelayedBinding(Queue commonDelayedQueue,CustomExchange commonDelayedExchange) {
|
||||||
return BindingBuilder.bind(delayedQueue()).to(delayedExchange()).with(ROUTING_KEY).noargs();
|
return BindingBuilder.bind(commonDelayedQueue()).to(commonDelayedExchange()).with(ROUTING_KEY).noargs();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,16 @@ public class CheckTimeOutMqConsumer {
|
|||||||
@RabbitListener(queues = CheckTimeOutMqConfig.QUEUE_NAME
|
@RabbitListener(queues = CheckTimeOutMqConfig.QUEUE_NAME
|
||||||
,containerFactory = "customContainerFactory")
|
,containerFactory = "customContainerFactory")
|
||||||
public void checkTimeOutMq(String message) {
|
public void checkTimeOutMq(String message) {
|
||||||
log.info("checkTimeOutMq: " + message);
|
log.info("开始执行预扣费: " + message);
|
||||||
boolean next = settleService.withholdingFee(Long.valueOf(message));
|
try {
|
||||||
if(next){
|
boolean next = settleService.withholdingFee(Long.valueOf(message));
|
||||||
// 1分钟后继续执行
|
if(next){
|
||||||
amqpProducer.sendCheckTimeOut(message,60);
|
// 1分钟后继续执行
|
||||||
|
amqpProducer.sendCheckTimeOut(message,60);
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("每分钟定时扣费失败!",e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
Long callPrice = roomData.getCallPrice();
|
Long callPrice = roomData.getCallPrice();
|
||||||
Long callTime = roomService.getCallTime(room);
|
Long callTime = roomService.getCallTime(room);
|
||||||
// 本次支付金额
|
// 本次支付金额
|
||||||
long totalAmount = callPrice * (callTime / 60); // 本次需要支付的金额
|
long totalAmount = callPrice * ((callTime / 60) + 1); // 本次需要支付的金额
|
||||||
Long payCoin = roomData.getPayCoin(); // 已经支付的余额
|
Long payCoin = roomData.getPayCoin(); // 已经支付的余额
|
||||||
Long payIncome = roomData.getPayIncome(); // 已经支付的收益
|
Long payIncome = roomData.getPayIncome(); // 已经支付的收益
|
||||||
// 补差价
|
// 补差价
|
||||||
@@ -357,9 +357,10 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
consumeLogService.save(consumeLog);
|
consumeLogService.save(consumeLog);
|
||||||
userCallService.update(Wrappers.lambdaUpdate(UserCall.class)
|
userCallService.update(Wrappers.lambdaUpdate(UserCall.class)
|
||||||
.eq(UserCall::getId, userCall.getId())
|
.eq(UserCall::getId, userCall.getId())
|
||||||
|
.set(UserCall::getTraceId,tractId)
|
||||||
.set(UserCall::getBeginTime, DateUtil.date(roomData.getBeginTime()).toLocalDateTime())
|
.set(UserCall::getBeginTime, DateUtil.date(roomData.getBeginTime()).toLocalDateTime())
|
||||||
.set(UserCall::getEndTime,DateUtil.date(roomData.getHangUpTime()).toLocalDateTime())
|
.set(UserCall::getEndTime,DateUtil.date(roomData.getHangupTime()).toLocalDateTime())
|
||||||
.set(UserCall::getCallTime,roomData.getHangUpTime() - roomData.getBeginTime())
|
.set(UserCall::getCallTime,roomData.getHangupTime() - roomData.getBeginTime())
|
||||||
.set(UserCall::getCallAmount,amountReal)
|
.set(UserCall::getCallAmount,amountReal)
|
||||||
.set(UserCall::getCallIncome, anchorAmount)
|
.set(UserCall::getCallIncome, anchorAmount)
|
||||||
.set(UserCall::getStatus, RoomStatusEnums.STATUS_HANGUP.getCode()));
|
.set(UserCall::getStatus, RoomStatusEnums.STATUS_HANGUP.getCode()));
|
||||||
@@ -367,6 +368,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
resp.setConsumeLog(consumeLog);
|
resp.setConsumeLog(consumeLog);
|
||||||
resp.setPayIncome(payIncome);
|
resp.setPayIncome(payIncome);
|
||||||
resp.setPayCoin(payCoin);
|
resp.setPayCoin(payCoin);
|
||||||
|
resp.setAnchorIncome(anchorAmount);
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ public class UserCallServiceImpl extends ServiceImpl<UserCallMapper, UserCall> i
|
|||||||
}
|
}
|
||||||
UserCall userCall = new UserCall();
|
UserCall userCall = new UserCall();
|
||||||
userCall.setFromUid(fromUid);
|
userCall.setFromUid(fromUid);
|
||||||
|
userCall.setFromUsercode(fromUser.getUsercode());
|
||||||
userCall.setToUid(toUser.getId());
|
userCall.setToUid(toUser.getId());
|
||||||
|
userCall.setToUsercode(toUser.getUsercode());
|
||||||
userCall.setCallPrice(anchor.getPrice());
|
userCall.setCallPrice(anchor.getPrice());
|
||||||
userCall.setReceiverVideoDivide(anchor.getVideoRate());
|
userCall.setReceiverVideoDivide(anchor.getVideoRate());
|
||||||
boolean save = this.save(userCall);
|
boolean save = this.save(userCall);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import com.ruoyi.cai.dto.app.vo.user.UserListVo;
|
|||||||
import com.ruoyi.cai.dto.app.vo.user.OnlineStatusVo;
|
import com.ruoyi.cai.dto.app.vo.user.OnlineStatusVo;
|
||||||
import com.ruoyi.cai.mapper.UserMapper;
|
import com.ruoyi.cai.mapper.UserMapper;
|
||||||
import com.ruoyi.cai.service.*;
|
import com.ruoyi.cai.service.*;
|
||||||
|
import com.ruoyi.cai.ws.service.RoomService;
|
||||||
import com.ruoyi.common.core.domain.PageQuery;
|
import com.ruoyi.common.core.domain.PageQuery;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import com.ruoyi.common.helper.LoginHelper;
|
import com.ruoyi.common.helper.LoginHelper;
|
||||||
@@ -61,6 +62,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
|||||||
private UserForbidService userForbidService;
|
private UserForbidService userForbidService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private AnchorApplyService anchorApplyService;
|
private AnchorApplyService anchorApplyService;
|
||||||
|
@Autowired
|
||||||
|
private RoomService roomService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User getByUsername(String username) {
|
public User getByUsername(String username) {
|
||||||
@@ -114,7 +117,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
|||||||
// 在线状态
|
// 在线状态
|
||||||
OnlineStatusVo onlineStatusVo;
|
OnlineStatusVo onlineStatusVo;
|
||||||
if(user.getIsAnchor() == 1 && anchor != null){
|
if(user.getIsAnchor() == 1 && anchor != null){
|
||||||
onlineStatusVo = userOnlineService.onlineStatus(userId,anchor.getOpenVideoStatus(),anchor.getVideoStatus(), user.getIsAnchor());
|
boolean runningVideo = roomService.checkRunningVideo(userId, anchor.getUserId());
|
||||||
|
onlineStatusVo = userOnlineService.onlineStatus(userId,anchor.getOpenVideoStatus(),
|
||||||
|
runningVideo?1:anchor.getVideoStatus(), user.getIsAnchor());
|
||||||
}else{
|
}else{
|
||||||
onlineStatusVo = userOnlineService.onlineStatus(userId,0,0, user.getIsAnchor());
|
onlineStatusVo = userOnlineService.onlineStatus(userId,0,0, user.getIsAnchor());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class RoomData {
|
|||||||
private BigDecimal videoDivide;
|
private BigDecimal videoDivide;
|
||||||
private Long payCoin = 0L;
|
private Long payCoin = 0L;
|
||||||
private Long payIncome = 0L;
|
private Long payIncome = 0L;
|
||||||
private Long hangUpTime; // 结束时间
|
private Long hangupTime; // 结束时间
|
||||||
|
|
||||||
private Long settleTime; // 结算时间
|
private Long settleTime; // 结算时间
|
||||||
|
|
||||||
|
|||||||
@@ -2,19 +2,23 @@ package com.ruoyi.cai.ws.cache;
|
|||||||
|
|
||||||
import com.ruoyi.cai.ws.constant.RedisConstant;
|
import com.ruoyi.cai.ws.constant.RedisConstant;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
|
import org.redisson.api.RMap;
|
||||||
|
import org.redisson.api.RScript;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class CallerRoomCache {
|
public class CallerRoomCache {
|
||||||
@Autowired
|
@Autowired
|
||||||
private StringRedisTemplate redisTemplate;
|
private StringRedisTemplate redisTemplate;
|
||||||
|
@Autowired
|
||||||
|
private RedissonClient redissonClient;
|
||||||
|
|
||||||
public String getKey(Long fromUserId){
|
public String getKey(Long fromUserId){
|
||||||
return String.format(RedisConstant.CALLER_ROOM_DATA,fromUserId);
|
return String.format(RedisConstant.CALLER_ROOM_DATA,fromUserId);
|
||||||
@@ -22,36 +26,46 @@ public class CallerRoomCache {
|
|||||||
|
|
||||||
public Long getRoomId(Long fromUserId, Long toUserId){
|
public Long getRoomId(Long fromUserId, Long toUserId){
|
||||||
String key = getKey(fromUserId);
|
String key = getKey(fromUserId);
|
||||||
Object roomId = redisTemplate.opsForHash().get(key, toUserId);
|
RMap<String, Object> map = redissonClient.getMap(key);
|
||||||
|
Object roomId = map.get(toUserId+"");
|
||||||
return roomId == null ? null : Long.valueOf(roomId.toString());
|
return roomId == null ? null : Long.valueOf(roomId.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRoom(Long fromUid, Long toUid, Long roomId) {
|
public void addRoom(Long fromUid, Long toUid, Long roomId) {
|
||||||
String key = getKey(fromUid);
|
String key = getKey(fromUid);
|
||||||
redisTemplate.opsForHash().put(key,toUid,roomId);
|
RMap<String, Object> map = redissonClient.getMap(key);
|
||||||
redisTemplate.expire(key,7, TimeUnit.DAYS);
|
map.put(toUid+"",roomId+"");
|
||||||
|
map.expire(Duration.ofDays(7));
|
||||||
|
// map.expire(7,TimeUnit.DAYS);
|
||||||
|
// redisTemplate.opsForHash().put(key,toUid,roomId);
|
||||||
|
// redisTemplate.expire(key,7, TimeUnit.DAYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Object,Object> getAll(Long fromUid){
|
public Map<Object,Object> getAll(Long fromUid){
|
||||||
String key = getKey(fromUid);
|
String key = getKey(fromUid);
|
||||||
return redisTemplate.opsForHash().entries(key);
|
RMap<Object, Object> map = redissonClient.getMap(key);
|
||||||
|
return map.readAllMap();
|
||||||
|
// return redisTemplate.opsForHash().entries(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void del(Long fromUid) {
|
public void del(Long fromUid) {
|
||||||
String key = getKey(fromUid);
|
String key = getKey(fromUid);
|
||||||
redisTemplate.delete(key);
|
redissonClient.getMap(key).delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static String DEL_ROOM_LUA = "return KEYS[1]\n" +
|
private final static String DEL_ROOM_LUA =
|
||||||
"local r = tonumber(redis.call('hget',KEYS[1],ARGV[1]))\n" +
|
"local r = tonumber(redis.call('hget',KEYS[1],ARGV[1]))\n" +
|
||||||
"if r == tonumber(ARGV[2]) then\n" +
|
"if r == tonumber(ARGV[2]) then\n" +
|
||||||
" return redis.call('hdel',KEYS[1],ARGV[1])\n" +
|
" return redis.call('hdel',KEYS[1],ARGV[1])\n" +
|
||||||
"end\n" +
|
"end\n" +
|
||||||
"return 0";
|
"return 0";
|
||||||
|
|
||||||
public boolean delRoom(Long receiverId, Long roomId) {
|
public boolean delRoom(Long callerId, Long receiverId, Long roomId) {
|
||||||
DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(DEL_ROOM_LUA,Boolean.class);
|
RScript script = redissonClient.getScript();
|
||||||
Boolean execute = redisTemplate.execute(redisScript, Collections.singletonList(getKey(roomId)), receiverId,roomId);
|
Boolean execute = script.eval(RScript.Mode.READ_WRITE, DEL_ROOM_LUA, RScript.ReturnType.BOOLEAN,
|
||||||
|
Collections.singletonList(getKey(callerId)), receiverId+"", roomId+"");
|
||||||
|
// DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(DEL_ROOM_LUA,Boolean.class);
|
||||||
|
// Boolean execute = redisTemplate.execute(redisScript, Collections.singletonList(getKey(roomId)), receiverId,roomId);
|
||||||
return BooleanUtils.isTrue(execute);
|
return BooleanUtils.isTrue(execute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package com.ruoyi.cai.ws.cache;
|
package com.ruoyi.cai.ws.cache;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import com.ruoyi.cai.ws.bean.FdCtxData;
|
import com.ruoyi.cai.ws.bean.FdCtxData;
|
||||||
import com.ruoyi.cai.ws.constant.RedisConstant;
|
import com.ruoyi.cai.ws.constant.RedisConstant;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.redisson.api.RBucket;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -21,24 +19,21 @@ import java.util.concurrent.TimeUnit;
|
|||||||
@Component
|
@Component
|
||||||
public class FdCtxDataCache {
|
public class FdCtxDataCache {
|
||||||
@Autowired
|
@Autowired
|
||||||
private StringRedisTemplate redisTemplate;
|
private RedissonClient redissonClient;
|
||||||
|
|
||||||
public String getKey(String sessionKey){
|
public String getKey(String sessionKey){
|
||||||
return String.format(RedisConstant.FDCTX_DATA,sessionKey);
|
return String.format(RedisConstant.FDCTX_DATA,sessionKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(FdCtxData fdCtxData) {
|
public void save(FdCtxData fdCtxData) {
|
||||||
String str = JSON.toJSONString(fdCtxData);
|
RBucket<FdCtxData> bucket = redissonClient.getBucket(getKey(fdCtxData.getSessionKey()));
|
||||||
redisTemplate.opsForValue().set(getKey(fdCtxData.getSessionKey()),str,5, TimeUnit.DAYS);
|
bucket.set(fdCtxData,5,TimeUnit.DAYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FdCtxData getByRoomId(String sessionKey){
|
public FdCtxData getByRoomId(String sessionKey){
|
||||||
String key = getKey(sessionKey);
|
String key = getKey(sessionKey);
|
||||||
String s = redisTemplate.opsForValue().get(key);
|
RBucket<FdCtxData> bucket = redissonClient.getBucket(key);
|
||||||
if(StringUtils.isEmpty(s)){
|
return bucket.get();
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return JSON.parseObject(s,FdCtxData.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.ruoyi.cai.ws.cache;
|
package com.ruoyi.cai.ws.cache;
|
||||||
|
|
||||||
import com.ruoyi.cai.ws.constant.RedisConstant;
|
import com.ruoyi.cai.ws.constant.RedisConstant;
|
||||||
|
import org.redisson.api.RSet;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -12,20 +14,28 @@ import java.util.Set;
|
|||||||
public class OnlineDataCache {
|
public class OnlineDataCache {
|
||||||
@Autowired
|
@Autowired
|
||||||
private StringRedisTemplate redisTemplate;
|
private StringRedisTemplate redisTemplate;
|
||||||
|
@Autowired
|
||||||
|
private RedissonClient redissonClient;
|
||||||
|
|
||||||
public String getKey(){
|
public String getKey(){
|
||||||
return RedisConstant.ONLINE_ROOM_DATA;
|
return RedisConstant.ONLINE_ROOM_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getAll(){
|
public Set<String> getAll(){
|
||||||
return redisTemplate.opsForSet().members(getKey());
|
RSet<String> set = redissonClient.getSet(getKey());
|
||||||
|
return set.readAll();
|
||||||
|
// return redisTemplate.opsForSet().members(getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(Long roomId){
|
public void add(Long roomId){
|
||||||
redisTemplate.opsForSet().add(getKey(), String.valueOf(roomId));
|
RSet<String> set = redissonClient.getSet(getKey());
|
||||||
|
set.add(String.valueOf(roomId));
|
||||||
|
// redisTemplate.opsForSet().add(getKey(), String.valueOf(roomId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(Long roomId) {
|
public void remove(Long roomId) {
|
||||||
redisTemplate.opsForSet().remove(getKey(),roomId);
|
RSet<String> set = redissonClient.getSet(getKey());
|
||||||
|
set.delete();
|
||||||
|
// redisTemplate.opsForSet().remove(getKey(),roomId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,18 @@ package com.ruoyi.cai.ws.cache;
|
|||||||
import com.ruoyi.cai.ws.constant.RedisConstant;
|
import com.ruoyi.cai.ws.constant.RedisConstant;
|
||||||
import com.ruoyi.cai.ws.constant.UserDataConstant;
|
import com.ruoyi.cai.ws.constant.UserDataConstant;
|
||||||
import com.ruoyi.cai.ws.holder.WebSocketSessionHolder;
|
import com.ruoyi.cai.ws.holder.WebSocketSessionHolder;
|
||||||
|
import org.redisson.api.RMap;
|
||||||
|
import org.redisson.api.RSet;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,6 +27,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
public class RoomCtxCache {
|
public class RoomCtxCache {
|
||||||
@Autowired
|
@Autowired
|
||||||
private StringRedisTemplate redisTemplate;
|
private StringRedisTemplate redisTemplate;
|
||||||
|
@Autowired
|
||||||
|
private RedissonClient redissonClient;
|
||||||
|
|
||||||
public String getKey(Long roomId){
|
public String getKey(Long roomId){
|
||||||
return String.format(RedisConstant.FDCTX_ROOM_DATA,roomId);
|
return String.format(RedisConstant.FDCTX_ROOM_DATA,roomId);
|
||||||
@@ -29,23 +36,28 @@ public class RoomCtxCache {
|
|||||||
|
|
||||||
public void addFd(String sessionKey,Long roomId,Integer userType){
|
public void addFd(String sessionKey,Long roomId,Integer userType){
|
||||||
String key = getKey(roomId);
|
String key = getKey(roomId);
|
||||||
redisTemplate.opsForHash().put(key,sessionKey,userType);
|
RMap<Object, Object> map = redissonClient.getMap(key);
|
||||||
redisTemplate.expire(key,7, TimeUnit.DAYS);
|
map.put(sessionKey,userType);
|
||||||
|
map.expire(Duration.ofDays(7));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getSessionKeysByRoomId(Long roomId){
|
public List<String> getSessionKeysByRoomId(Long roomId){
|
||||||
String key = getKey(roomId);
|
String key = getKey(roomId);
|
||||||
Map<Object, Object> entries = redisTemplate.opsForHash().entries(key);
|
RMap<String, Object> entries = redissonClient.getMap(key);
|
||||||
List<String> res = new ArrayList<>();
|
Set<String> set = entries.readAllKeySet();
|
||||||
for (Object o : entries.keySet()) {
|
List<String> keys = new ArrayList<>();
|
||||||
res.add(String.valueOf(o));
|
for (String sessionKey : set) {
|
||||||
|
if(WebSocketSessionHolder.existSession(sessionKey)){
|
||||||
|
keys.add(sessionKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSessionKeyByRoomIdAndUserType(Long roomId,Integer userType){
|
public String getSessionKeyByRoomIdAndUserType(Long roomId,Integer userType){
|
||||||
String key = getKey(roomId);
|
String key = getKey(roomId);
|
||||||
Map<Object, Object> entries = redisTemplate.opsForHash().entries(key);
|
RMap<Object, Object> map = redissonClient.getMap(key);
|
||||||
|
Map<Object, Object> entries = map.readAllMap();
|
||||||
for (Map.Entry<Object, Object> entry : entries.entrySet()) {
|
for (Map.Entry<Object, Object> entry : entries.entrySet()) {
|
||||||
String sessionKey = String.valueOf(entry.getKey());
|
String sessionKey = String.valueOf(entry.getKey());
|
||||||
Integer userTypeK = Integer.valueOf(entry.getValue().toString());
|
Integer userTypeK = Integer.valueOf(entry.getValue().toString());
|
||||||
|
|||||||
@@ -6,12 +6,16 @@ import com.ruoyi.cai.ws.bean.RoomData;
|
|||||||
import com.ruoyi.cai.ws.constant.RedisConstant;
|
import com.ruoyi.cai.ws.constant.RedisConstant;
|
||||||
import com.ruoyi.cai.ws.constant.RoomStatusEnums;
|
import com.ruoyi.cai.ws.constant.RoomStatusEnums;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
|
import org.redisson.api.RMap;
|
||||||
|
import org.redisson.api.RScript;
|
||||||
import org.redisson.api.RedissonClient;
|
import org.redisson.api.RedissonClient;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -26,6 +30,8 @@ public class RoomDataCache {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private RedissonClient redissonClient;
|
private RedissonClient redissonClient;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
private RedisTemplate redisTemplate;
|
||||||
|
@Autowired
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
public String getKey(Long roomId){
|
public String getKey(Long roomId){
|
||||||
@@ -33,82 +39,105 @@ public class RoomDataCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public RoomData getByRoomId(Long roomId){
|
public RoomData getByRoomId(Long roomId){
|
||||||
Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(getKey(roomId));
|
RMap<String, Object> map = redissonClient.getMap(getKey(roomId));
|
||||||
if(map.get("roomId") == null){
|
Map<String, Object> allMap = map.readAllMap();
|
||||||
|
// Map<Object, Object> map = redisTemplate.opsForHash().entries(getKey(roomId));
|
||||||
|
if(allMap.get("roomId") == null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return JSON.parseObject(JSON.toJSONString(map),RoomData.class);
|
return JSON.parseObject(JSON.toJSONString(allMap),RoomData.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(RoomData roomData) {
|
public void init(RoomData roomData) {
|
||||||
Map<String,Object> map = JSON.parseObject(JSON.toJSONString(roomData));
|
Map<String,Object> map = JSON.parseObject(JSON.toJSONString(roomData));
|
||||||
stringRedisTemplate.opsForHash().putAll(getKey(roomData.getRoomId()),map);
|
// redisTemplate.opsForHash().putAll(getKey(roomData.getRoomId()),map);
|
||||||
|
RMap<String, Object> mapRedis = redissonClient.getMap(getKey(roomData.getRoomId()));
|
||||||
|
mapRedis.putAll(map);
|
||||||
|
mapRedis.expire(Duration.ofDays(15));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hMSet(Long roomId,Map<String,Object> data) {
|
public void hMSet(Long roomId,Map<String,Object> data) {
|
||||||
String key = getKey(roomId);
|
String key = getKey(roomId);
|
||||||
stringRedisTemplate.opsForHash().putAll(key,data);
|
// redisTemplate.opsForHash().putAll(key,data);
|
||||||
|
RMap<Object, Object> map = redissonClient.getMap(key);
|
||||||
|
map.putAll(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hMSet(Long roomId,String mKey,Object mData) {
|
public void hMSet(Long roomId,String mKey,Object mData) {
|
||||||
String key = getKey(roomId);
|
String key = getKey(roomId);
|
||||||
stringRedisTemplate.opsForHash().put(key,mKey,mData);
|
RMap<String, Object> map = redissonClient.getMap(key);
|
||||||
|
map.put(mKey,mData);
|
||||||
|
// redisTemplate.opsForHash().put(key,mKey,mData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private final static String HANG_UP = "local hangupTime = tonumber(redis.call('hGet', KEYS[1], 'hangupTime'))\n" +
|
private final static String HANG_UP = "local hangupTime = tonumber(redis.call('hGet', KEYS[1], '\"hangupTime\"'))\n" +
|
||||||
"if hangupTime > 0 then\n" +
|
"if hangupTime and hangupTime > 0 then\n" +
|
||||||
" return 0\n" +
|
" return 0\n" +
|
||||||
"end\n" +
|
"end\n" +
|
||||||
"return redis.call('hMSet', KEYS[1], 'status', 8, 'hangupTime', ARGV[1])";
|
"return redis.call('hMSet', KEYS[1], '\"status\"', 8, '\"hangupTime\"', ARGV[1])";
|
||||||
|
|
||||||
public boolean hangUp(Long roomId) {
|
public boolean hangUp(Long roomId) {
|
||||||
DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(HANG_UP,Boolean.class);
|
RScript script = redissonClient.getScript();
|
||||||
String currentTime = String.valueOf(System.currentTimeMillis() / 1000);
|
Long currentTime = System.currentTimeMillis() / 1000;
|
||||||
Boolean execute = stringRedisTemplate.execute(redisScript, Collections.singletonList(getKey(roomId)), currentTime);
|
Boolean execute = script.eval(RScript.Mode.READ_WRITE, HANG_UP, RScript.ReturnType.BOOLEAN,
|
||||||
|
Collections.singletonList(getKey(roomId)), currentTime);
|
||||||
|
// DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(HANG_UP,Boolean.class);
|
||||||
|
// Boolean execute = stringRedisTemplate.execute(redisScript, Collections.singletonList(getKey(roomId)), currentTime);
|
||||||
return BooleanUtils.isTrue(execute);
|
return BooleanUtils.isTrue(execute);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStatus(Long roomId, RoomStatusEnums status) {
|
public void setStatus(Long roomId, RoomStatusEnums status) {
|
||||||
String key = getKey(roomId);
|
String key = getKey(roomId);
|
||||||
stringRedisTemplate.opsForHash().put(key,"status",status.getCode());
|
// redisTemplate.opsForHash().put(key,"status",status.getCode());
|
||||||
|
RMap<String, Object> map = redissonClient.getMap(key);
|
||||||
|
map.put("status",status.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static String SET_STATUS_RECEIVER_CONNECTION = "local status = tonumber(redis.call('hget', KEYS[1], 'status'))\n" +
|
private final static String SET_STATUS_RECEIVER_CONNECTION = "local status = tonumber(redis.call('hget', KEYS[1], '\"status\"'))\n" +
|
||||||
"if status ~= 1 then\n" +
|
"if status ~= 1 then\n" +
|
||||||
" return 0\n" +
|
" return 0\n" +
|
||||||
"end\n" +
|
"end\n" +
|
||||||
"return redis.call('hmset', KEYS[1], 'status', 3)";
|
"return redis.call('hmset', KEYS[1], '\"status\"', 3)";
|
||||||
|
|
||||||
public boolean setStatusReceiverConnection(Long roomId) {
|
public boolean setStatusReceiverConnection(Long roomId) {
|
||||||
DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(SET_STATUS_RECEIVER_CONNECTION,Boolean.class);
|
RScript script = redissonClient.getScript();
|
||||||
Boolean execute = stringRedisTemplate.execute(redisScript, Collections.singletonList(getKey(roomId)));
|
Boolean execute = script.eval(RScript.Mode.READ_WRITE, SET_STATUS_RECEIVER_CONNECTION, RScript.ReturnType.BOOLEAN,
|
||||||
|
Collections.singletonList(getKey(roomId)));
|
||||||
|
// DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(SET_STATUS_RECEIVER_CONNECTION,Boolean.class);
|
||||||
|
// Boolean execute = stringRedisTemplate.execute(redisScript, Collections.singletonList(getKey(roomId)));
|
||||||
return BooleanUtils.isTrue(execute);
|
return BooleanUtils.isTrue(execute);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static String SET_STATUS_AGREE =
|
private final static String SET_STATUS_AGREE =
|
||||||
"local status = tonumber(redis.call('hget', KEYS[1], 'status'))\n" +
|
"local status = tonumber(redis.call('hget', KEYS[1], '\"status\"'))\n" +
|
||||||
"local beginTime = tonumber(redis.call('hget', KEYS[1], 'beginTime'))\n" +
|
"local beginTime = tonumber(redis.call('hget', KEYS[1], '\"beginTime\"'))\n" +
|
||||||
"if status ~= 3 or beginTime > 0 then\n" +
|
"if status ~= 3 or (beginTime and beginTime > 0) then\n" +
|
||||||
" return 0\n" +
|
" return 0\n" +
|
||||||
"end\n" +
|
"end\n" +
|
||||||
"return redis.call('hmset', KEYS[1], 'status', 7, 'beginTime', ARGV[1])";
|
"return redis.call('hmset', KEYS[1], '\"status\"', 7, '\"beginTime\"', ARGV[1])";
|
||||||
|
|
||||||
public boolean setStatusAgree(Long roomId) {
|
public boolean setStatusAgree(Long roomId) {
|
||||||
DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(SET_STATUS_AGREE,Boolean.class);
|
|
||||||
String currentTime = String.valueOf(System.currentTimeMillis() / 1000);
|
String currentTime = String.valueOf(System.currentTimeMillis() / 1000);
|
||||||
Boolean execute = stringRedisTemplate.execute(redisScript, Collections.singletonList(getKey(roomId)),currentTime);
|
RScript script = redissonClient.getScript();
|
||||||
|
Boolean execute = script.eval(RScript.Mode.READ_WRITE, SET_STATUS_AGREE, RScript.ReturnType.BOOLEAN,
|
||||||
|
Collections.singletonList(getKey(roomId)),currentTime);
|
||||||
|
// DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(SET_STATUS_AGREE,Boolean.class);
|
||||||
|
// Boolean execute = stringRedisTemplate.execute(redisScript, Collections.singletonList(getKey(roomId)),currentTime);
|
||||||
return BooleanUtils.isTrue(execute);
|
return BooleanUtils.isTrue(execute);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static String INCS_BLACK_AMOUNT =
|
private final static String INCS_BLACK_AMOUNT =
|
||||||
"redis.call('hIncrBy', KEYS[1], 'payCoin', ARGV[1])\n" +
|
"redis.call('hIncrBy', KEYS[1], '\"payCoin\"', ARGV[1])\n" +
|
||||||
"redis.call('hIncrBy', KEYS[1], 'payIncome', ARGV[2])";
|
"redis.call('hIncrBy', KEYS[1], '\"payIncome\"', ARGV[2])";
|
||||||
|
|
||||||
public boolean incsBlackAmount(Long roomId, Long decrCoin, Long decrIncomeCoin) {
|
public boolean incsBlackAmount(Long roomId, Long decrCoin, Long decrIncomeCoin) {
|
||||||
DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(INCS_BLACK_AMOUNT,Boolean.class);
|
RScript script = redissonClient.getScript();
|
||||||
Boolean execute = stringRedisTemplate.execute(redisScript, Collections.singletonList(getKey(roomId)),
|
Boolean execute = script.eval(RScript.Mode.READ_WRITE, INCS_BLACK_AMOUNT, RScript.ReturnType.BOOLEAN,
|
||||||
decrCoin,decrIncomeCoin);
|
Collections.singletonList(getKey(roomId)),decrCoin.intValue(),decrIncomeCoin.intValue());
|
||||||
|
// DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(INCS_BLACK_AMOUNT,Boolean.class);
|
||||||
|
// Boolean execute = stringRedisTemplate.execute(redisScript, Collections.singletonList(getKey(roomId)),
|
||||||
|
// decrCoin,decrIncomeCoin);
|
||||||
return BooleanUtils.isTrue(execute);
|
return BooleanUtils.isTrue(execute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,13 @@ import com.alibaba.fastjson2.JSON;
|
|||||||
import com.ruoyi.cai.ws.bean.UserData;
|
import com.ruoyi.cai.ws.bean.UserData;
|
||||||
import com.ruoyi.cai.ws.constant.RedisConstant;
|
import com.ruoyi.cai.ws.constant.RedisConstant;
|
||||||
import com.ruoyi.cai.ws.constant.UserDataConstant;
|
import com.ruoyi.cai.ws.constant.UserDataConstant;
|
||||||
|
import org.redisson.api.RMap;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,6 +22,8 @@ import java.util.Map;
|
|||||||
public class UserDataCache {
|
public class UserDataCache {
|
||||||
@Autowired
|
@Autowired
|
||||||
private StringRedisTemplate redisTemplate;
|
private StringRedisTemplate redisTemplate;
|
||||||
|
@Autowired
|
||||||
|
private RedissonClient redissonClient;
|
||||||
|
|
||||||
public String getKey(Long roomId,int type){
|
public String getKey(Long roomId,int type){
|
||||||
return String.format(RedisConstant.USER_ROOM_DATA,roomId,type== UserDataConstant.TYPE_CALLER?"caller":"receiver");
|
return String.format(RedisConstant.USER_ROOM_DATA,roomId,type== UserDataConstant.TYPE_CALLER?"caller":"receiver");
|
||||||
@@ -34,18 +39,23 @@ public class UserDataCache {
|
|||||||
|
|
||||||
public UserData getUserDataByRoom(Long roomId,int type){
|
public UserData getUserDataByRoom(Long roomId,int type){
|
||||||
String key = getKey(roomId, type);
|
String key = getKey(roomId, type);
|
||||||
Map<Object, Object> entries = redisTemplate.opsForHash().entries(key);
|
// Map<Object, Object> entries = redisTemplate.opsForHash().entries(key);
|
||||||
if(entries.get("roomId") == null){
|
RMap<Object, Object> entries = redissonClient.getMap(key);
|
||||||
|
Map<Object, Object> map = entries.readAllMap();
|
||||||
|
if(map.get("roomId") == null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return JSON.parseObject(JSON.toJSONString(entries),UserData.class);
|
return JSON.parseObject(JSON.toJSONString(map),UserData.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(UserData userData,int type){
|
public void init(UserData userData,int type){
|
||||||
String key = getKey(userData.getRoomId(), type);
|
String key = getKey(userData.getRoomId(), type);
|
||||||
userData.setUserType(type);
|
userData.setUserType(type);
|
||||||
Map<String,Object> map = JSON.parseObject(JSON.toJSONString(userData));
|
Map<String,Object> map = JSON.parseObject(JSON.toJSONString(userData));
|
||||||
redisTemplate.opsForHash().putAll(key,map);
|
// redisTemplate.opsForHash().putAll(key,map);
|
||||||
|
RMap<Object, Object> mapRedis = redissonClient.getMap(key);
|
||||||
|
mapRedis.putAll(map);
|
||||||
|
mapRedis.expire(Duration.ofDays(15));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initCaller(UserData callerUserData) {
|
public void initCaller(UserData callerUserData) {
|
||||||
@@ -58,6 +68,7 @@ public class UserDataCache {
|
|||||||
|
|
||||||
public void hMSet(Long roomId,Integer userType,Map<String,Object> data) {
|
public void hMSet(Long roomId,Integer userType,Map<String,Object> data) {
|
||||||
String key = getKey(roomId, userType);
|
String key = getKey(roomId, userType);
|
||||||
redisTemplate.opsForHash().putAll(key,data);
|
// redisTemplate.opsForHash().putAll(key,data);
|
||||||
|
redissonClient.getMap(key).putAll(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ public class WsRMsgGen {
|
|||||||
|
|
||||||
public static WsR hangup(String message, Long roomId, Integer hangUpType) {
|
public static WsR hangup(String message, Long roomId, Integer hangUpType) {
|
||||||
Map<String,Object> map = new HashMap<>();
|
Map<String,Object> map = new HashMap<>();
|
||||||
map.put("roomid","roomId");
|
map.put("roomid",roomId);
|
||||||
map.put("type","hangUpType");
|
map.put("type",hangUpType);
|
||||||
WsR<Map<String, Object>> ok = WsR.ok(map);
|
WsR<Map<String, Object>> ok = WsR.ok(map);
|
||||||
ok.setMethod("hangup");
|
ok.setMethod("hangup");
|
||||||
ok.setMsg(message);
|
ok.setMsg(message);
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import com.ruoyi.cai.ws.constant.HangUpEnums;
|
|||||||
import com.ruoyi.cai.ws.dto.WsToken;
|
import com.ruoyi.cai.ws.dto.WsToken;
|
||||||
import com.ruoyi.cai.ws.service.CheckConnectionDTO;
|
import com.ruoyi.cai.ws.service.CheckConnectionDTO;
|
||||||
import com.ruoyi.cai.ws.service.RoomService;
|
import com.ruoyi.cai.ws.service.RoomService;
|
||||||
import com.ruoyi.cai.ws.util.MapGetUtil;
|
|
||||||
import com.ruoyi.cai.ws.util.WsExceptionUtil;
|
import com.ruoyi.cai.ws.util.WsExceptionUtil;
|
||||||
|
import jodd.util.StringUtil;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.socket.TextMessage;
|
import org.springframework.web.socket.TextMessage;
|
||||||
@@ -36,6 +36,9 @@ public class MessageHandleApplication {
|
|||||||
|
|
||||||
public void processOn(WebSocketSession session, TextMessage message) {
|
public void processOn(WebSocketSession session, TextMessage message) {
|
||||||
String payload = message.getPayload();
|
String payload = message.getPayload();
|
||||||
|
if(StringUtil.isEmpty(payload)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
JSONObject jsonObject = JSON.parseObject(payload);
|
JSONObject jsonObject = JSON.parseObject(payload);
|
||||||
Object method = jsonObject.get("method");
|
Object method = jsonObject.get("method");
|
||||||
if(method == null){
|
if(method == null){
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
package com.ruoyi.cai.ws.handler;
|
package com.ruoyi.cai.ws.handler;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.URLUtil;
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
import com.ruoyi.cai.chat.ChatManager;
|
import com.ruoyi.cai.chat.ChatManager;
|
||||||
|
import com.ruoyi.cai.ws.cache.FdCtxDataCache;
|
||||||
import com.ruoyi.cai.ws.constant.WebSocketConstants;
|
import com.ruoyi.cai.ws.constant.WebSocketConstants;
|
||||||
import com.ruoyi.cai.ws.holder.WebSocketSessionHolder;
|
import com.ruoyi.cai.ws.holder.WebSocketSessionHolder;
|
||||||
import com.ruoyi.cai.ws.processon.OpenLogic;
|
import com.ruoyi.cai.ws.processon.OpenLogic;
|
||||||
|
import com.ruoyi.cai.ws.service.RoomService;
|
||||||
import com.ruoyi.cai.ws.util.WebSocketUtils;
|
import com.ruoyi.cai.ws.util.WebSocketUtils;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.http.client.utils.URIUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -14,6 +20,9 @@ import org.springframework.web.socket.handler.AbstractWebSocketHandler;
|
|||||||
|
|
||||||
import javax.websocket.server.PathParam;
|
import javax.websocket.server.PathParam;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,10 +43,27 @@ public class RoomWebSocketHandler extends AbstractWebSocketHandler {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void afterConnectionEstablished(WebSocketSession session) {
|
public void afterConnectionEstablished(WebSocketSession session) {
|
||||||
|
URI uri = session.getUri();
|
||||||
|
Map<String, String> para = getPara(uri == null ? null : uri.getQuery());
|
||||||
|
Map<String, Object> attributes = session.getAttributes();
|
||||||
|
attributes.putAll(para);
|
||||||
openLogic.processOn(session);
|
openLogic.processOn(session);
|
||||||
log.info("[connect] sessionId: {},userId:{}", session.getId(), session.getId());
|
log.info("[connect] sessionId: {},userId:{}", session.getId(), session.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String,String> getPara(String uri) {
|
||||||
|
Map<String,String> map = new HashMap<>();
|
||||||
|
if(StringUtils.isEmpty(uri)){
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
String[] keys = uri.split("&");
|
||||||
|
for (String key : keys) {
|
||||||
|
String[] split = key.split("=");
|
||||||
|
map.put(split[0],split.length > 1 ? split[1] : "");
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理发送来的文本消息
|
* 处理发送来的文本消息
|
||||||
*
|
*
|
||||||
@@ -47,7 +73,11 @@ public class RoomWebSocketHandler extends AbstractWebSocketHandler {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
|
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
|
||||||
messageHandleApplication.processOn(session,message);
|
try {
|
||||||
|
messageHandleApplication.processOn(session,message);
|
||||||
|
}catch (Exception e){
|
||||||
|
log.error("ws消息处理失败!需要开发检查问题!",e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -79,6 +109,10 @@ public class RoomWebSocketHandler extends AbstractWebSocketHandler {
|
|||||||
log.error("[transport error] sessionId: {} , exception:{}", session.getId(), exception.getMessage());
|
log.error("[transport error] sessionId: {} , exception:{}", session.getId(), exception.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RoomService roomService;
|
||||||
|
@Autowired
|
||||||
|
private FdCtxDataCache fdCtxDataCache;
|
||||||
/**
|
/**
|
||||||
* 连接关闭后
|
* 连接关闭后
|
||||||
*
|
*
|
||||||
@@ -88,6 +122,7 @@ public class RoomWebSocketHandler extends AbstractWebSocketHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
|
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
|
||||||
String token = String.valueOf(session.getAttributes().get("token"));
|
String token = String.valueOf(session.getAttributes().get("token"));
|
||||||
|
// TODO 连接关闭 是否要删除fd的关系
|
||||||
WebSocketSessionHolder.removeSession(token);
|
WebSocketSessionHolder.removeSession(token);
|
||||||
log.info("[disconnect] sessionId: {},token:{}", session.getId(), token);
|
log.info("[disconnect] sessionId: {},token:{}", session.getId(), token);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class HangupMessageHandler extends AbstractMessageHandle implements IMess
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 触发结算
|
// 触发结算
|
||||||
settleService.processOn(room);
|
settleService.processOn(room.getRoomId());
|
||||||
Integer type = fdCtxData.isCaller() ? HangUpEnums.FROM.getCode() : HangUpEnums.TO.getCode();
|
Integer type = fdCtxData.isCaller() ? HangUpEnums.FROM.getCode() : HangUpEnums.TO.getCode();
|
||||||
sendToCurrent(fdCtxData,WsRMsgGen.hangup("您已挂断",room.getRoomId(), type));
|
sendToCurrent(fdCtxData,WsRMsgGen.hangup("您已挂断",room.getRoomId(), type));
|
||||||
sendToTar(fdCtxData,WsRMsgGen.hangup("对方已挂断",room.getRoomId(), type));
|
sendToTar(fdCtxData,WsRMsgGen.hangup("对方已挂断",room.getRoomId(), type));
|
||||||
|
|||||||
@@ -9,18 +9,18 @@ import com.ruoyi.cai.trd.ImMsgGen;
|
|||||||
import com.ruoyi.cai.ws.bean.Room;
|
import com.ruoyi.cai.ws.bean.Room;
|
||||||
import com.ruoyi.cai.ws.bean.UserData;
|
import com.ruoyi.cai.ws.bean.UserData;
|
||||||
import com.ruoyi.cai.ws.cache.OnlineDataCache;
|
import com.ruoyi.cai.ws.cache.OnlineDataCache;
|
||||||
import com.ruoyi.cai.ws.cache.RoomCtxCache;
|
|
||||||
import com.ruoyi.cai.ws.constant.RoomStatusEnums;
|
import com.ruoyi.cai.ws.constant.RoomStatusEnums;
|
||||||
import com.ruoyi.cai.ws.service.RoomService;
|
import com.ruoyi.cai.ws.service.RoomService;
|
||||||
|
import com.ruoyi.cai.ws.service.SettleService;
|
||||||
import com.ruoyi.yunxin.Yunxin;
|
import com.ruoyi.yunxin.Yunxin;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@Slf4j
|
||||||
public class CheckTimeOutJob {
|
public class CheckTimeOutJob {
|
||||||
@Autowired
|
@Autowired
|
||||||
private OnlineDataCache onlineDataCache;
|
private OnlineDataCache onlineDataCache;
|
||||||
@@ -29,13 +29,14 @@ public class CheckTimeOutJob {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private UserCallService userCallService;
|
private UserCallService userCallService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private RoomCtxCache roomCtxCache;
|
private SettleService settleService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private Yunxin yunxin;
|
private Yunxin yunxin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1 分钟执行一次
|
* 检查房间是不是三分钟没有接听, 需要自动挂断掉
|
||||||
*/
|
*/
|
||||||
@Scheduled(fixedDelay = 60,timeUnit = TimeUnit.SECONDS)
|
// @Scheduled(fixedDelay = 60,timeUnit = TimeUnit.SECONDS)
|
||||||
public void run(){
|
public void run(){
|
||||||
Set<String> roomIdStr = onlineDataCache.getAll();
|
Set<String> roomIdStr = onlineDataCache.getAll();
|
||||||
for (String roomIdS : roomIdStr) {
|
for (String roomIdS : roomIdStr) {
|
||||||
@@ -45,7 +46,11 @@ public class CheckTimeOutJob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void deal(Long roomId){
|
public void deal(Long roomId){
|
||||||
|
log.info("开始执行房间超时检测,是否一直不接 roomId={}",roomId);
|
||||||
Room room = roomService.load(roomId);
|
Room room = roomService.load(roomId);
|
||||||
|
if(room == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(!RoomStatusEnums.STATUS_CALLER_CONNECT.getCode().equals(room.getStatus())
|
if(!RoomStatusEnums.STATUS_CALLER_CONNECT.getCode().equals(room.getStatus())
|
||||||
&& !RoomStatusEnums.STATUS_RECEIVER_CONNECT.getCode().equals(room.getStatus())){
|
&& !RoomStatusEnums.STATUS_RECEIVER_CONNECT.getCode().equals(room.getStatus())){
|
||||||
return;
|
return;
|
||||||
@@ -66,6 +71,7 @@ public class CheckTimeOutJob {
|
|||||||
userCallService.update(Wrappers.lambdaUpdate(UserCall.class)
|
userCallService.update(Wrappers.lambdaUpdate(UserCall.class)
|
||||||
.eq(UserCall::getId,roomId)
|
.eq(UserCall::getId,roomId)
|
||||||
.set(UserCall::getStatus, RoomStatusEnums.STATUS_TIMEOUT_CANCEL.getCode()));
|
.set(UserCall::getStatus, RoomStatusEnums.STATUS_TIMEOUT_CANCEL.getCode()));
|
||||||
|
// TODO 需要放开主播的接听状态
|
||||||
roomService.closeAllFd(roomId);
|
roomService.closeAllFd(roomId);
|
||||||
ImDataRes imDataRes = ImMsgGen.callNotice(3, callUserData.getId(), receiverUserData.getId(), 0);
|
ImDataRes imDataRes = ImMsgGen.callNotice(3, callUserData.getId(), receiverUserData.getId(), 0);
|
||||||
yunxin.sendToSync(receiverUserData.getId(),callUserData.getId(),imDataRes);
|
yunxin.sendToSync(receiverUserData.getId(),callUserData.getId(),imDataRes);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class HeartbeatJob {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 30秒执行一次
|
* 30秒执行一次 心跳只处理接听后的心跳
|
||||||
*/
|
*/
|
||||||
@Scheduled(fixedDelay = 30,timeUnit = TimeUnit.SECONDS)
|
@Scheduled(fixedDelay = 30,timeUnit = TimeUnit.SECONDS)
|
||||||
public void run(){
|
public void run(){
|
||||||
@@ -50,6 +50,9 @@ public class HeartbeatJob {
|
|||||||
try {
|
try {
|
||||||
Long roomId = Long.valueOf(roomIdS);
|
Long roomId = Long.valueOf(roomIdS);
|
||||||
Room room = roomService.load(roomId);
|
Room room = roomService.load(roomId);
|
||||||
|
if(room == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(!room.isCanCall()){
|
if(!room.isCanCall()){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -69,7 +72,7 @@ public class HeartbeatJob {
|
|||||||
userCallService.update(Wrappers.lambdaUpdate(UserCall.class)
|
userCallService.update(Wrappers.lambdaUpdate(UserCall.class)
|
||||||
.eq(UserCall::getId,roomId)
|
.eq(UserCall::getId,roomId)
|
||||||
.set(UserCall::getStatus, RoomStatusEnums.STATUS_TIMEOUT_CANCEL.getCode()));
|
.set(UserCall::getStatus, RoomStatusEnums.STATUS_TIMEOUT_CANCEL.getCode()));
|
||||||
settleService.processOn(room);
|
settleService.processOn(roomId);
|
||||||
}
|
}
|
||||||
List<String> keys = roomCtxCache.getSessionKeysByRoomId(roomId);
|
List<String> keys = roomCtxCache.getSessionKeysByRoomId(roomId);
|
||||||
RoomWebSocketUtil.sendSendMessage(keys, hangup);
|
RoomWebSocketUtil.sendSendMessage(keys, hangup);
|
||||||
|
|||||||
@@ -25,17 +25,13 @@ public class SettleJob {
|
|||||||
/**
|
/**
|
||||||
* 每 1 分钟执行一次
|
* 每 1 分钟执行一次
|
||||||
*/
|
*/
|
||||||
@Scheduled(fixedDelay = 60,timeUnit = TimeUnit.SECONDS)
|
// @Scheduled(fixedDelay = 60,timeUnit = TimeUnit.SECONDS)
|
||||||
public void run(){
|
public void run(){
|
||||||
Set<String> all = onlineDataCache.getAll();
|
Set<String> all = onlineDataCache.getAll();
|
||||||
for (String roomIdS : all) {
|
for (String roomIdS : all) {
|
||||||
try {
|
try {
|
||||||
Long roomId = Long.valueOf(roomIdS);
|
Long roomId = Long.valueOf(roomIdS);
|
||||||
Room room = roomService.load(roomId);
|
settleService.processOn(roomId);
|
||||||
if(room == null){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
settleService.processOn(room);
|
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
log.info("定时任务结算失败!",e);
|
log.info("定时任务结算失败!",e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class WebSocketManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Room room = roomService.load(roomId);
|
Room room = roomService.load(roomId);
|
||||||
if(room == null){
|
if(room == null || !room.isCanCall()){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return room;
|
return room;
|
||||||
@@ -104,7 +104,6 @@ public class WebSocketManager {
|
|||||||
RoomData roomData = new RoomData();
|
RoomData roomData = new RoomData();
|
||||||
roomData.setRoomId(call.getId());
|
roomData.setRoomId(call.getId());
|
||||||
roomData.setCallPrice(call.getCallPrice());
|
roomData.setCallPrice(call.getCallPrice());
|
||||||
roomData.setSkillName(call.getSkillName());
|
|
||||||
roomData.setStatus(call.getStatus());
|
roomData.setStatus(call.getStatus());
|
||||||
roomData.setVideoDivide(call.getReceiverVideoDivide());
|
roomData.setVideoDivide(call.getReceiverVideoDivide());
|
||||||
roomDataCache.init(roomData);
|
roomDataCache.init(roomData);
|
||||||
@@ -119,7 +118,7 @@ public class WebSocketManager {
|
|||||||
receiveUserData.setRoomId(call.getId());
|
receiveUserData.setRoomId(call.getId());
|
||||||
receiveUserData.setNickname(receiverUser.getNickname());
|
receiveUserData.setNickname(receiverUser.getNickname());
|
||||||
receiveUserData.setUserCode(receiverUser.getUsercode());
|
receiveUserData.setUserCode(receiverUser.getUsercode());
|
||||||
userDataCache.initReceiver(callerUserData);
|
userDataCache.initReceiver(receiveUserData);
|
||||||
callerRoomCache.addRoom(call.getFromUid(),call.getToUid(),call.getId());
|
callerRoomCache.addRoom(call.getFromUid(),call.getToUid(),call.getId());
|
||||||
return call.getId();
|
return call.getId();
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class OpenLogic {
|
|||||||
Long roomId = wsToken.getRoomId();
|
Long roomId = wsToken.getRoomId();
|
||||||
Long userId = wsToken.getUserId();
|
Long userId = wsToken.getUserId();
|
||||||
Room room = roomService.load(roomId);
|
Room room = roomService.load(roomId);
|
||||||
if(room == null || (room.getCallUserData().getId().equals(userId) && room.getReceiverUserData().getId().equals(userId))){
|
if(room == null || (!room.getCallUserData().getId().equals(userId) && !room.getReceiverUserData().getId().equals(userId))){
|
||||||
WsExceptionUtil.throwException(session,"房间不可用", HangUpEnums.OTHER,roomId);
|
WsExceptionUtil.throwException(session,"房间不可用", HangUpEnums.OTHER,roomId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,8 +138,8 @@ public class RoomService {
|
|||||||
if(beginTime == null){
|
if(beginTime == null){
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
if(roomData.getHangUpTime() != null){
|
if(roomData.getHangupTime() != null){
|
||||||
return roomData.getHangUpTime() - roomData.getBeginTime();
|
return roomData.getHangupTime() - roomData.getBeginTime();
|
||||||
}
|
}
|
||||||
return DateUtil.currentSeconds() - beginTime;
|
return DateUtil.currentSeconds() - beginTime;
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ public class RoomService {
|
|||||||
Long receiverId = receiverUserData.getId();
|
Long receiverId = receiverUserData.getId();
|
||||||
Long callerId = room.getCallUserData().getId();
|
Long callerId = room.getCallUserData().getId();
|
||||||
// 呼叫方释放资源
|
// 呼叫方释放资源
|
||||||
callerRoomCache.delRoom(receiverId,roomId);
|
callerRoomCache.delRoom(callerId,receiverId,roomId);
|
||||||
userService.updateVideoStatus(callerId,0);
|
userService.updateVideoStatus(callerId,0);
|
||||||
// 接收方释放资源(已连接的情况下)
|
// 接收方释放资源(已连接的情况下)
|
||||||
if(receiverUserData.getConnectTime() != null && receiverUserData.getConnectTime() > 0){
|
if(receiverUserData.getConnectTime() != null && receiverUserData.getConnectTime() > 0){
|
||||||
@@ -195,11 +195,25 @@ public class RoomService {
|
|||||||
}
|
}
|
||||||
// 修改释放状态
|
// 修改释放状态
|
||||||
Map<String,Object> map = new HashMap<>();
|
Map<String,Object> map = new HashMap<>();
|
||||||
map.put("releaseRes",1);
|
map.put("releaseRes",true);
|
||||||
roomDataCache.hMSet(roomId,map);
|
roomDataCache.hMSet(roomId,map);
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
log.error("释放房间资源失败!房间号:{}",roomId,e);
|
log.error("释放房间资源失败!房间号:{}",roomId,e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否正在通话中
|
||||||
|
*/
|
||||||
|
public boolean checkRunningVideo(Long toUserId, Long fromUserId) {
|
||||||
|
Long roomId = callerRoomCache.getRoomId(toUserId, fromUserId);
|
||||||
|
if(roomId != null){
|
||||||
|
Room room = load(roomId);
|
||||||
|
if(room != null && room.isCanCall()){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class SettleService {
|
|||||||
boolean b = roomService.hangUp(room.getRoomId());
|
boolean b = roomService.hangUp(room.getRoomId());
|
||||||
if(b){
|
if(b){
|
||||||
// 结算操作
|
// 结算操作
|
||||||
settleService.processOn(room);
|
settleService.processOn(room.getRoomId());
|
||||||
}
|
}
|
||||||
// 向客户端发送挂断指令
|
// 向客户端发送挂断指令
|
||||||
WsR r = WsRMsgGen.hangup("拨打方余额不足", room.getRoomId(), HangUpEnums.NOTMONEY.getCode());
|
WsR r = WsRMsgGen.hangup("拨打方余额不足", room.getRoomId(), HangUpEnums.NOTMONEY.getCode());
|
||||||
@@ -99,10 +99,14 @@ public class SettleService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 结算处理
|
* 结算处理
|
||||||
* @param room
|
|
||||||
*/
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void processOn(Room room){
|
public void processOn(Long roomId){
|
||||||
|
Room room = roomService.load(roomId);
|
||||||
|
if(room == null){
|
||||||
|
log.warn("房间不存在,无需结算 roomId={}",roomId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
String lock = LockManager.getVideoSettleLock(room.getRoomId());
|
String lock = LockManager.getVideoSettleLock(room.getRoomId());
|
||||||
RLock clientLock = redissonClient.getLock(lock);
|
RLock clientLock = redissonClient.getLock(lock);
|
||||||
boolean locked = clientLock.isLocked();
|
boolean locked = clientLock.isLocked();
|
||||||
@@ -110,7 +114,7 @@ public class SettleService {
|
|||||||
log.info("正在结算中,稍等!");
|
log.info("正在结算中,稍等!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean lockFlag = clientLock.tryLock(5, TimeUnit.SECONDS);
|
boolean lockFlag = clientLock.tryLock();
|
||||||
if(!lockFlag){
|
if(!lockFlag){
|
||||||
log.info("正在结算中,稍等!");
|
log.info("正在结算中,稍等!");
|
||||||
return;
|
return;
|
||||||
@@ -133,7 +137,6 @@ public class SettleService {
|
|||||||
}
|
}
|
||||||
if(!room.isReleaseRes()){ // 房间资源是否已经释放
|
if(!room.isReleaseRes()){ // 房间资源是否已经释放
|
||||||
roomService.releaseRes(room.getRoomId());
|
roomService.releaseRes(room.getRoomId());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
Long roomId = room.getRoomId();
|
Long roomId = room.getRoomId();
|
||||||
// 未通话,无需结算
|
// 未通话,无需结算
|
||||||
|
|||||||
Reference in New Issue
Block a user