mirror of
https://github.com/zongzibinbin/MallChat.git
synced 2026-03-15 23:23:43 +08:00
feat:
1.搭建分布式事务框架 2.项目引入rocketmq实现集群广播
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
package com.abin.mallchat.custom.chat.consumer;
|
||||
|
||||
import com.abin.mallchat.common.chat.dao.ContactDao;
|
||||
import com.abin.mallchat.common.chat.dao.MessageDao;
|
||||
import com.abin.mallchat.common.chat.dao.RoomDao;
|
||||
import com.abin.mallchat.common.chat.dao.RoomFriendDao;
|
||||
import com.abin.mallchat.common.chat.domain.entity.Message;
|
||||
import com.abin.mallchat.common.chat.domain.entity.Room;
|
||||
import com.abin.mallchat.common.chat.domain.entity.RoomFriend;
|
||||
import com.abin.mallchat.common.chat.domain.enums.RoomTypeEnum;
|
||||
import com.abin.mallchat.common.chat.domain.vo.response.ChatMessageResp;
|
||||
import com.abin.mallchat.common.chat.service.cache.GroupMemberCache;
|
||||
import com.abin.mallchat.common.chat.service.cache.HotRoomCache;
|
||||
import com.abin.mallchat.common.chat.service.cache.RoomCache;
|
||||
import com.abin.mallchat.common.common.constant.MQConstant;
|
||||
import com.abin.mallchat.common.common.domain.dto.MsgSendMessageDTO;
|
||||
import com.abin.mallchat.common.user.service.cache.UserCache;
|
||||
import com.abin.mallchat.common.user.service.impl.PushService;
|
||||
import com.abin.mallchat.custom.chat.service.ChatService;
|
||||
import com.abin.mallchat.custom.chat.service.WeChatMsgOperationService;
|
||||
import com.abin.mallchat.custom.chatai.service.IChatAIService;
|
||||
import com.abin.mallchat.custom.user.service.WebSocketService;
|
||||
import com.abin.mallchat.custom.user.service.adapter.WSAdapter;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Description: 发送消息更新房间收信箱,并同步给房间成员信箱
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-08-12
|
||||
*/
|
||||
@RocketMQMessageListener(consumerGroup = MQConstant.SEND_MSG_GROUP, topic = MQConstant.SEND_MSG_TOPIC)
|
||||
@Component
|
||||
public class MsgSendConsumer implements RocketMQListener<MsgSendMessageDTO> {
|
||||
@Autowired
|
||||
private WebSocketService webSocketService;
|
||||
@Autowired
|
||||
private ChatService chatService;
|
||||
@Autowired
|
||||
private MessageDao messageDao;
|
||||
@Autowired
|
||||
private IChatAIService openAIService;
|
||||
@Autowired
|
||||
WeChatMsgOperationService weChatMsgOperationService;
|
||||
@Autowired
|
||||
private RoomCache roomCache;
|
||||
@Autowired
|
||||
private RoomDao roomDao;
|
||||
@Autowired
|
||||
private GroupMemberCache groupMemberCache;
|
||||
@Autowired
|
||||
private UserCache userCache;
|
||||
@Autowired
|
||||
private RoomFriendDao roomFriendDao;
|
||||
@Autowired
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
@Autowired
|
||||
private ContactDao contactDao;
|
||||
@Autowired
|
||||
private HotRoomCache hotRoomCache;
|
||||
@Autowired
|
||||
private PushService pushService;
|
||||
|
||||
@Override
|
||||
public void onMessage(MsgSendMessageDTO dto) {
|
||||
Message message = messageDao.getById(dto.getMsgId());
|
||||
Room room = roomCache.get(message.getRoomId());
|
||||
ChatMessageResp msgResp = chatService.getMsgResp(message, null);
|
||||
//所有房间更新房间最新消息
|
||||
roomDao.refreshActiveTime(room.getId(), message.getId(), message.getCreateTime());
|
||||
roomCache.delete(room.getId());
|
||||
if (room.isHotRoom()) {//热门群聊推送所有在线的人
|
||||
//更新热门群聊时间-redis
|
||||
hotRoomCache.refreshActiveTime(room.getId(), message.getCreateTime());
|
||||
//推送所有人
|
||||
pushService.sendPushMsg(WSAdapter.buildMsgSend(msgResp));
|
||||
} else {
|
||||
List<Long> memberUidList = new ArrayList<>();
|
||||
if (Objects.equals(room.getType(), RoomTypeEnum.GROUP.getType())) {//普通群聊推送所有群成员
|
||||
memberUidList = groupMemberCache.getMemberUidList(room.getId());
|
||||
} else if (Objects.equals(room.getType(), RoomTypeEnum.FRIEND.getType())) {//单聊对象
|
||||
//对单人推送
|
||||
RoomFriend roomFriend = roomFriendDao.getByRoomId(room.getId());
|
||||
memberUidList = Arrays.asList(roomFriend.getUid1(), roomFriend.getUid2());
|
||||
}
|
||||
//更新所有群成员的会话时间
|
||||
contactDao.refreshOrCreateActiveTime(room.getId(), memberUidList, message.getId(), message.getCreateTime());
|
||||
//推送房间成员
|
||||
pushService.sendPushMsg(WSAdapter.buildMsgSend(msgResp), memberUidList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public class ChatController {
|
||||
private UserCache userCache;
|
||||
|
||||
@GetMapping("/public/member/page")
|
||||
@ApiOperation("群成员列表")
|
||||
@ApiOperation("群成员列表(废弃)")
|
||||
@Deprecated
|
||||
@FrequencyControl(time = 120, count = 20, target = FrequencyControl.Target.IP)
|
||||
public ApiResult<CursorPageBaseResp<ChatMemberResp>> getMemberPage(@Valid MemberReq request) {
|
||||
@@ -56,7 +56,7 @@ public class ChatController {
|
||||
}
|
||||
|
||||
@GetMapping("/member/list")
|
||||
@ApiOperation("房间内的所有群成员列表-@专用")
|
||||
@ApiOperation("房间内的所有群成员列表-@专用(废弃)")
|
||||
@Deprecated
|
||||
public ApiResult<List<ChatMemberListResp>> getMemberList(@Valid ChatMessageMemberReq chatMessageMemberReq) {
|
||||
return ApiResult.success(chatService.getMemberList(chatMessageMemberReq));
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.abin.mallchat.custom.chat.service.strategy.mark.MsgMarkFactory;
|
||||
import com.abin.mallchat.custom.chat.service.strategy.msg.AbstractMsgHandler;
|
||||
import com.abin.mallchat.custom.chat.service.strategy.msg.MsgHandlerFactory;
|
||||
import com.abin.mallchat.custom.chat.service.strategy.msg.RecallMsgHandler;
|
||||
import com.abin.mallchat.transaction.service.MQProducer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -93,6 +94,8 @@ public class ChatServiceImpl implements ChatService {
|
||||
private GroupMemberDao groupMemberDao;
|
||||
@Autowired
|
||||
private RoomGroupCache roomGroupCache;
|
||||
@Autowired
|
||||
private MQProducer mqProducer;
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
@@ -149,7 +152,7 @@ public class ChatServiceImpl implements ChatService {
|
||||
List<ChatMemberResp> resultList = new ArrayList<>();//最终列表
|
||||
Boolean isLast = Boolean.FALSE;
|
||||
if (activeStatusEnum == ChatActiveStatusEnum.ONLINE) {//在线列表
|
||||
CursorPageBaseResp<User> cursorPage = userDao.getCursorPage(memberUidList, request, ChatActiveStatusEnum.ONLINE);
|
||||
CursorPageBaseResp<User> cursorPage = userDao.getCursorPage(memberUidList, new CursorPageBaseReq(request.getPageSize(), timeCursor), ChatActiveStatusEnum.ONLINE);
|
||||
resultList.addAll(MemberAdapter.buildMember(cursorPage.getList()));//添加在线列表
|
||||
if (cursorPage.getIsLast()) {//如果是最后一页,从离线列表再补点数据
|
||||
activeStatusEnum = ChatActiveStatusEnum.OFFLINE;
|
||||
@@ -160,7 +163,7 @@ public class ChatServiceImpl implements ChatService {
|
||||
timeCursor = cursorPage.getCursor();
|
||||
isLast = cursorPage.getIsLast();
|
||||
} else if (activeStatusEnum == ChatActiveStatusEnum.OFFLINE) {//离线列表
|
||||
CursorPageBaseResp<User> cursorPage = userDao.getCursorPage(memberUidList, request, ChatActiveStatusEnum.OFFLINE);
|
||||
CursorPageBaseResp<User> cursorPage = userDao.getCursorPage(memberUidList, new CursorPageBaseReq(request.getPageSize(), timeCursor), ChatActiveStatusEnum.OFFLINE);
|
||||
resultList.addAll(MemberAdapter.buildMember(cursorPage.getList()));//添加离线线列表
|
||||
timeCursor = cursorPage.getCursor();
|
||||
isLast = cursorPage.getIsLast();
|
||||
@@ -171,13 +174,26 @@ public class ChatServiceImpl implements ChatService {
|
||||
|
||||
@Override
|
||||
public CursorPageBaseResp<ChatMessageResp> getMsgPage(ChatMessagePageReq request, Long receiveUid) {
|
||||
CursorPageBaseResp<Message> cursorPage = messageDao.getCursorPage(request.getRoomId(), request);
|
||||
//用最后一条消息id,来限制被踢出的人能看见的最大一条消息
|
||||
Long lastMsgId = getLastMsgId(request.getRoomId(), receiveUid);
|
||||
CursorPageBaseResp<Message> cursorPage = messageDao.getCursorPage(request.getRoomId(), request, lastMsgId);
|
||||
if (cursorPage.isEmpty()) {
|
||||
return CursorPageBaseResp.empty();
|
||||
}
|
||||
return CursorPageBaseResp.init(cursorPage, getMsgRespBatch(cursorPage.getList(), receiveUid));
|
||||
}
|
||||
|
||||
private Long getLastMsgId(Long roomId, Long receiveUid) {
|
||||
Room room = roomCache.get(roomId);
|
||||
AssertUtil.isNotEmpty(room, "房间号有误");
|
||||
if (room.isHotRoom()) {
|
||||
return null;
|
||||
}
|
||||
AssertUtil.isNotEmpty(receiveUid, "请先登录");
|
||||
Contact contact = contactDao.get(receiveUid, roomId);
|
||||
return contact.getLastMsgId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatMemberStatisticResp getMemberStatistic() {
|
||||
System.out.println(Thread.currentThread().getName());
|
||||
|
||||
@@ -17,7 +17,6 @@ import com.abin.mallchat.common.common.annotation.RedissonLock;
|
||||
import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
|
||||
import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
|
||||
import com.abin.mallchat.common.common.event.GroupMemberAddEvent;
|
||||
import com.abin.mallchat.common.common.event.WSPushEvent;
|
||||
import com.abin.mallchat.common.common.utils.AssertUtil;
|
||||
import com.abin.mallchat.common.user.dao.UserDao;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
@@ -28,6 +27,7 @@ import com.abin.mallchat.common.user.domain.vo.response.ws.WSMemberChange;
|
||||
import com.abin.mallchat.common.user.service.IRoleService;
|
||||
import com.abin.mallchat.common.user.service.cache.UserCache;
|
||||
import com.abin.mallchat.common.user.service.cache.UserInfoCache;
|
||||
import com.abin.mallchat.common.user.service.impl.PushService;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.enums.GroupRoleAPPEnum;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.request.*;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMemberListResp;
|
||||
@@ -90,18 +90,20 @@ public class RoomAppServiceImpl implements RoomAppService {
|
||||
private RoomService roomService;
|
||||
@Autowired
|
||||
private GroupMemberCache groupMemberCache;
|
||||
@Autowired
|
||||
private PushService pushService;
|
||||
|
||||
@Override
|
||||
public CursorPageBaseResp<ChatRoomResp> getContactPage(CursorPageBaseReq request, Long uid) {
|
||||
//查出用户要展示的会话列表
|
||||
CursorPageBaseResp<Long> page;
|
||||
if (Objects.nonNull(uid)) {
|
||||
Double hotStart = getCursorOrNull(request.getCursor());
|
||||
Double hotEnd;
|
||||
Double hotEnd = getCursorOrNull(request.getCursor());
|
||||
Double hotStart;
|
||||
//用户基础会话
|
||||
CursorPageBaseResp<Contact> contactPage = contactDao.getContactPage(uid, request);
|
||||
List<Long> baseRoomIds = contactPage.getList().stream().map(Contact::getRoomId).collect(Collectors.toList());
|
||||
hotEnd = getCursorOrNull(contactPage.getCursor());
|
||||
hotStart = getCursorOrNull(contactPage.getCursor());
|
||||
//热门房间
|
||||
Set<ZSetOperations.TypedTuple<String>> typedTuples = hotRoomCache.getRoomRange(hotStart, hotEnd);
|
||||
List<Long> hotRoomIds = typedTuples.stream().map(ZSetOperations.TypedTuple::getValue).filter(Objects::nonNull).map(Long::parseLong).collect(Collectors.toList());
|
||||
@@ -193,7 +195,7 @@ public class RoomAppServiceImpl implements RoomAppService {
|
||||
//发送移除事件告知群成员
|
||||
List<Long> memberUidList = groupMemberCache.getMemberUidList(roomGroup.getRoomId());
|
||||
WSBaseResp<WSMemberChange> ws = MemberAdapter.buildMemberRemoveWS(roomGroup.getRoomId(), member.getUid());
|
||||
applicationEventPublisher.publishEvent(new WSPushEvent(this, memberUidList, ws));
|
||||
pushService.sendPushMsg(ws, memberUidList);
|
||||
groupMemberCache.evictMemberUidList(member.getId());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.abin.mallchat.custom.chatai.utils;
|
||||
|
||||
import com.abin.mallchat.common.common.exception.BusinessException;
|
||||
import com.abin.mallchat.common.common.utils.JsonUtils;
|
||||
import com.abin.mallchat.custom.chatai.domain.ChatGPTMsg;
|
||||
import com.abin.mallchat.utils.JsonUtils;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.knuddels.jtokkit.Encodings;
|
||||
import com.knuddels.jtokkit.api.Encoding;
|
||||
|
||||
@@ -6,12 +6,12 @@ import com.abin.mallchat.common.chat.domain.entity.RoomGroup;
|
||||
import com.abin.mallchat.common.chat.service.cache.GroupMemberCache;
|
||||
import com.abin.mallchat.common.chat.service.cache.MsgCache;
|
||||
import com.abin.mallchat.common.common.event.GroupMemberAddEvent;
|
||||
import com.abin.mallchat.common.common.event.WSPushEvent;
|
||||
import com.abin.mallchat.common.user.dao.UserDao;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
import com.abin.mallchat.common.user.domain.enums.WSBaseResp;
|
||||
import com.abin.mallchat.common.user.domain.vo.response.ws.WSMemberChange;
|
||||
import com.abin.mallchat.common.user.service.cache.UserInfoCache;
|
||||
import com.abin.mallchat.common.user.service.impl.PushService;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
|
||||
import com.abin.mallchat.custom.chat.service.ChatService;
|
||||
import com.abin.mallchat.custom.chat.service.adapter.MemberAdapter;
|
||||
@@ -51,6 +51,8 @@ public class GroupMemberAddListener {
|
||||
private UserDao userDao;
|
||||
@Autowired
|
||||
private GroupMemberCache groupMemberCache;
|
||||
@Autowired
|
||||
private PushService pushService;
|
||||
|
||||
|
||||
@Async
|
||||
@@ -66,7 +68,6 @@ public class GroupMemberAddListener {
|
||||
}
|
||||
|
||||
@Async
|
||||
|
||||
@TransactionalEventListener(classes = GroupMemberAddEvent.class, fallbackExecution = true)
|
||||
public void sendChangePush(GroupMemberAddEvent event) {
|
||||
List<GroupMember> memberList = event.getMemberList();
|
||||
@@ -76,7 +77,7 @@ public class GroupMemberAddListener {
|
||||
List<User> users = userDao.listByIds(uidList);
|
||||
users.forEach(user -> {
|
||||
WSBaseResp<WSMemberChange> ws = MemberAdapter.buildMemberAddWS(roomGroup.getRoomId(), user);
|
||||
applicationEventPublisher.publishEvent(new WSPushEvent(this, memberUidList, ws));
|
||||
pushService.sendPushMsg(ws, memberUidList);
|
||||
});
|
||||
//移除缓存
|
||||
groupMemberCache.evictMemberUidList(roomGroup.getRoomId());
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.abin.mallchat.custom.common.event.listener;
|
||||
import com.abin.mallchat.common.chat.domain.dto.ChatMsgRecallDTO;
|
||||
import com.abin.mallchat.common.chat.service.cache.MsgCache;
|
||||
import com.abin.mallchat.common.common.event.MessageRecallEvent;
|
||||
import com.abin.mallchat.common.user.service.impl.PushService;
|
||||
import com.abin.mallchat.custom.chat.service.ChatService;
|
||||
import com.abin.mallchat.custom.user.service.WebSocketService;
|
||||
import com.abin.mallchat.custom.user.service.adapter.WSAdapter;
|
||||
@@ -26,6 +27,8 @@ public class MessageRecallListener {
|
||||
private ChatService chatService;
|
||||
@Autowired
|
||||
private MsgCache msgCache;
|
||||
@Autowired
|
||||
private PushService pushService;
|
||||
|
||||
@Async
|
||||
@TransactionalEventListener(classes = MessageRecallEvent.class, fallbackExecution = true)
|
||||
@@ -37,7 +40,7 @@ public class MessageRecallListener {
|
||||
@Async
|
||||
@TransactionalEventListener(classes = MessageRecallEvent.class, fallbackExecution = true)
|
||||
public void sendToAll(MessageRecallEvent event) {
|
||||
webSocketService.sendToAllOnline(WSAdapter.buildMsgRecall(event.getRecallDTO()));
|
||||
pushService.sendPushMsg(WSAdapter.buildMsgRecall(event.getRecallDTO()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,33 +6,28 @@ import com.abin.mallchat.common.chat.dao.RoomDao;
|
||||
import com.abin.mallchat.common.chat.dao.RoomFriendDao;
|
||||
import com.abin.mallchat.common.chat.domain.entity.Message;
|
||||
import com.abin.mallchat.common.chat.domain.entity.Room;
|
||||
import com.abin.mallchat.common.chat.domain.entity.RoomFriend;
|
||||
import com.abin.mallchat.common.chat.domain.enums.HotFlagEnum;
|
||||
import com.abin.mallchat.common.chat.domain.enums.RoomTypeEnum;
|
||||
import com.abin.mallchat.common.chat.domain.vo.response.ChatMessageResp;
|
||||
import com.abin.mallchat.common.chat.service.cache.GroupMemberCache;
|
||||
import com.abin.mallchat.common.chat.service.cache.HotRoomCache;
|
||||
import com.abin.mallchat.common.chat.service.cache.RoomCache;
|
||||
import com.abin.mallchat.common.common.constant.MQConstant;
|
||||
import com.abin.mallchat.common.common.domain.dto.MsgSendMessageDTO;
|
||||
import com.abin.mallchat.common.common.event.MessageSendEvent;
|
||||
import com.abin.mallchat.common.common.event.WSPushEvent;
|
||||
import com.abin.mallchat.common.user.service.cache.UserCache;
|
||||
import com.abin.mallchat.custom.chat.service.ChatService;
|
||||
import com.abin.mallchat.custom.chat.service.WeChatMsgOperationService;
|
||||
import com.abin.mallchat.custom.chatai.service.IChatAIService;
|
||||
import com.abin.mallchat.custom.user.service.WebSocketService;
|
||||
import com.abin.mallchat.custom.user.service.adapter.WSAdapter;
|
||||
import com.abin.mallchat.transaction.service.MQProducer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.event.TransactionPhase;
|
||||
import org.springframework.transaction.event.TransactionalEventListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -69,35 +64,13 @@ public class MessageSendListener {
|
||||
private ContactDao contactDao;
|
||||
@Autowired
|
||||
private HotRoomCache hotRoomCache;
|
||||
@Autowired
|
||||
private MQProducer mqProducer;
|
||||
|
||||
@Async
|
||||
@TransactionalEventListener(classes = MessageSendEvent.class, fallbackExecution = true)
|
||||
@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT, classes = MessageSendEvent.class, fallbackExecution = true)
|
||||
public void messageRoute(MessageSendEvent event) {
|
||||
Message message = messageDao.getById(event.getMsgId());
|
||||
Room room = roomCache.get(message.getRoomId());
|
||||
ChatMessageResp msgResp = chatService.getMsgResp(message, null);
|
||||
//更新房间最新消息
|
||||
roomDao.refreshActiveTime(room.getId(), message.getId(), message.getCreateTime());
|
||||
roomCache.delete(room.getId());
|
||||
if (isHotRoom(room)) {//热门群聊推送所有在线的人
|
||||
//更新热门群聊列表
|
||||
hotRoomCache.refreshActiveTime(room.getId(), message.getCreateTime());
|
||||
//推送所有人
|
||||
applicationEventPublisher.publishEvent(new WSPushEvent(this, WSAdapter.buildMsgSend(msgResp)));
|
||||
} else {
|
||||
List<Long> memberUidList = new ArrayList<>();
|
||||
if (Objects.equals(room.getType(), RoomTypeEnum.GROUP.getType())) {//普通群聊推送所有群成员
|
||||
memberUidList = groupMemberCache.getMemberUidList(room.getId());
|
||||
} else if (Objects.equals(room.getType(), RoomTypeEnum.FRIEND.getType())) {//单聊对象
|
||||
//对单人推送
|
||||
RoomFriend roomFriend = roomFriendDao.getByRoomId(room.getId());
|
||||
memberUidList = Arrays.asList(roomFriend.getUid1(), roomFriend.getUid2());
|
||||
}
|
||||
//更新所有群成员的会话时间
|
||||
contactDao.refreshOrCreateActiveTime(room.getId(), memberUidList, message.getId(), message.getCreateTime());
|
||||
//推送房间成员
|
||||
applicationEventPublisher.publishEvent(new WSPushEvent(this, memberUidList, WSAdapter.buildMsgSend(msgResp)));
|
||||
}
|
||||
Long msgId = event.getMsgId();
|
||||
mqProducer.sendSecureMsg(MQConstant.SEND_MSG_TOPIC, new MsgSendMessageDTO(msgId), msgId);
|
||||
}
|
||||
|
||||
@TransactionalEventListener(classes = MessageSendEvent.class, fallbackExecution = true)
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.abin.mallchat.common.common.event.UserApplyEvent;
|
||||
import com.abin.mallchat.common.user.dao.UserApplyDao;
|
||||
import com.abin.mallchat.common.user.domain.entity.UserApply;
|
||||
import com.abin.mallchat.common.user.domain.vo.response.ws.WSFriendApply;
|
||||
import com.abin.mallchat.common.user.service.impl.PushService;
|
||||
import com.abin.mallchat.custom.user.service.WebSocketService;
|
||||
import com.abin.mallchat.custom.user.service.adapter.WSAdapter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -25,12 +26,15 @@ public class UserApplyListener {
|
||||
@Autowired
|
||||
private WebSocketService webSocketService;
|
||||
|
||||
@Autowired
|
||||
private PushService pushService;
|
||||
|
||||
@Async
|
||||
@TransactionalEventListener(classes = UserApplyEvent.class, fallbackExecution = true)
|
||||
public void notifyFriend(UserApplyEvent event) {
|
||||
UserApply userApply = event.getUserApply();
|
||||
Integer unReadCount = userApplyDao.getUnReadCount(userApply.getTargetId());
|
||||
webSocketService.sendToUid(WSAdapter.buildApplySend(new WSFriendApply(userApply.getUid(), unReadCount)), userApply.getTargetId());
|
||||
pushService.sendPushMsg(WSAdapter.buildApplySend(new WSFriendApply(userApply.getUid(), unReadCount)), userApply.getTargetId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ 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.IpService;
|
||||
import com.abin.mallchat.common.user.service.cache.UserCache;
|
||||
import com.abin.mallchat.common.user.service.impl.PushService;
|
||||
import com.abin.mallchat.custom.user.service.WebSocketService;
|
||||
import com.abin.mallchat.custom.user.service.adapter.WSAdapter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -32,6 +33,8 @@ public class UserOnlineListener {
|
||||
private WSAdapter wsAdapter;
|
||||
@Autowired
|
||||
private IpService ipService;
|
||||
@Autowired
|
||||
private PushService pushService;
|
||||
|
||||
@Async
|
||||
@EventListener(classes = UserOnlineEvent.class)
|
||||
@@ -39,7 +42,7 @@ public class UserOnlineListener {
|
||||
User user = event.getUser();
|
||||
userCache.online(user.getId(), user.getLastOptTime());
|
||||
//推送给所有在线用户,该用户登录成功
|
||||
webSocketService.sendToAllOnline(wsAdapter.buildOnlineNotifyResp(event.getUser()));
|
||||
pushService.sendPushMsg(wsAdapter.buildOnlineNotifyResp(event.getUser()));
|
||||
}
|
||||
|
||||
@Async
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.abin.mallchat.custom.common.event.listener;
|
||||
|
||||
import com.abin.mallchat.common.common.event.WSPushEvent;
|
||||
import com.abin.mallchat.common.user.domain.enums.WSPushTypeEnum;
|
||||
import com.abin.mallchat.custom.user.service.WebSocketService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.event.TransactionalEventListener;
|
||||
|
||||
/**
|
||||
* 好友申请监听器
|
||||
*
|
||||
* @author zhongzb create on 2022/08/26
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class WSPushListener {
|
||||
@Autowired
|
||||
private WebSocketService webSocketService;
|
||||
|
||||
@Async
|
||||
@TransactionalEventListener(classes = WSPushEvent.class, fallbackExecution = true)
|
||||
public void wsPush(WSPushEvent event) {
|
||||
WSPushTypeEnum wsPushTypeEnum = WSPushTypeEnum.of(event.getPushType());
|
||||
switch (wsPushTypeEnum) {
|
||||
case USER:
|
||||
webSocketService.sendToUidList(event.getWsBaseMsg(), event.getUidList());
|
||||
break;
|
||||
case ALL:
|
||||
webSocketService.sendToAllOnline(event.getWsBaseMsg(), null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.abin.mallchat.custom.user.consumer;
|
||||
|
||||
import com.abin.mallchat.common.common.constant.MQConstant;
|
||||
import com.abin.mallchat.common.common.domain.dto.PushMessageDTO;
|
||||
import com.abin.mallchat.common.user.domain.enums.WSPushTypeEnum;
|
||||
import com.abin.mallchat.custom.user.service.WebSocketService;
|
||||
import org.apache.rocketmq.spring.annotation.MessageModel;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-08-12
|
||||
*/
|
||||
@RocketMQMessageListener(topic = MQConstant.PUSH_TOPIC, consumerGroup = MQConstant.PUSH_GROUP, messageModel = MessageModel.BROADCASTING)
|
||||
@Component
|
||||
public class PushConsumer implements RocketMQListener<PushMessageDTO> {
|
||||
@Autowired
|
||||
private WebSocketService webSocketService;
|
||||
|
||||
@Override
|
||||
public void onMessage(PushMessageDTO message) {
|
||||
WSPushTypeEnum wsPushTypeEnum = WSPushTypeEnum.of(message.getPushType());
|
||||
switch (wsPushTypeEnum) {
|
||||
case USER:
|
||||
webSocketService.sendToUid(message.getWsBaseMsg(), message.getUid());
|
||||
break;
|
||||
case ALL:
|
||||
webSocketService.sendToAllOnline(message.getWsBaseMsg(), null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,6 @@ import com.abin.mallchat.common.user.domain.enums.WSBaseResp;
|
||||
import com.abin.mallchat.common.user.domain.vo.request.ws.WSAuthorize;
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface WebSocketService {
|
||||
/**
|
||||
* 处理用户登录请求,需要返回一张带code的二维码
|
||||
@@ -70,7 +68,4 @@ public interface WebSocketService {
|
||||
|
||||
void sendToUid(WSBaseResp<?> wsBaseResp, Long uid);
|
||||
|
||||
void sendToUidList(WSBaseResp<?> wsBaseResp, List<Long> uidList);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -270,10 +270,6 @@ public class WebSocketServiceImpl implements WebSocketService {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendToUidList(WSBaseResp<?> wsBaseResp, List<Long> uidList) {
|
||||
uidList.forEach(uid -> sendToUid(wsBaseResp, uid));
|
||||
}
|
||||
|
||||
private void sendMsg(Channel channel, WSBaseResp<?> wsBaseResp) {
|
||||
channel.writeAndFlush(new TextWebSocketFrame(JSONUtil.toJsonStr(wsBaseResp)));
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.abin.mallchat.custom.spring;
|
||||
|
||||
import com.abin.mallchat.custom.chat.service.RoomAppService;
|
||||
import com.abin.mallchat.custom.chat.service.WeChatMsgOperationService;
|
||||
import com.abin.mallchat.custom.chat.service.impl.ChatServiceImpl;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -17,12 +19,15 @@ import java.util.Collections;
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@Component
|
||||
public class WXTemplate {
|
||||
|
||||
@Autowired
|
||||
private WeChatMsgOperationService chatMsgOperationService;
|
||||
@Autowired
|
||||
private ChatServiceImpl chatService;
|
||||
@Autowired
|
||||
private RoomAppService roomAppService;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
Reference in New Issue
Block a user