mirror of
https://github.com/zongzibinbin/MallChat.git
synced 2026-03-13 21:53:41 +08:00
1.记录微信消息
2.重复上线问题解决
This commit is contained in:
12
README.md
12
README.md
@@ -1,12 +1,12 @@
|
||||

|
||||
|
||||
MallChat的后端项目,是一个既能购物又能即时聊天的电商系统。致力于打造互联网企业级项目的最佳实践。电商该有的购物车,订单,支付,推荐,搜索,拉新,促活,推送,物流,客服,它都必须有。持续更新ing~~
|
||||
MallChat的后端项目,是一个既能购物又能即时聊天的电商系统。致力于打造互联网企业级项目的最佳实践。电商该有的购物车,订单,支付,推荐,搜索,拉新,促活,推送,物流,客服,它都必须有。持续更新ing~~(记得star啊喂!)
|
||||
|
||||
<p align="center">
|
||||
<a href="#公众号"><img src="https://img.shields.io/badge/公众号-程序员阿斌-blue.svg?style=plasticr"></a>
|
||||
<a href="#公众号"><img src="https://img.shields.io/badge/交流群-加入开发-green.svg?style=plasticr"></a>
|
||||
<a href="https://github.com/zongzibinbin/MallChat"><img src="https://img.shields.io/badge/github-项目地址-yellow.svg?style=plasticr"></a>
|
||||
<a href="https://github.com/zongzibinbin/MallChat"><img src="https://img.shields.io/badge/码云-项目地址-orange.svg?style=plasticr"></a>
|
||||
<a href="https://gitee.com/zhongzhibinbin/MallChat"><img src="https://img.shields.io/badge/码云-项目地址-orange.svg?style=plasticr"></a>
|
||||
<a href="https://github.com/Evansy/MallChatWeb"><img src="https://img.shields.io/badge/前端-项目地址-blueviolet.svg?style=plasticr"></a>
|
||||
</p>
|
||||
|
||||
@@ -16,9 +16,9 @@ MallChat的后端项目,是一个既能购物又能即时聊天的电商系统
|
||||
1. **快速体验地址**:[抹茶聊天首页](https://mallchat.cn)
|
||||
2. **前端项目仓库**:[MallChatWeb](https://github.com/Evansy/MallChatWeb)
|
||||
3. **项目视频记录**:[Bilibili地址](https://space.bilibili.com/146719540) 全程分享项目进度,功能选型的思考,同时征集迭代建议。
|
||||
4. **项目学习文档**:10w+字,保姆级教学路线,环境搭建、核心功能、基建轮子、接口压测、问题记录、一个不落。可点击[抹茶项目文档](https://www.yuque.com/snab/mallcaht)查看(内含500人交流大群)
|
||||
4. **项目学习文档**:10w+字,保姆级教学路线,环境搭建、核心功能、基建轮子、接口压测、问题记录、一个不落。可点击[抹茶项目文档](https://www.yuque.com/snab/planet/cef1mcko4fve0ur3)查看(内含500人交流大群)
|
||||
5. **项目交流群**:对抹茶感兴趣的,可以加入[交流群](#公众号)。你的每一个举动,都会决定项目未来的方向。无论是提意见做产品经理,还是找bug做个测试人员,又或者加入开发小模块成为contributer,都欢迎你的加入。
|
||||
6. **码云仓库**:[https://github.com/zongzibinbin/MallChat](https://github.com/zongzibinbin/MallChat) (国内访问速度更快)
|
||||
6. **码云仓库**:[https://gitee.com/zhongzhibinbin/MallChat](https://gitee.com/zhongzhibinbin/MallChat) (国内访问速度更快)
|
||||
|
||||
## 项目介绍
|
||||
|
||||
@@ -59,11 +59,11 @@ MallChat的后端项目,是一个既能购物又能即时聊天的电商系统
|
||||
|
||||
### 环境搭建
|
||||
|
||||
在项目目录下的`application.yml`修改自己的启动环境`spring.profiles.active` = `test`然后找到同级文件`application-test.properties`,填写自己的环境配置。[星球成员](https://www.yuque.com/snab/mallcaht)提供一套测试环境配置,可直连
|
||||
在项目目录下的`application.yml`修改自己的启动环境`spring.profiles.active` = `test`然后找到同级文件`application-test.properties`,填写自己的环境配置。[星球成员](https://www.yuque.com/snab/planet/cne0nel2hny8eu4i)提供一套测试环境配置,可直连
|
||||
|
||||
### 项目文档
|
||||
|
||||
保姆级教学路线,环境搭建、核心功能、基建轮子、接口压测、问题记录、项目亮点一个不落。点击[项目文档](https://www.yuque.com/snab/mallcaht)
|
||||
保姆级教学路线,环境搭建、核心功能、基建轮子、接口压测、问题记录、项目亮点一个不落。点击[项目文档](https://www.yuque.com/snab/planet/cef1mcko4fve0ur3)
|
||||
|
||||
更多有趣功能在持续更新中。。。
|
||||
|
||||
|
||||
@@ -145,4 +145,17 @@ CREATE TABLE `user_backpack` (
|
||||
INDEX `idx_update_time`(`update_time`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户背包表' ROW_FORMAT = Dynamic;
|
||||
|
||||
DROP TABLE IF EXISTS `wx_msg`;
|
||||
CREATE TABLE `wx_msg` (
|
||||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`open_id` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '微信openid用户标识',
|
||||
`msg` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户消息',
|
||||
`create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
`update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_open_id`(`open_id`) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time`) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信消息表' ROW_FORMAT = Dynamic;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.abin.mallchat.common.chat.dao;
|
||||
|
||||
import com.abin.mallchat.common.chat.domain.entity.WxMsg;
|
||||
import com.abin.mallchat.common.chat.mapper.WxMsgMapper;
|
||||
import com.abin.mallchat.common.chat.service.IWxMsgService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 微信消息表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* @since 2023-05-16
|
||||
*/
|
||||
@Service
|
||||
public class WxMsgDao extends ServiceImpl<WxMsgMapper, WxMsg> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.abin.mallchat.common.chat.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 微信消息表
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* @since 2023-05-16
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableName("wx_msg")
|
||||
public class WxMsg implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 微信openid用户标识
|
||||
*/
|
||||
@TableField("open_id")
|
||||
private String openId;
|
||||
|
||||
/**
|
||||
* 用户消息
|
||||
*/
|
||||
@TableField("msg")
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField("create_time")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField("update_time")
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.abin.mallchat.common.chat.mapper;
|
||||
|
||||
import com.abin.mallchat.common.chat.domain.entity.WxMsg;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 微信消息表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* @since 2023-05-16
|
||||
*/
|
||||
public interface WxMsgMapper extends BaseMapper<WxMsg> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.abin.mallchat.common.chat.service;
|
||||
|
||||
import com.abin.mallchat.common.chat.domain.entity.WxMsg;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 微信消息表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* @since 2023-05-16
|
||||
*/
|
||||
public interface IWxMsgService extends IService<WxMsg> {
|
||||
|
||||
}
|
||||
@@ -754,6 +754,9 @@ public class RedisUtils {
|
||||
public static Boolean zAdd(String key, Object value, double score) {
|
||||
return zAdd(key, value.toString(), score);
|
||||
}
|
||||
public static Boolean zIsMember(String key, Object value) {
|
||||
return Objects.nonNull(stringRedisTemplate.opsForZSet().score(key,value.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
|
||||
@@ -53,6 +53,11 @@ public class UserCache {
|
||||
RedisUtils.zAdd(onlineKey, uid, optTime.getTime());
|
||||
}
|
||||
|
||||
public boolean isOnline(Long uid) {
|
||||
String onlineKey = RedisKey.getKey(RedisKey.ONLINE_UID_ZET);
|
||||
return RedisUtils.zIsMember(onlineKey, uid);
|
||||
}
|
||||
|
||||
//用户下线
|
||||
public void offline(Long uid, Date optTime) {
|
||||
String onlineKey = RedisKey.getKey(RedisKey.ONLINE_UID_ZET);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.abin.mallchat.common.chat.mapper.WxMsgMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -85,7 +85,7 @@ public class ChatMessageResp {
|
||||
private Integer userDislike;
|
||||
}
|
||||
@Data
|
||||
private static class Badge {
|
||||
public static class Badge {
|
||||
@ApiModelProperty("徽章图像")
|
||||
private String img;
|
||||
@ApiModelProperty("徽章说明")
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.abin.mallchat.common.chat.domain.enums.MessageMarkTypeEnum;
|
||||
import com.abin.mallchat.common.chat.domain.enums.MessageStatusEnum;
|
||||
import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum;
|
||||
import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum;
|
||||
import com.abin.mallchat.common.user.domain.entity.ItemConfig;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMessageResp;
|
||||
@@ -35,11 +36,11 @@ public class MessageAdapter {
|
||||
|
||||
}
|
||||
|
||||
public static List<ChatMessageResp> buildMsgResp(List<Message> messages, Map<Long, Message> replyMap, Map<Long, User> userMap, List<MessageMark> msgMark, Long receiveUid) {
|
||||
public static List<ChatMessageResp> buildMsgResp(List<Message> messages, Map<Long, Message> replyMap, Map<Long, User> userMap, List<MessageMark> msgMark, Long receiveUid, Map<Long, ItemConfig> itemMap) {
|
||||
Map<Long, List<MessageMark>> markMap = msgMark.stream().collect(Collectors.groupingBy(MessageMark::getMsgId));
|
||||
return messages.stream().map(a -> {
|
||||
ChatMessageResp resp = new ChatMessageResp();
|
||||
resp.setFromUser(buildFromUser(userMap.get(a.getFromUid())));
|
||||
resp.setFromUser(buildFromUser(userMap.get(a.getFromUid()),itemMap));
|
||||
resp.setMessage(buildMessage(a, replyMap, userMap, markMap.getOrDefault(a.getId(), new ArrayList<>()), receiveUid));
|
||||
return resp;
|
||||
})
|
||||
@@ -80,11 +81,18 @@ public class MessageAdapter {
|
||||
return mark;
|
||||
}
|
||||
|
||||
private static ChatMessageResp.UserInfo buildFromUser(User fromUser) {
|
||||
private static ChatMessageResp.UserInfo buildFromUser(User fromUser, Map<Long, ItemConfig> itemMap) {
|
||||
ChatMessageResp.UserInfo userInfo = new ChatMessageResp.UserInfo();
|
||||
userInfo.setUsername(fromUser.getName());
|
||||
userInfo.setAvatar(fromUser.getAvatar());
|
||||
userInfo.setUid(fromUser.getId());
|
||||
if(Objects.nonNull(fromUser.getItemId())){
|
||||
ChatMessageResp.Badge badge =new ChatMessageResp.Badge();
|
||||
ItemConfig itemConfig = itemMap.get(fromUser.getItemId());
|
||||
badge.setImg(itemConfig.getImg());
|
||||
badge.setDescribe(itemConfig.getDescribe());
|
||||
userInfo.setBadge(badge);
|
||||
}
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,10 @@ import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
|
||||
import com.abin.mallchat.common.common.exception.BusinessException;
|
||||
import com.abin.mallchat.common.common.utils.AssertUtil;
|
||||
import com.abin.mallchat.common.user.dao.UserDao;
|
||||
import com.abin.mallchat.common.user.domain.entity.ItemConfig;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
import com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum;
|
||||
import com.abin.mallchat.common.user.service.cache.ItemCache;
|
||||
import com.abin.mallchat.common.user.service.cache.UserCache;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageMarkReq;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessagePageReq;
|
||||
@@ -69,6 +71,8 @@ public class ChatServiceImpl implements ChatService {
|
||||
private RoomDao roomDao;
|
||||
@Autowired
|
||||
private MessageMarkDao messageMarkDao;
|
||||
@Autowired
|
||||
private ItemCache itemCache;
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
@@ -209,7 +213,8 @@ public class ChatServiceImpl implements ChatService {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Map<Long, Message> replyMap = new HashMap<>();
|
||||
Map<Long, User> userMap = new HashMap<>();
|
||||
Map<Long, User> userMap;
|
||||
Map<Long, ItemConfig> itemMap;
|
||||
//批量查出回复的消息
|
||||
List<Long> replyIds = messages.stream().map(Message::getReplyMsgId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
|
||||
if (CollectionUtil.isNotEmpty(replyIds)) {
|
||||
@@ -218,9 +223,11 @@ public class ChatServiceImpl implements ChatService {
|
||||
//批量查询消息关联用户
|
||||
Set<Long> uidSet = Stream.concat(replyMap.values().stream().map(Message::getFromUid), messages.stream().map(Message::getFromUid)).collect(Collectors.toSet());
|
||||
userMap = userCache.getUserInfoBatch(uidSet);
|
||||
//批量查询item信息
|
||||
itemMap = userMap.values().stream().map(User::getItemId).distinct().filter(Objects::nonNull).map(itemCache::getById).collect(Collectors.toMap(ItemConfig::getId,Function.identity()));
|
||||
//查询消息标志
|
||||
List<MessageMark> msgMark = messageMarkDao.getValidMarkByMsgIdBatch(messages.stream().map(Message::getId).collect(Collectors.toList()));
|
||||
return MessageAdapter.buildMsgResp(messages, replyMap, userMap, msgMark, receiveUid);
|
||||
return MessageAdapter.buildMsgResp(messages, replyMap, userMap, msgMark, receiveUid,itemMap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class UserOnlineListener {
|
||||
User user = event.getUser();
|
||||
userCache.online(user.getId(), user.getLastOptTime());
|
||||
//推送给所有在线用户,该用户登录成功
|
||||
webSocketService.sendToAllOnline(wsAdapter.buildOnlineNotifyResp(event.getUser()), event.getUser().getId());
|
||||
webSocketService.sendToAllOnline(wsAdapter.buildOnlineNotifyResp(event.getUser()), null);
|
||||
}
|
||||
|
||||
@Async
|
||||
|
||||
@@ -59,7 +59,7 @@ public class WxPortalController {
|
||||
log.error("callBack error",e);
|
||||
}
|
||||
RedirectView redirectView = new RedirectView();
|
||||
redirectView.setUrl("https://mp.weixin.qq.com/s/MKCWzoCIzvh5G_1sK5sLoA");
|
||||
redirectView.setUrl("https://mp.weixin.qq.com/s/m1SRsBG96kLJW5mPe4AVGA");
|
||||
return redirectView;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ public class BadgeResp {
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "徽章图标")
|
||||
private String image;
|
||||
private String img;
|
||||
|
||||
@ApiModelProperty(value = "徽章描述")
|
||||
private String describe;
|
||||
|
||||
@@ -91,7 +91,9 @@ public class WxMsgService {
|
||||
public void authorize(WxOAuth2UserInfo userInfo) {
|
||||
User user = userDao.getByOpenId(userInfo.getOpenid());
|
||||
//更新用户信息
|
||||
fillUserInfo(user.getId(), userInfo);
|
||||
if(Objects.isNull(user.getName())){
|
||||
fillUserInfo(user.getId(), userInfo);
|
||||
}
|
||||
//触发用户登录成功操作
|
||||
Integer eventKey = OPENID_EVENT_CODE_MAP.get(userInfo.getOpenid());
|
||||
login(user.getId(), eventKey);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.abin.mallchat.custom.user.service.handler;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.abin.mallchat.common.chat.dao.WxMsgDao;
|
||||
import com.abin.mallchat.common.chat.domain.entity.WxMsg;
|
||||
import com.abin.mallchat.custom.user.service.adapter.TextBuilder;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
@@ -9,6 +11,7 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -21,12 +24,18 @@ import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
|
||||
@Component
|
||||
public class MsgHandler extends AbstractHandler {
|
||||
|
||||
@Autowired
|
||||
private WxMsgDao wxMsgDao;
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService weixinService,
|
||||
WxSessionManager sessionManager) {
|
||||
if (true) {
|
||||
return WxMpXmlOutMessage.TEXT().build();
|
||||
WxMsg msg =new WxMsg();
|
||||
msg.setOpenId(wxMessage.getFromUser());
|
||||
msg.setMsg(wxMessage.getContent());
|
||||
wxMsgDao.save(msg);
|
||||
return null;
|
||||
}
|
||||
if (!wxMessage.getMsgType().equals(XmlMsgType.EVENT)) {
|
||||
//可以选择将消息保存到本地
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.abin.mallchat.common.common.config.ThreadPoolConfig;
|
||||
import com.abin.mallchat.common.user.dao.UserDao;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
import com.abin.mallchat.common.common.event.UserOfflineEvent;
|
||||
import com.abin.mallchat.common.user.service.cache.UserCache;
|
||||
import com.abin.mallchat.custom.user.domain.dto.ws.WSChannelExtraDTO;
|
||||
import com.abin.mallchat.custom.user.domain.vo.request.ws.WSAuthorize;
|
||||
import com.abin.mallchat.custom.user.domain.vo.response.ws.WSBaseResp;
|
||||
@@ -51,7 +52,8 @@ public class WebSocketServiceImpl implements WebSocketService {
|
||||
* 所有已连接的websocket连接列表和一些额外参数
|
||||
*/
|
||||
private static final ConcurrentHashMap<Channel, WSChannelExtraDTO> ONLINE_WS_MAP = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<Channel, WSChannelExtraDTO> getOnlineMap(){
|
||||
|
||||
public static ConcurrentHashMap<Channel, WSChannelExtraDTO> getOnlineMap() {
|
||||
return ONLINE_WS_MAP;
|
||||
}
|
||||
|
||||
@@ -67,6 +69,8 @@ public class WebSocketServiceImpl implements WebSocketService {
|
||||
@Autowired
|
||||
@Qualifier(ThreadPoolConfig.WS_EXECUTOR)
|
||||
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
|
||||
@Autowired
|
||||
private UserCache userCache;
|
||||
|
||||
/**
|
||||
* 处理用户登录请求,需要返回一张带code的二维码
|
||||
@@ -144,12 +148,14 @@ public class WebSocketServiceImpl implements WebSocketService {
|
||||
//返回给用户登录成功
|
||||
sendMsg(channel, WSAdapter.buildLoginSuccessResp(user, token));
|
||||
//发送用户上线事件
|
||||
user.setLastOptTime(new Date());
|
||||
user.getIpInfo().refreshIp(NettyUtil.getAttr(channel, NettyUtil.IP));
|
||||
applicationEventPublisher.publishEvent(new UserOnlineEvent(this, user));
|
||||
boolean online = userCache.isOnline(user.getId());
|
||||
if (!online) {
|
||||
user.setLastOptTime(new Date());
|
||||
user.getIpInfo().refreshIp(NettyUtil.getAttr(channel, NettyUtil.IP));
|
||||
applicationEventPublisher.publishEvent(new UserOnlineEvent(this, user));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用户上线
|
||||
*/
|
||||
|
||||
@@ -86,17 +86,18 @@ public class NettyWebSocketServerHandler extends SimpleChannelInboundHandler<Tex
|
||||
// 读取客户端发送的请求报文
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
|
||||
log.info("服务器端收到消息 = " + msg.text());
|
||||
WSBaseReq wsBaseReq = JSONUtil.toBean(msg.text(), WSBaseReq.class);
|
||||
WSReqTypeEnum wsReqTypeEnum = WSReqTypeEnum.of(wsBaseReq.getType());
|
||||
switch (wsReqTypeEnum) {
|
||||
case LOGIN:
|
||||
getService().handleLoginReq(ctx.channel());
|
||||
log.info("请求二维码 = " + msg.text());
|
||||
break;
|
||||
case HEARTBEAT:
|
||||
break;
|
||||
case AUTHORIZE:
|
||||
getService().authorize(ctx.channel(), JSONUtil.toBean(wsBaseReq.getData(), WSAuthorize.class));
|
||||
log.info("主动认证 = " + msg.text());
|
||||
default:
|
||||
log.info("未知类型");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user