Browse Source

优化心跳功能

master
xie.bx 3 years ago
parent
commit
d3743db6ca
  1. 2
      commom/src/main/java/com/bx/common/contant/Constant.java
  2. 17
      im-server/src/main/java/com/bx/imserver/websocket/processor/HeartbeatProcessor.java
  3. 9
      im-server/src/main/java/com/bx/imserver/websocket/processor/LoginProcessor.java

2
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;
}

17
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<HeartbeatInfo> {
SendInfo sendInfo = new SendInfo();
sendInfo.setCmd(WSCmdEnum.HEART_BEAT.getCode());
ctx.channel().writeAndFlush(sendInfo);
// 设置属性
AttributeKey<Long> 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);
}
}

9
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<LoginInfo> {
}
// 绑定用户和channel
WebsocketChannelCtxHolder.addChannelCtx(loginInfo.getUserId(),ctx);
// 设置属性
// 设置用户id属性
AttributeKey<Long> 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());

Loading…
Cancel
Save