Commit e4fc42d1 by 邓敏

webSocket新增心跳机制

1 parent a3bbd3a0
......@@ -40,6 +40,10 @@ public class WebSocketUtil implements WebSocketHandler {
@Autowired
private OprMemDictMapper oprMemDictMapper;
private int heartbeatMin = 1; // 断连最小心跳次数
private int heartbeatMax = 3; // 断连最大心跳次数
private int reconnectionSeconds = 60; //每次断连间隔重新连接秒
/**
* 存放建立连接webSocket对象
*/
......@@ -58,14 +62,13 @@ public class WebSocketUtil implements WebSocketHandler {
Long id = Long.valueOf(params.split("=")[1]);
if(null != webSocketMap && webSocketMap.get(id) != null) {
if(webSocketMap.get(id).isOpen()) {
/*
相同账户进行挤号,发送消息给前者WebSocket通知账户已在其他地方登录
*/
/* 相同账户进行挤号,发送消息给WebSocket通知账户已在其他地方登录 */
webSocketMap.get(id).sendMessage(new TextMessage(JSONObject.toJSONString(ResponseData.generateCreatedResponse(1011))));
webSocketMap.get(id).close();
} else {
/*
* 如果上次连接的WebSocket状态是关闭,并且上一次记录时间大于60秒的,则判断为这次登陆是免密码登陆的重新记录上线时间
* 如果上次连接的WebSocket状态是关闭,
* 并且上一次记录时间大于 { heartbeatMax * reconnectionSeconds } 秒(心跳检测机制),则判断为这次登陆是免密码登陆的重新记录上线时间
*/
List<OprMemDictDO> list = oprMemDictMapper.selectList(new QueryWrapper<OprMemDictDO>()
.lambda()
......@@ -74,7 +77,7 @@ public class WebSocketUtil implements WebSocketHandler {
Calendar calendar = Calendar.getInstance();
calendar.setTime(DateFormatUtil.localDateTimeToDate(list.get(0).getCreateDate()));
calendar.add(Calendar.SECOND,60);
calendar.add(Calendar.SECOND,heartbeatMax * reconnectionSeconds);
if(calendar.getTime().after(DateFormatUtil.localDateTimeToDate(list.get(0).getCreateDate()))) {
if(list.get(0).getOprType().equals("登出")) {
OprMemDictDO oprMemDictDO = new OprMemDictDO();
......@@ -127,9 +130,6 @@ public class WebSocketUtil implements WebSocketHandler {
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception{
if(null != session) {
/*
断开连接后不会马上判断为下线状态,而是进入60秒的心跳检测机制,如果60秒内没有进行重连,则判断为下线,记录下线时间和状态
*/
if(null != webSocketMap) {
String params = session.getUri().getQuery();
Long id = Long.valueOf(params.split("=")[1]);
......@@ -141,17 +141,19 @@ public class WebSocketUtil implements WebSocketHandler {
}
/**
* 断开连接后60秒后进行判断是否重新连接了,如果没有连接成功则判断为下线
* 断开连接后进行三次心跳验证判断是否重新连接了,如果没有连接成功则判断为下线
*
* @param session
*/
public void heartbeat(WebSocketSession session) {
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
ScheduledFuture scheduledFuture = service.scheduleAtFixedRate(new Runnable() {
int beatsNum = heartbeatMin;
@SneakyThrows
@Override
public void run() {
if(null != session && !session.isOpen()) {
while (beatsNum > heartbeatMax) {
String params = session.getUri().getQuery();
Long id = Long.valueOf(params.split("=")[1]);
OprMemDictDO oprMemDictDO = new OprMemDictDO();
......@@ -162,8 +164,13 @@ public class WebSocketUtil implements WebSocketHandler {
oprMemDictMapper.insert(oprMemDictDO);
taskMap.get(session.getId()).cancel(true);
}
beatsNum++;
} else if (null != session && session.isOpen()) {
/* 时间段内重新连接了结束验证 */
taskMap.get(session.getId()).cancel(true);
}
}
}, 1, 1, TimeUnit.MINUTES);
}, 0, reconnectionSeconds, TimeUnit.SECONDS);
taskMap.put(session.getId(), scheduledFuture);
}
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!