diff --git a/src/main/java/com/subsidy/common/configure/WebSocketConfig.java b/src/main/java/com/subsidy/common/configure/WebSocketConfig.java
index 696db4b..277b1ba 100644
--- a/src/main/java/com/subsidy/common/configure/WebSocketConfig.java
+++ b/src/main/java/com/subsidy/common/configure/WebSocketConfig.java
@@ -3,10 +3,17 @@ package com.subsidy.common.configure;
import com.subsidy.common.interceptor.WebSocketInterceptor;
import com.subsidy.util.websocket.WebSocketUtil;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+import javax.servlet.http.HttpSession;
+import javax.websocket.HandshakeResponse;
+import javax.websocket.server.HandshakeRequest;
+import javax.websocket.server.ServerEndpointConfig;
/**
*
@@ -18,7 +25,7 @@ import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry
*/
@Configuration
@EnableWebSocket
-public class WebSocketConfig implements WebSocketConfigurer {
+public class WebSocketConfig extends ServerEndpointConfig.Configurator implements WebSocketConfigurer {
@Autowired
private WebSocketUtil webSocketUtil;
@@ -33,4 +40,22 @@ public class WebSocketConfig implements WebSocketConfigurer {
.addInterceptors(webSocketInterceptor) // 自定义验证规则
.setAllowedOrigins("*");
}
+
+
+
+ @Override
+ public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
+ HttpSession httpSession = (HttpSession)request.getHttpSession();
+ if (httpSession != null) {
+ // 读取session域中存储的数据
+ sec.getUserProperties().put(HttpSession.class.getName(),httpSession);
+ }
+ super.modifyHandshake(sec, request, response);
+ }
+
+ @Bean
+ public ServerEndpointExporter serverEndpointExporter(){
+ return new ServerEndpointExporter();
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/com/subsidy/common/interceptor/AuthenticationInterceptor.java b/src/main/java/com/subsidy/common/interceptor/AuthenticationInterceptor.java
index a86e689..f07d107 100644
--- a/src/main/java/com/subsidy/common/interceptor/AuthenticationInterceptor.java
+++ b/src/main/java/com/subsidy/common/interceptor/AuthenticationInterceptor.java
@@ -2,6 +2,7 @@ package com.subsidy.common.interceptor;
import com.alibaba.fastjson.JSON;
import com.auth0.jwt.interfaces.Claim;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.subsidy.common.ResponseData;
import com.subsidy.common.ResponseVO;
@@ -9,8 +10,10 @@ import com.subsidy.common.constant.Code;
import com.subsidy.common.exception.HttpException;
import com.subsidy.mapper.AdministerMapper;
import com.subsidy.mapper.MemberMapper;
+import com.subsidy.mapper.MemberTokensMapper;
import com.subsidy.model.AdministerDO;
import com.subsidy.model.MemberDO;
+import com.subsidy.model.MemberTokensDO;
import com.subsidy.util.ConstantUtils;
import com.subsidy.util.JwtUtil;
import com.subsidy.util.Localstorage;
@@ -49,6 +52,9 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
@Autowired
private MemberMapper memberMapper;
+ @Autowired
+ private MemberTokensMapper memberTokensMapper;
+
@Override
@CrossOrigin()
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
@@ -60,14 +66,14 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
-// TimeRequired timeRequired = method.getAnnotation(TimeRequired.class);
-// if (timeRequired !=null){
-// Calendar calendar = Calendar.getInstance();
-// int hour = calendar.get(Calendar.HOUR_OF_DAY);
-// if (hour<6){
-// throw new HttpException(17001);
-// }
-// }
+ TimeRequired timeRequired = method.getAnnotation(TimeRequired.class);
+ if (timeRequired !=null){
+ Calendar calendar = Calendar.getInstance();
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ if (hour<6){
+ throw new HttpException(17001);
+ }
+ }
LoginRequired methodAnnotation = method.getAnnotation(LoginRequired.class);
if (methodAnnotation != null) {
@@ -98,6 +104,14 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
Localstorage.setUser(memberDO);
return true;
}
+
+ int count = memberTokensMapper.selectCount(new QueryWrapper()
+ .lambda()
+ .eq(MemberTokensDO::getMemberId,memberDO.getId()));
+ if (count==0){
+ throw new HttpException(1011);
+ }
+
/**
* 学生端设置单设备登录
*/
diff --git a/src/main/java/com/subsidy/controller/MemberController.java b/src/main/java/com/subsidy/controller/MemberController.java
index cf76582..a2b841d 100644
--- a/src/main/java/com/subsidy/controller/MemberController.java
+++ b/src/main/java/com/subsidy/controller/MemberController.java
@@ -1,5 +1,6 @@
package com.subsidy.controller;
+import com.alibaba.fastjson.JSON;
import com.subsidy.common.ResponseData;
import com.subsidy.common.ResponseVO;
import com.subsidy.common.interceptor.LoginRequired;
@@ -7,6 +8,7 @@ import com.subsidy.common.interceptor.TimeRequired;
import com.subsidy.dto.administer.VerifyCodeDTO;
import com.subsidy.dto.live.PolyvInfoDTO;
import com.subsidy.dto.member.*;
+import com.subsidy.dto.vod.InsertHistoryNewDTO;
import com.subsidy.mapper.MemberMapper;
import com.subsidy.model.ExerciseDoneResultDO;
import com.subsidy.model.MemberDO;
@@ -221,6 +223,13 @@ public class MemberController {
return memberService.polyvInfo(userid,channelId,ts,token);
}
+ @RequestMapping("logout")
+ @ApiOperation("登出 学生id")
+ @TimeRequired
+ public ResponseVO logout(@RequestBody String param){
+ MemberDO memberDO = JSON.parseObject(param, MemberDO.class);
+ return ResponseData.generateCreatedResponse(0,memberService.logout(memberDO));
+ }
diff --git a/src/main/java/com/subsidy/controller/MemberTokensController.java b/src/main/java/com/subsidy/controller/MemberTokensController.java
new file mode 100644
index 0000000..d83f0a0
--- /dev/null
+++ b/src/main/java/com/subsidy/controller/MemberTokensController.java
@@ -0,0 +1,22 @@
+package com.subsidy.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+import io.swagger.annotations.Api;
+
+/**
+ *
+ * 用户登录token 前端控制器
+ *
+ *
+ * @author Tuyp
+ * @since 2023-01-06
+ */
+@RestController
+@Api(tags = "用户登录token")
+@RequestMapping("/member-tokens-do")
+public class MemberTokensController {
+
+}
diff --git a/src/main/java/com/subsidy/mapper/MemberTokensMapper.java b/src/main/java/com/subsidy/mapper/MemberTokensMapper.java
new file mode 100644
index 0000000..1b1c3ea
--- /dev/null
+++ b/src/main/java/com/subsidy/mapper/MemberTokensMapper.java
@@ -0,0 +1,20 @@
+package com.subsidy.mapper;
+
+import com.subsidy.model.MemberTokensDO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ *
+ * 用户登录token Mapper 接口
+ *
+ *
+ * @author Tuyp
+ * @since 2023-01-06
+ */
+ @Repository
+public interface MemberTokensMapper extends BaseMapper {
+
+ void updateToken(Long memberId,String token);
+
+}
diff --git a/src/main/java/com/subsidy/mapper/OprMemDictMapper.java b/src/main/java/com/subsidy/mapper/OprMemDictMapper.java
index 9a11aeb..beb95d5 100644
--- a/src/main/java/com/subsidy/mapper/OprMemDictMapper.java
+++ b/src/main/java/com/subsidy/mapper/OprMemDictMapper.java
@@ -25,4 +25,6 @@ public interface OprMemDictMapper extends BaseMapper {
OprMemDictDO getLatestLoginInfo(Long userId);
+ void deleteData(OprMemDictDO oprMemDictDO);
+
}
diff --git a/src/main/java/com/subsidy/model/MemberTokensDO.java b/src/main/java/com/subsidy/model/MemberTokensDO.java
new file mode 100644
index 0000000..5c9da32
--- /dev/null
+++ b/src/main/java/com/subsidy/model/MemberTokensDO.java
@@ -0,0 +1,36 @@
+package com.subsidy.model;
+
+import com.subsidy.util.BaseModel;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ *
+ * 用户登录token
+ *
+ *
+ * @author Tuyp
+ * @since 2023-01-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("member_tokens")
+public class MemberTokensDO extends BaseModel {
+
+ private static final long serialVersionUID = 1L;
+
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ private Long memberId;
+
+ /**
+ * 用户token
+ */
+ private String token;
+
+
+}
diff --git a/src/main/java/com/subsidy/service/MemberService.java b/src/main/java/com/subsidy/service/MemberService.java
index b73d0c1..a7c5a17 100644
--- a/src/main/java/com/subsidy/service/MemberService.java
+++ b/src/main/java/com/subsidy/service/MemberService.java
@@ -78,4 +78,6 @@ public interface MemberService extends IService {
List memberLives(MemberDO memberDO);
PolyvInfoVO polyvInfo(String userid,String channelId,String ts,String token);
+
+ String logout(MemberDO memberDO);
}
diff --git a/src/main/java/com/subsidy/service/MemberTokensService.java b/src/main/java/com/subsidy/service/MemberTokensService.java
new file mode 100644
index 0000000..cb9c2b6
--- /dev/null
+++ b/src/main/java/com/subsidy/service/MemberTokensService.java
@@ -0,0 +1,16 @@
+package com.subsidy.service;
+
+import com.subsidy.model.MemberTokensDO;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 用户登录token 服务类
+ *
+ *
+ * @author Tuyp
+ * @since 2023-01-06
+ */
+public interface MemberTokensService extends IService {
+
+}
diff --git a/src/main/java/com/subsidy/service/impl/ImageCheckRecordServiceImpl.java b/src/main/java/com/subsidy/service/impl/ImageCheckRecordServiceImpl.java
index 86bef7b..fc62438 100644
--- a/src/main/java/com/subsidy/service/impl/ImageCheckRecordServiceImpl.java
+++ b/src/main/java/com/subsidy/service/impl/ImageCheckRecordServiceImpl.java
@@ -254,7 +254,9 @@ public class ImageCheckRecordServiceImpl extends ServiceImpl()
+ .lambda()
+ .eq(ImageCheckRecordDO::getBizSeqNo,checkResultDTO.getId()));
if (!StringUtils.isEmpty(resultVO.getSimilarity())) {
BeanUtils.copyProperties(resultVO, imageCheckRecordDO);
ActivityDetectionDO activityDetectionDO = new ActivityDetectionDO();
@@ -286,6 +288,7 @@ public class ImageCheckRecordServiceImpl extends ServiceImpl imple
@Autowired
private ActivityDetectionMapper activityDetectionMapper;
+ @Autowired
+ private MemberTokensMapper memberTokensMapper;
+
public IPage getAll(GetAllDTO getAllDTO) {
Page pager = new Page(getAllDTO.getPageNum(), getAllDTO.getPageSize());
@@ -340,12 +343,15 @@ public class MemberServiceImpl extends ServiceImpl imple
throw new HttpException(70010);
}
//审计日志
- OprMemDictDO oprMemDictDO = new OprMemDictDO();
- oprMemDictDO.setUserId(memberDO.getId());
- oprMemDictDO.setOprType("登录");
- oprMemDictDO.setResult(1);
- oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
- oprMemDictMapper.insert(oprMemDictDO);
+ OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(memberDO.getId());
+ if (null == oprMemDictDO || !(oprMemDictDO.getResult() == 1 && "登录".equals(oprMemDictDO.getOprType()))) {
+ oprMemDictDO = new OprMemDictDO();
+ oprMemDictDO.setUserId(memberDO.getId());
+ oprMemDictDO.setOprType("登录");
+ oprMemDictDO.setResult(1);
+ oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
+ oprMemDictMapper.insert(oprMemDictDO);
+ }
//mongoTemplate.insert(oprMemDictDO);
userRoleVO.setCompanyId(companyDictDO.getId());
userRoleVO.setSuperviseName(companyDictDO.getSuperviseName());
@@ -390,12 +396,15 @@ public class MemberServiceImpl extends ServiceImpl imple
memberVO.setCompanyId(companyDictDO.getId());
memberVO.setCompanyName(companyDictDO.getCompanyName());
memberVO.setQxyStatus(companyDictDO.getQxyStatus());
- OprMemDictDO oprMemDictDO = new OprMemDictDO();
- oprMemDictDO.setUserId(memberDO.getId());
- oprMemDictDO.setOprType("登录");
- oprMemDictDO.setResult(1);
- oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
- oprMemDictMapper.insert(oprMemDictDO);
+ OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(memberDO.getId());
+ if (null == oprMemDictDO || !(oprMemDictDO.getResult() == 1 && "登录".equals(oprMemDictDO.getOprType()))) {
+ oprMemDictDO = new OprMemDictDO();
+ oprMemDictDO.setUserId(memberDO.getId());
+ oprMemDictDO.setOprType("登录");
+ oprMemDictDO.setResult(1);
+ oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
+ oprMemDictMapper.insert(oprMemDictDO);
+ }
memberVO.setCompanyId(companyDictDO.getId());
memberVO.setSuperviseName(companyDictDO.getSuperviseName());
memberVO.setCompanyName(companyDictDO.getCompanyName());
@@ -406,6 +415,20 @@ public class MemberServiceImpl extends ServiceImpl imple
memberVO.setRotationImgDictDOS(rotationImgDictDOS);
String token = JwtUtil.generateToken(memberDO.getId(), ConstantUtils.MOBILE_TERMINATE);
+
+ //更新token
+ int count = memberTokensMapper.selectCount(new QueryWrapper()
+ .lambda()
+ .eq(MemberTokensDO::getMemberId, memberDO.getId()));
+ if (count > 0) {
+ memberTokensMapper.updateToken(memberDO.getId(), token);
+ } else {
+ MemberTokensDO memberTokensDO = new MemberTokensDO();
+ memberTokensDO.setMemberId(memberDO.getId());
+ memberTokensDO.setToken(token);
+ memberTokensMapper.insert(memberTokensDO);
+ }
+
Localstorage.setUser(memberDO);
memberVO.setToken(token);
return memberVO;
@@ -536,12 +559,15 @@ public class MemberServiceImpl extends ServiceImpl imple
BeanUtils.copyProperties(memberDO, userRoleVO);
//审计日志
- OprMemDictDO oprMemDictDO = new OprMemDictDO();
- oprMemDictDO.setUserId(memberDO.getId());
- oprMemDictDO.setOprType("登录");
- oprMemDictDO.setResult(1);
- oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
- oprMemDictMapper.insert(oprMemDictDO);
+ OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(memberDO.getId());
+ if (null == oprMemDictDO || !(oprMemDictDO.getResult() == 1 && "登录".equals(oprMemDictDO.getOprType()))) {
+ oprMemDictDO = new OprMemDictDO();
+ oprMemDictDO.setUserId(memberDO.getId());
+ oprMemDictDO.setOprType("登录");
+ oprMemDictDO.setResult(1);
+ oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
+ oprMemDictMapper.insert(oprMemDictDO);
+ }
userRoleVO.setCompanyId(companyDictDO.getId());
userRoleVO.setSuperviseName(companyDictDO.getSuperviseName());
userRoleVO.setCompanyName(companyDictDO.getCompanyName());
@@ -627,12 +653,15 @@ public class MemberServiceImpl extends ServiceImpl imple
BeanUtils.copyProperties(memberDO, userRoleVO);
//审计日志
- OprMemDictDO oprMemDictDO = new OprMemDictDO();
- oprMemDictDO.setUserId(memberDO.getId());
- oprMemDictDO.setOprType("登录");
- oprMemDictDO.setResult(1);
- oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
- oprMemDictMapper.insert(oprMemDictDO);
+ OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(memberDO.getId());
+ if (null == oprMemDictDO || !(oprMemDictDO.getResult() == 1 && "登录".equals(oprMemDictDO.getOprType()))) {
+ oprMemDictDO = new OprMemDictDO();
+ oprMemDictDO.setUserId(memberDO.getId());
+ oprMemDictDO.setOprType("登录");
+ oprMemDictDO.setResult(1);
+ oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
+ oprMemDictMapper.insert(oprMemDictDO);
+ }
userRoleVO.setCompanyId(companyDictDO.getId());
userRoleVO.setSuperviseName(companyDictDO.getSuperviseName());
userRoleVO.setCompanyName(companyDictDO.getCompanyName());
@@ -1128,5 +1157,20 @@ public class MemberServiceImpl extends ServiceImpl imple
return polyvInfoVO;
}
+ public String logout(MemberDO memberDO) {
+ memberTokensMapper.delete(new QueryWrapper()
+ .lambda()
+ .eq(MemberTokensDO::getMemberId, memberDO.getId()));
+ OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(memberDO.getId());
+
+ if (oprMemDictDO.getResult() == 1 && "登出".equals(oprMemDictDO.getOprType())) {
+ oprMemDictMapper.deleteData(oprMemDictDO);
+ }
+ oprMemDictDO.setUserId(memberDO.getId());
+ oprMemDictDO.setResult(1);
+ oprMemDictDO.setOprType("登出");
+ oprMemDictMapper.insert(oprMemDictDO);
+ return ConstantUtils.ADD_SUCCESS;
+ }
}
diff --git a/src/main/java/com/subsidy/service/impl/MemberTokensServiceImpl.java b/src/main/java/com/subsidy/service/impl/MemberTokensServiceImpl.java
new file mode 100644
index 0000000..92f447f
--- /dev/null
+++ b/src/main/java/com/subsidy/service/impl/MemberTokensServiceImpl.java
@@ -0,0 +1,20 @@
+package com.subsidy.service.impl;
+
+import com.subsidy.model.MemberTokensDO;
+import com.subsidy.mapper.MemberTokensMapper;
+import com.subsidy.service.MemberTokensService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 用户登录token 服务实现类
+ *
+ *
+ * @author Tuyp
+ * @since 2023-01-06
+ */
+@Service
+public class MemberTokensServiceImpl extends ServiceImpl implements MemberTokensService {
+
+}
diff --git a/src/main/java/com/subsidy/util/websocket/WebSocketUtil.java b/src/main/java/com/subsidy/util/websocket/WebSocketUtil.java
index 90c6f11..6c00456 100644
--- a/src/main/java/com/subsidy/util/websocket/WebSocketUtil.java
+++ b/src/main/java/com/subsidy/util/websocket/WebSocketUtil.java
@@ -3,6 +3,7 @@ package com.subsidy.util.websocket;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.subsidy.common.ResponseData;
+import com.subsidy.common.exception.HttpException;
import com.subsidy.mapper.ClassDictMapper;
import com.subsidy.mapper.MemberMapper;
import com.subsidy.mapper.OprMemDictMapper;
@@ -15,17 +16,15 @@ import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
-import org.springframework.web.socket.handler.AbstractWebSocketHandler;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.*;
/**
- *
* WebSocket
- *
- * https://zhuanlan.zhihu.com/p/531474864
+ * https://zhuanlan.zhihu.com/p/531474864
+ *
* @author DengMin
* @since 2022/7/13
*/
@@ -44,7 +43,7 @@ public class WebSocketUtil implements WebSocketHandler {
private int heartbeatMin = 1; // 断连最小心跳次数
private int heartbeatMax = 3; // 断连最大心跳次数
- private int reconnectionSeconds = 60; //每次断连间隔重新连接秒
+ private int reconnectionSeconds = 30; //每次断连间隔重新连接秒
/**
* 存放建立连接webSocket对象 Map
@@ -60,42 +59,38 @@ public class WebSocketUtil implements WebSocketHandler {
public void afterConnectionEstablished(WebSocketSession session) throws IOException {
if (null != session) {
String params = session.getUri().getQuery();
- Long id = Long.valueOf(params.split("=")[1]);
-
+ //ws://www.youkehulian.cn/nginx/socket?userId=3340&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MzM0MCwidHlwZSI6Im1vYmlsZSIsImV4cCI6MTY3MzA1NjAzOSwiaWF0IjoxNjcyOTY5NjM5fQ.qx05-0AoWcaktgux30dJLmRE7AdtRuSWvk6cX7CNnao
+// Long id = Long.valueOf(params.split("=")[1]);
+ String[] split = params.split("=");
+ Long id = Long.valueOf(split[1].split("&")[0]);
+ String token = split[2];
+// OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(id); //最近一次登录
+// if (null != oprMemDictDO) {
+// //如果最近一次不是登录成功,那么就是页面上刷新
+// if (!("登录".equals(oprMemDictDO.getOprType()) && 1 == oprMemDictDO.getResult())) {
+// webSocketMap.put(id, session);
+// webSocketMap.get(id).sendMessage(new TextMessage(JSONObject.toJSONString(ResponseData.generateCreatedResponse(1012))));
+// }
+// }
//webSocketMap的操作
if (null != webSocketMap && webSocketMap.get(id) != null) {
if (webSocketMap.get(id).isOpen()) {
/* 相同账户进行挤号,发送消息给WebSocket通知账户已在其他地方登录 */
webSocketMap.get(id).sendMessage(new TextMessage(JSONObject.toJSONString(ResponseData.generateCreatedResponse(1011))));
webSocketMap.get(id).close();
- } else {
- /*
- * 上次连接的WebSocket状态是关闭,
- * 并且上一次记录时间大于 { heartbeatMax * reconnectionSeconds } 秒(心跳检测机制),则判断为这次登陆是免密码登陆的重新记录上线时间
- */
- OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(id); //最近一次登录
-
- if (oprMemDictDO.getOprType().equals("登出")) {
- //登出过的话就写记录,否则不写
- oprMemDictDO.setUserId(id);
- oprMemDictDO.setResult(1);
- oprMemDictDO.setOprType("登录");
-// oprMemDictDO.setIpAddress(session.getRemoteAddress().getHostName());
- oprMemDictMapper.insert(oprMemDictDO);
- }
-// }
}
webSocketMap.remove(id);
}
webSocketMap.put(id, session);
-
// 数据操作
SystemSettings systemSettings = memberMapper.companySettings(id); //公司配置
List classSettings = classDictMapper.getClassSettings(id);
systemSettings.setClassSettingsVOS(classSettings);
if (CollectionUtils.isNotEmpty(classSettings)) {
String data = JSONObject.toJSONString(ResponseData.generateCreatedResponse(0, systemSettings), SerializerFeature.WriteMapNullValue);
- webSocketMap.get(id).sendMessage(new TextMessage(data));
+ if (null != webSocketMap.get(id)) {
+ webSocketMap.get(id).sendMessage(new TextMessage(data));
+ }
}
}
}
@@ -104,8 +99,8 @@ public class WebSocketUtil implements WebSocketHandler {
* 接收WebSocket客户端Message
*/
@Override
- public void handleMessage(WebSocketSession session, WebSocketMessage> message) throws Exception {
- this.handleMessage(session,message);
+ public void handleMessage(WebSocketSession session, WebSocketMessage> message) {
+ this.handleMessage(session, message);
}
/**
@@ -116,9 +111,11 @@ public class WebSocketUtil implements WebSocketHandler {
if (session.isOpen()) {
session.close();
}
-
String params = session.getUri().getQuery();
- Long id = Long.valueOf(params.split("=")[1]);
+ String[] split = params.split("=");
+ Long id = Long.valueOf(split[1].split("&")[0]);
+// String token = split[2];
+// Long id = Long.valueOf(params.split("=")[1]);
webSocketMap.remove(id);
}
@@ -129,9 +126,12 @@ public class WebSocketUtil implements WebSocketHandler {
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
if (null != session) {
if (null != webSocketMap) {
- String params = session.getUri().getQuery();
- Long id = Long.valueOf(params.split("=")[1]);
- heartbeat(webSocketMap.get(id));
+// String params = session.getUri().getQuery();
+// String[] split = params.split("=");
+// Long id = Long.valueOf(split[1].split("&")[0]);
+// String token = split[2];
+// Long id = Long.valueOf(params.split("=")[1]);
+// heartbeat(webSocketMap.get(id));
}
}
}
@@ -148,34 +148,55 @@ public class WebSocketUtil implements WebSocketHandler {
* 断开连接后进行三次心跳验证判断是否重新连接了,如果没有连接成功则判断为下线
*/
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()) {
- if (beatsNum > heartbeatMax) { //heartbeatMa:2
- String params = session.getUri().getQuery();
- Long id = Long.valueOf(params.split("=")[1]);
- OprMemDictDO oprMemDictDO = new OprMemDictDO();
- oprMemDictDO.setUserId(id);
- oprMemDictDO.setResult(1);
- oprMemDictDO.setOprType("登出");
- oprMemDictMapper.insert(oprMemDictDO);
- taskMap.get(session.getId()).cancel(true);
-// break;
- }
- beatsNum++;
- } else if (null != session && session.isOpen()) {
- /* 时间段内重新连接了结束验证 */
- beatsNum = heartbeatMin;
- taskMap.get(session.getId()).cancel(true);
- }
- }
- }, 0, reconnectionSeconds, TimeUnit.SECONDS);
- taskMap.put(session.getId(), scheduledFuture);
+// ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
+// String params = session.getUri().getQuery();
+// String[] split = params.split("=");
+// Long id = Long.valueOf(split[1].split("&")[0]);
+// String token = split[2];
+//
+// ScheduledFuture scheduledFuture = service.scheduleAtFixedRate(new Runnable() {
+// int beatsNum = heartbeatMin; //至少一次
+//
+// @SneakyThrows
+// @Override
+// public void run() {
+// if (null != session && !session.isOpen()) {
+// //判断这个session在不在map里
+// if (taskMap.containsKey(token)) {
+// //在map里并且这个session还是断开的情况下,进行重连,超过次数就掉线
+// if (beatsNum > heartbeatMax) { //
+// OprMemDictDO oprMemDictDO = new OprMemDictDO();
+// oprMemDictDO.setUserId(id);
+// oprMemDictDO.setResult(1);
+// oprMemDictDO.setOprType("登出");
+// oprMemDictMapper.insert(oprMemDictDO);
+// //结束任务
+// taskMap.get(token).cancel(true);
+// taskMap.remove(token);
+// }
+// beatsNum++;
+// }
+// } else if (null != session && session.isOpen()) {
+// if (taskMap.containsKey(token)){
+// /* 时间段内重新连接了结束验证 */
+// beatsNum = heartbeatMin; //重连次数清零
+// taskMap.get(token).cancel(true);
+// taskMap.remove(token);
+// }
+//
+// }
+// }
+// }, 0, reconnectionSeconds, TimeUnit.SECONDS);
+// taskMap.put(token, scheduledFuture);
}
+
+ public static void main(String[] args) {
+ String url = "ws://www.youkehulian.cn/nginx/socket?userId=3340&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MzM0MCwidHlwZSI6Im1vYmlsZSIsImV4cCI6MTY3MzA1NjAzOSwiaWF0IjoxNjcyOTY5NjM5fQ.qx05-0AoWcaktgux30dJLmRE7AdtRuSWvk6cX7CNnao";
+ String[] split = url.split("=");
+ Long id = Long.valueOf(split[1].split("&")[0]);
+ String token = split[2];
+ System.out.println(id);
+ System.out.println(token);
+ }
}
\ No newline at end of file
diff --git a/src/main/resources/code.properties b/src/main/resources/code.properties
index 16b0958..54021c1 100644
--- a/src/main/resources/code.properties
+++ b/src/main/resources/code.properties
@@ -2,6 +2,7 @@ meishu.code-message[0]=成功
meishu.code-message[1010]=无效的令牌
meishu.code-message[1011]=当前账户已在其他设备登录
+meishu.code-message[1012]=你已掉线,请重新登录
meishu.code-message[10003]=验证码错误
meishu.code-message[10004]=账号或密码错误
diff --git a/src/main/resources/mapper/MemberTokensMapper.xml b/src/main/resources/mapper/MemberTokensMapper.xml
new file mode 100644
index 0000000..0e3c1a3
--- /dev/null
+++ b/src/main/resources/mapper/MemberTokensMapper.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ create_date,
+ update_date,
+ delete_date,
+ id, member_id, token
+
+
+
+ UPDATE member_tokens t
+ SET t.token = #{token}
+ WHERE
+ t.delete_date IS NULL
+ AND t.member_id = #{memberId}
+
+
+
diff --git a/src/main/resources/mapper/OprMemDictMapper.xml b/src/main/resources/mapper/OprMemDictMapper.xml
index c5588f3..5ebdae3 100644
--- a/src/main/resources/mapper/OprMemDictMapper.xml
+++ b/src/main/resources/mapper/OprMemDictMapper.xml
@@ -56,17 +56,28 @@
+
+
+ DELETE
+ FROM
+ opr_mem_dict
+ WHERE
+ delete_date IS NULL
+ AND id = #{id}
+