diff --git a/commom/src/main/java/com/bx/common/contant/Constant.java b/commom/src/main/java/com/bx/common/contant/Constant.java index 40d3cf7..8e6b2dd 100644 --- a/commom/src/main/java/com/bx/common/contant/Constant.java +++ b/commom/src/main/java/com/bx/common/contant/Constant.java @@ -10,4 +10,6 @@ public class Constant { public static final long MAX_FILE_SIZE = 10*1024*1024; // 群聊最大人数 public static final long MAX_GROUP_MEMBER = 500; + // 在线状态过期时间 600s + public static final long ONLINE_TIMEOUT_SECOND = 600; } diff --git a/im-server/src/main/java/com/bx/imserver/websocket/processor/HeartbeatProcessor.java b/im-server/src/main/java/com/bx/imserver/websocket/processor/HeartbeatProcessor.java index 69cb8f2..9ae18de 100644 --- a/im-server/src/main/java/com/bx/imserver/websocket/processor/HeartbeatProcessor.java +++ b/im-server/src/main/java/com/bx/imserver/websocket/processor/HeartbeatProcessor.java @@ -1,17 +1,22 @@ package com.bx.imserver.websocket.processor; import cn.hutool.core.bean.BeanUtil; +import com.bx.common.contant.Constant; +import com.bx.common.contant.RedisKey; import com.bx.common.enums.WSCmdEnum; import com.bx.common.model.im.HeartbeatInfo; import com.bx.common.model.im.SendInfo; import com.bx.imserver.websocket.WebsocketServer; import io.netty.channel.ChannelHandlerContext; +import io.netty.util.Attribute; +import io.netty.util.AttributeKey; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import java.util.HashMap; +import java.util.concurrent.TimeUnit; @Slf4j @Component @@ -30,6 +35,18 @@ public class HeartbeatProcessor extends MessageProcessor { SendInfo sendInfo = new SendInfo(); sendInfo.setCmd(WSCmdEnum.HEART_BEAT.getCode()); ctx.channel().writeAndFlush(sendInfo); + + // 设置属性 + AttributeKey attr = AttributeKey.valueOf("HEARTBEAt_TIMES"); + Long heartbeatTimes = ctx.channel().attr(attr).get(); + ctx.channel().attr(attr).set(++heartbeatTimes); + if(heartbeatTimes%10 == 0){ + // 每心跳10次,用户在线状态续一次命 + attr = AttributeKey.valueOf("USER_ID"); + Long userId = ctx.channel().attr(attr).get(); + String key = RedisKey.IM_USER_SERVER_ID+userId; + redisTemplate.expire(key, Constant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS); + } } diff --git a/im-server/src/main/java/com/bx/imserver/websocket/processor/LoginProcessor.java b/im-server/src/main/java/com/bx/imserver/websocket/processor/LoginProcessor.java index a5225f8..64bd23a 100644 --- a/im-server/src/main/java/com/bx/imserver/websocket/processor/LoginProcessor.java +++ b/im-server/src/main/java/com/bx/imserver/websocket/processor/LoginProcessor.java @@ -1,6 +1,7 @@ package com.bx.imserver.websocket.processor; import cn.hutool.core.bean.BeanUtil; +import com.bx.common.contant.Constant; import com.bx.common.contant.RedisKey; import com.bx.common.enums.WSCmdEnum; import com.bx.common.model.im.LoginInfo; @@ -15,6 +16,7 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import java.util.HashMap; +import java.util.concurrent.TimeUnit; @Slf4j @Component @@ -39,12 +41,15 @@ public class LoginProcessor extends MessageProcessor { } // 绑定用户和channel WebsocketChannelCtxHolder.addChannelCtx(loginInfo.getUserId(),ctx); - // 设置属性 + // 设置用户id属性 AttributeKey attr = AttributeKey.valueOf("USER_ID"); ctx.channel().attr(attr).set(loginInfo.getUserId()); + // 心跳次数 + attr = AttributeKey.valueOf("HEARTBEAt_TIMES"); + ctx.channel().attr(attr).set(0L); // 在redis上记录每个user的channelId,15秒没有心跳,则自动过期 String key = RedisKey.IM_USER_SERVER_ID+loginInfo.getUserId(); - redisTemplate.opsForValue().set(key, WSServer.getServerId()); + redisTemplate.opsForValue().set(key, WSServer.getServerId(), Constant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS); // 响应ws SendInfo sendInfo = new SendInfo(); sendInfo.setCmd(WSCmdEnum.LOGIN.getCode());