diff --git a/framework/src/main/java/cn/lili/modules/im/entity/enums/MessageResultType.java b/framework/src/main/java/cn/lili/modules/im/entity/enums/MessageResultType.java index ba54b5d5..c557a45e 100644 --- a/framework/src/main/java/cn/lili/modules/im/entity/enums/MessageResultType.java +++ b/framework/src/main/java/cn/lili/modules/im/entity/enums/MessageResultType.java @@ -16,6 +16,7 @@ public enum MessageResultType { * 未读消息 * 历史消息 * 系统提示 + * 下线提醒 */ FRIENDS, ADD_FRIENDS, @@ -23,6 +24,7 @@ public enum MessageResultType { READ_MESSAGE, UN_READ, HISTORY, - SYSTEM_TIPS + SYSTEM_TIPS, + OFFLINE } diff --git a/framework/src/main/java/cn/lili/modules/im/entity/vo/MessageVO.java b/framework/src/main/java/cn/lili/modules/im/entity/vo/MessageVO.java index 420091e1..120abc1a 100644 --- a/framework/src/main/java/cn/lili/modules/im/entity/vo/MessageVO.java +++ b/framework/src/main/java/cn/lili/modules/im/entity/vo/MessageVO.java @@ -2,6 +2,7 @@ package cn.lili.modules.im.entity.vo; import cn.lili.modules.im.entity.enums.MessageResultType; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; /** @@ -12,6 +13,7 @@ import lombok.Data; * 2021-12-30 15:51 */ @Data +@Builder @AllArgsConstructor public class MessageVO { diff --git a/im-api/src/main/java/cn/lili/controller/im/ImUserController.java b/im-api/src/main/java/cn/lili/controller/im/ImUserController.java index b3b56937..ff00bc0f 100644 --- a/im-api/src/main/java/cn/lili/controller/im/ImUserController.java +++ b/im-api/src/main/java/cn/lili/controller/im/ImUserController.java @@ -5,7 +5,6 @@ import cn.lili.common.enums.ResultUtil; import cn.lili.common.security.AuthUser; import cn.lili.common.security.context.UserContext; import cn.lili.common.vo.ResultMessage; -import cn.lili.modules.member.entity.dos.FootPrint; import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.member.entity.dto.FootPrintQueryParams; import cn.lili.modules.member.service.FootprintService; @@ -38,11 +37,9 @@ public class ImUserController { private final MemberService memberService; - @Autowired - private StoreService storeService; + private final StoreService storeService; - @Autowired - private FootprintService footprintService; + private final FootprintService footprintService; @GetMapping @ApiOperation(value = "获取用户信息") diff --git a/im-api/src/main/java/cn/lili/controller/im/WebSocketServer.java b/im-api/src/main/java/cn/lili/controller/im/WebSocketServer.java index 6e7f8de8..97db2ad9 100644 --- a/im-api/src/main/java/cn/lili/controller/im/WebSocketServer.java +++ b/im-api/src/main/java/cn/lili/controller/im/WebSocketServer.java @@ -1,6 +1,6 @@ package cn.lili.controller.im; -import cn.lili.cache.Cache; +import cn.hutool.json.JSONUtil; import cn.lili.common.security.AuthUser; import cn.lili.common.security.context.UserContext; import cn.lili.common.security.enums.UserEnums; @@ -12,11 +12,10 @@ import cn.lili.modules.im.entity.vo.MessageOperation; import cn.lili.modules.im.entity.vo.MessageVO; import cn.lili.modules.im.service.ImMessageService; import cn.lili.modules.im.service.ImTalkService; -import cn.lili.modules.member.service.MemberService; -import cn.lili.modules.store.service.StoreService; import com.alibaba.druid.util.StringUtils; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; @@ -35,53 +34,46 @@ import java.util.concurrent.ConcurrentHashMap; @ServerEndpoint(value = "/lili/webSocket/{accessToken}", configurator = CustomSpringConfigurator.class) @Scope("prototype") @Slf4j +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class WebSocketServer { /** * 消息服务 */ - @Autowired - private ImMessageService imMessageService; + private final ImMessageService imMessageService; - /** - * im用户服务 - */ - @Autowired - private MemberService memberService; + private final ImTalkService imTalkService; - @Autowired - private StoreService storeService; - - @Autowired - private ImTalkService imTalkService; - - - @Autowired - private Cache cache; /** * 在线人数 * PS 注意,只能单节点,如果多节点部署需要自行寻找方案 */ private static ConcurrentHashMap sessionPools = new ConcurrentHashMap<>(); + /** * 建立连接 * * @param session */ @OnOpen - public void onOpen(@PathParam("accessToken") String accessToken, Session session) throws IOException { - AuthUser authUser = UserContext.getAuthUser(accessToken); - Object message = null; - if (UserEnums.STORE.equals(authUser.getRole())) { - message = storeService.getById(authUser.getStoreId()); - sessionPools.put(authUser.getStoreId(), session); + public void onOpen(@PathParam("accessToken") String accessToken, Session session) { - } else if (UserEnums.MEMBER.equals(authUser.getRole())) { - message = memberService.getById(authUser.getId()); - sessionPools.put(authUser.getId(), session); + + AuthUser authUser = UserContext.getAuthUser(accessToken); + + String sessionId = UserEnums.STORE.equals(authUser.getRole()) ? authUser.getStoreId() : authUser.getId(); + //如果已有会话,则进行下线提醒。 + if (sessionPools.containsKey(sessionId)) { + log.info("用户重复登陆,旧用户下线"); + Session oldSession = sessionPools.get(sessionId); + sendMessage(oldSession, MessageVO.builder().messageResultType(MessageResultType.OFFLINE).result("用户异地登陆").build()); + try { + oldSession.close(); + } catch (Exception e) { + e.printStackTrace(); + } } - MessageVO messageVO = new MessageVO(MessageResultType.FRIENDS, message); - sendMessage(authUser.getId(), messageVO); + sessionPools.put(sessionId, session); } /** @@ -89,8 +81,9 @@ public class WebSocketServer { */ @OnClose public void onClose(@PathParam("accessToken") String accessToken) { - log.info("断开连接:{}", accessToken); - sessionPools.remove(UserContext.getAuthUser(accessToken).getId()); + AuthUser authUser = UserContext.getAuthUser(accessToken); + log.info("用户断开断开连接:{}", JSONUtil.toJsonStr(authUser)); + sessionPools.remove(authUser); } /** @@ -101,7 +94,7 @@ public class WebSocketServer { */ @OnMessage public void onMessage(@PathParam("accessToken") String accessToken, String msg) { - log.error(msg); + log.info("发送消息:{}", msg); MessageOperation messageOperation = JSON.parseObject(msg, MessageOperation.class); operation(accessToken, messageOperation); } @@ -123,9 +116,9 @@ public class WebSocketServer { ImMessage imMessage = new ImMessage(messageOperation); imMessageService.save(imMessage); //修改最后消息信息 - imTalkService.update(new LambdaUpdateWrapper().eq(ImTalk::getId,messageOperation.getTalkId()).set(ImTalk::getLastTalkMessage,messageOperation.getContext()) - .set(ImTalk::getLastTalkTime,imMessage.getCreateTime()) - .set(ImTalk::getLastMessageType,imMessage.getMessageType())); + imTalkService.update(new LambdaUpdateWrapper().eq(ImTalk::getId, messageOperation.getTalkId()).set(ImTalk::getLastTalkMessage, messageOperation.getContext()) + .set(ImTalk::getLastTalkTime, imMessage.getCreateTime()) + .set(ImTalk::getLastMessageType, imMessage.getMessageType())); //发送消息 sendMessage(messageOperation.getTo(), new MessageVO(MessageResultType.MESSAGE, imMessage)); break; @@ -148,15 +141,25 @@ public class WebSocketServer { /** * 发送消息 * - * @param key 密钥 + * @param sessionId sessionId + * @param message 消息对象 + */ + private void sendMessage(String sessionId, MessageVO message) { + Session session = sessionPools.get(sessionId); + sendMessage(session, message); + } + + /** + * 发送消息 + * + * @param session 会话 * @param message 消息对象 */ - private void sendMessage(String key, MessageVO message) { - Session session = sessionPools.get(key); + private void sendMessage(Session session, MessageVO message) { if (session != null) { try { session.getBasicRemote().sendText(JSON.toJSONString(message, true)); - } catch (IOException e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -170,16 +173,8 @@ public class WebSocketServer { */ @OnError public void onError(Session session, Throwable throwable) { - throwable.printStackTrace(); + log.error("socket异常: {}", session.getId(), throwable); } - /** - * 获取店铺id - * - * @return - */ - private String storeKey(String storeId) { - return "STORE_" + storeId; - } }