后台保活和注册

This commit is contained in:
ZuoZuo 2026-05-02 02:23:48 +08:00
parent 17e4cd69bb
commit c7a650ce7f
7 changed files with 113 additions and 87 deletions

View File

@ -1,12 +1,12 @@
package com.red.circle.other.inner.model.cmd.user.account; package com.red.circle.other.inner.model.cmd.user.account;
import com.red.circle.common.business.dto.cmd.AppExtCommand; import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.framework.core.asserts.ResponseAssert; import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.ResponseErrorCode; import com.red.circle.framework.core.response.ResponseErrorCode;
import com.red.circle.tool.core.text.StringUtils; import com.red.circle.other.inner.enums.user.AuthTypeEnum;
import com.red.circle.other.inner.model.cmd.user.UserProfileCmd; import com.red.circle.other.inner.model.cmd.user.UserProfileCmd;
import jakarta.validation.constraints.NotBlank; import com.red.circle.tool.core.text.StringUtils;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.util.Objects; import java.util.Objects;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -30,11 +30,10 @@ public class CreateAccountCmd extends AppExtCommand {
*/ */
private String invitationCode; private String invitationCode;
/** /**
* 注册类型:MOBILEFACEBOOKGOOGLEAPPLESnapchat. * 注册类型:MOBILEFACEBOOKGOOGLEAPPLESnapchat.
*/ */
@NotBlank(message = "type required.") private String type = AuthTypeEnum.GOOGLE.name();
private String type;
/** /**
* 开放id. * 开放id.
@ -70,13 +69,21 @@ public class CreateAccountCmd extends AppExtCommand {
return profile.getUserNickname(); return profile.getUserNickname();
} }
public String profileAvatar() { public String profileAvatar() {
return profile.getUserAvatar(); return profile.getUserAvatar();
} }
public boolean checkTypeMobile() { public String getType() {
return Objects.equals(type, "MOBILE"); return StringUtils.isBlank(type) ? AuthTypeEnum.GOOGLE.name() : type;
} }
public void setType(String type) {
this.type = StringUtils.isBlank(type) ? AuthTypeEnum.GOOGLE.name() : type;
}
public boolean checkTypeMobile() {
return Objects.equals(getType(), AuthTypeEnum.MOBILE.name());
}
public boolean checkChina() { public boolean checkChina() {
if (Objects.equals(invitePeople, "CY1101")) { if (Objects.equals(invitePeople, "CY1101")) {

View File

@ -3,11 +3,16 @@ package com.red.circle.live.domain.constant;
/** /**
* @author pengliang on 2023/12/12 * @author pengliang on 2023/12/12
*/ */
public interface ActiveSecondConstant { public interface ActiveSecondConstant {
/** /**
* 心跳60s一次 预留30s异常等待. * 房间在线用户保活时间.
*/ */
int EXPIRATION_SECOND = 120; int ROOM_USER_EXPIRATION_SECOND = 5 * 60;
} /**
* 麦位活跃保活时间.
*/
int MIC_EXPIRATION_SECOND = 120;
}

View File

@ -49,9 +49,9 @@ public class LiveMicrophone implements Serializable {
/** /**
* 是否活跃. * 是否活跃.
*/ */
public boolean checkInactiveExpire() { public boolean checkInactiveExpire() {
long intervalTime = (System.currentTimeMillis() - this.refreshTime) / 1000; long intervalTime = (System.currentTimeMillis() - this.refreshTime) / 1000;
return intervalTime >= ActiveSecondConstant.EXPIRATION_SECOND; return intervalTime >= ActiveSecondConstant.MIC_EXPIRATION_SECOND;
} }
} }

View File

@ -48,9 +48,9 @@ public class LiveRoomUser implements Serializable {
/** /**
* 是否活跃. * 是否活跃.
*/ */
public boolean checkInactiveExpire() { public boolean checkInactiveExpire() {
long intervalTime = (System.currentTimeMillis() - this.refreshTime) / 1000; long intervalTime = (System.currentTimeMillis() - this.refreshTime) / 1000;
return intervalTime > ActiveSecondConstant.EXPIRATION_SECOND; return intervalTime > ActiveSecondConstant.ROOM_USER_EXPIRATION_SECOND;
} }
} }

View File

@ -1,8 +1,9 @@
package com.red.circle.live.infra.database.cache.service.impl; package com.red.circle.live.infra.database.cache.service.impl;
import com.red.circle.component.redis.service.RedisService; import com.red.circle.component.redis.service.RedisService;
import com.red.circle.live.domain.online.LiveRoomUser; import com.red.circle.live.domain.constant.ActiveSecondConstant;
import com.red.circle.live.domain.online.LiveRoomUserRefresh; import com.red.circle.live.domain.online.LiveRoomUser;
import com.red.circle.live.domain.online.LiveRoomUserRefresh;
import com.red.circle.live.infra.database.cache.key.LiveMicUserKey; import com.red.circle.live.infra.database.cache.key.LiveMicUserKey;
import com.red.circle.live.infra.database.cache.service.LiveMicUserCacheService; import com.red.circle.live.infra.database.cache.service.LiveMicUserCacheService;
import com.red.circle.tool.core.collection.CollectionUtils; import com.red.circle.tool.core.collection.CollectionUtils;
@ -47,8 +48,8 @@ public class LiveMicUserCacheServiceImpl implements LiveMicUserCacheService {
if (Objects.nonNull(user)) { if (Objects.nonNull(user)) {
redisService.hashPut(LiveMicUserKey.ROOM.getKey(roomId), Objects.toString(user.getUserId()), redisService.hashPut(LiveMicUserKey.ROOM.getKey(roomId), Objects.toString(user.getUserId()),
user); user);
//放入redis key IN_ROOM:userId v 是roomId 放1分钟30秒每次来了都刷新过期时间 redisService.setString("IN_ROOM:" + user.getUserId(), roomId,
redisService.setString("IN_ROOM:" + user.getUserId(), roomId, 90, TimeUnit.SECONDS); ActiveSecondConstant.ROOM_USER_EXPIRATION_SECOND, TimeUnit.SECONDS);
} }
return new LiveRoomUserRefresh() return new LiveRoomUserRefresh()
@ -95,7 +96,8 @@ public class LiveMicUserCacheServiceImpl implements LiveMicUserCacheService {
} }
private void setExpire(Long roomId) { private void setExpire(Long roomId) {
redisService.expire(LiveMicUserKey.ROOM.getKey(roomId), 90, TimeUnit.SECONDS); redisService.expire(LiveMicUserKey.ROOM.getKey(roomId),
} ActiveSecondConstant.ROOM_USER_EXPIRATION_SECOND, TimeUnit.SECONDS);
}
}
}

View File

@ -40,9 +40,11 @@ import org.apache.commons.lang3.StringUtils;
@Slf4j @Slf4j
@RocketMqMessageListener(groupId = OnlineStatusUploadSink.INPUT, tag = OnlineStatusUploadSink.TAG) @RocketMqMessageListener(groupId = OnlineStatusUploadSink.INPUT, tag = OnlineStatusUploadSink.TAG)
@RequiredArgsConstructor @RequiredArgsConstructor
public class OnlineStatusUploadListener implements MessageListener { public class OnlineStatusUploadListener implements MessageListener {
private final ExpandService expandService; private static final int ONLINE_EXPIRE_SECONDS = 5 * 60;
private final ExpandService expandService;
private final UserSVipGateway userSVipGateway; private final UserSVipGateway userSVipGateway;
private final WalletGoldClient walletGoldClient; private final WalletGoldClient walletGoldClient;
private final UserRegionGateway userRegionGateway; private final UserRegionGateway userRegionGateway;
@ -134,14 +136,14 @@ public class OnlineStatusUploadListener implements MessageListener {
.setRegionCode(Optional.ofNullable( .setRegionCode(Optional.ofNullable(
userRegionGateway.getUserRegion(userProfile.getId()) userRegionGateway.getUserRegion(userProfile.getId())
).map(UserRegionDTO::getRegionCode).orElse("OTHER")) ).map(UserRegionDTO::getRegionCode).orElse("OTHER"))
.setStatus(StringUtils.isNotBlank(event.getStatus()) .setStatus(StringUtils.isNotBlank(event.getStatus())
? UserOnlineStatusEnum.valueOf(event.getStatus()) ? UserOnlineStatusEnum.valueOf(event.getStatus())
: UserOnlineStatusEnum.IDLE) : UserOnlineStatusEnum.IDLE)
.setWeights(onlineStatusCommon.getWeights(userProfile.getId())) .setWeights(onlineStatusCommon.getWeights(userProfile.getId()))
.setExpiredTime(TimestampUtils.nowPlusSeconds(90)) .setExpiredTime(TimestampUtils.nowPlusSeconds(ONLINE_EXPIRE_SECONDS))
.setCreateTime(TimestampUtils.now()) .setCreateTime(TimestampUtils.now())
.setSessionId(DataTypeUtils.toLong(event.getSessionId())) .setSessionId(DataTypeUtils.toLong(event.getSessionId()))
.setSvipLevel(userSVipGateway.checkSVipIdentity(userProfile.getId()))); .setSvipLevel(userSVipGateway.checkSVipIdentity(userProfile.getId())));
} }
} }

View File

@ -39,18 +39,23 @@ public class OnlineUserServiceImpl implements OnlineUserService {
private final MongoTemplate mongoTemplate; private final MongoTemplate mongoTemplate;
@Override @Override
public boolean exists(Long sessionId, Long userId) { public boolean exists(Long sessionId, Long userId) {
return mongoTemplate.exists(Query.query(Criteria.where("sessionId").is(sessionId) return mongoTemplate.exists(Query.query(Criteria.where("sessionId").is(sessionId)
.and("id").is(userId)), OnlineUser.class); .and("id").is(userId)
} .and("status").is(UserOnlineStatusEnum.LANGUAGE_HALL)
.and("expiredTime").gte(TimestampUtils.now())), OnlineUser.class);
@Override }
public String getSessionId(Long userId) {
Criteria criteria = Criteria.where("id").is(userId); @Override
return Optional.ofNullable(mongoTemplate.findOne(Query.query(criteria), OnlineUser.class)) public String getSessionId(Long userId) {
.map(OnlineUser::getSessionId) Criteria criteria = Criteria.where("id").is(userId)
.map(Objects::toString) .and("status").is(UserOnlineStatusEnum.LANGUAGE_HALL)
.and("sessionId").gt(0)
.and("expiredTime").gte(TimestampUtils.now());
return Optional.ofNullable(mongoTemplate.findOne(Query.query(criteria), OnlineUser.class))
.map(OnlineUser::getSessionId)
.map(Objects::toString)
.orElse(null); .orElse(null);
} }
@ -202,10 +207,11 @@ public class OnlineUserServiceImpl implements OnlineUserService {
// } // }
@Override @Override
public List<OnlineUser> flowSessionOnlineUser(String sessionId, UserOnlineStatusEnum status, public List<OnlineUser> flowSessionOnlineUser(String sessionId, UserOnlineStatusEnum status,
Long lastTimingId) { Long lastTimingId) {
Criteria criteria = Criteria.where("sessionId").is(Long.parseLong(sessionId)) Criteria criteria = Criteria.where("sessionId").is(Long.parseLong(sessionId))
.and("status").is(status); .and("status").is(status)
.and("expiredTime").gte(TimestampUtils.now());
if (Objects.nonNull(lastTimingId)) { if (Objects.nonNull(lastTimingId)) {
criteria.and("timingId").gt(lastTimingId); criteria.and("timingId").gt(lastTimingId);
@ -227,10 +233,12 @@ public class OnlineUserServiceImpl implements OnlineUserService {
} }
@Override @Override
public Long countSessionId(Long sessionId) { public Long countSessionId(Long sessionId) {
return mongoTemplate.count(Query.query(Criteria.where("sessionId").is(sessionId)), return mongoTemplate.count(Query.query(Criteria.where("sessionId").is(sessionId)
OnlineUser.class); .and("status").is(UserOnlineStatusEnum.LANGUAGE_HALL)
} .and("expiredTime").gte(TimestampUtils.now())),
OnlineUser.class);
}
@Override @Override
public void removeByUserId(Long userId) { public void removeByUserId(Long userId) {
@ -272,9 +280,10 @@ public class OnlineUserServiceImpl implements OnlineUserService {
} }
@Override @Override
public List<OnlineUser> flowLanguageHallTop200(Long roomId, Long lastTimingId) { public List<OnlineUser> flowLanguageHallTop200(Long roomId, Long lastTimingId) {
Criteria criteria = Criteria.where("sessionId").is(roomId) Criteria criteria = Criteria.where("sessionId").is(roomId)
.and("status").is(UserOnlineStatusEnum.LANGUAGE_HALL); .and("status").is(UserOnlineStatusEnum.LANGUAGE_HALL)
.and("expiredTime").gte(TimestampUtils.now());
if (Objects.nonNull(lastTimingId)) { if (Objects.nonNull(lastTimingId)) {
criteria.and("timingId").gt(lastTimingId); criteria.and("timingId").gt(lastTimingId);
@ -347,11 +356,12 @@ public class OnlineUserServiceImpl implements OnlineUserService {
} }
@Override @Override
public List<OnlineUser> flowLanguageHallByRoomId(Long roomId) { public List<OnlineUser> flowLanguageHallByRoomId(Long roomId) {
Criteria criteria = Criteria.where("sessionId").is(roomId) Criteria criteria = Criteria.where("sessionId").is(roomId)
.and("status").is(UserOnlineStatusEnum.LANGUAGE_HALL); .and("status").is(UserOnlineStatusEnum.LANGUAGE_HALL)
return mongoTemplate.find(Query.query(criteria) .and("expiredTime").gte(TimestampUtils.now());
.with(Sort.by(Sort.Order.asc("timingId"))) return mongoTemplate.find(Query.query(criteria)
.with(Sort.by(Sort.Order.asc("timingId")))
.limit(5), OnlineUser.class); .limit(5), OnlineUser.class);
} }