Browse Source

多终端同时在线后端改造(开发中)

master
xsx 3 years ago
parent
commit
bf5bb70751
  1. 15
      im-client/src/main/java/com/bx/imclient/IMClient.java
  2. 128
      im-client/src/main/java/com/bx/imclient/sender/IMSender.java
  3. 5
      im-commom/src/main/java/com/bx/imcommon/contant/RedisKey.java
  4. 43
      im-commom/src/main/java/com/bx/imcommon/model/IMGroupMessage.java
  5. 9
      im-commom/src/main/java/com/bx/imcommon/model/IMPrivateMessage.java
  6. 13
      im-commom/src/main/java/com/bx/imcommon/model/IMRecvInfo.java
  7. 30
      im-commom/src/main/java/com/bx/imcommon/model/IMUserInfo.java
  8. 18
      im-commom/src/main/java/com/bx/imcommon/model/SendResult.java
  9. 2
      im-platform/src/main/java/com/bx/implatform/contant/RedisKey.java
  10. 9
      im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java
  11. 28
      im-platform/src/main/java/com/bx/implatform/listener/PrivateMessageListener.java
  12. 67
      im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java
  13. 21
      im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java
  14. 22
      im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcServiceImpl.java
  15. 53
      im-server/src/main/java/com/bx/imserver/netty/processor/GroupMessageProcessor.java
  16. 18
      im-server/src/main/java/com/bx/imserver/netty/processor/PrivateMessageProcessor.java
  17. 1
      im-server/src/main/java/com/bx/imserver/task/AbstractPullMessageTask.java
  18. 13
      im-server/src/main/java/com/bx/imserver/task/PullUnreadGroupMessageTask.java
  19. 13
      im-server/src/main/java/com/bx/imserver/task/PullUnreadPrivateMessageTask.java
  20. 10
      im-ui/src/components/chat/ChatPrivateVideo.vue
  21. 10
      im-ui/src/components/chat/ChatVideoAcceptor.vue
  22. 5
      im-ui/src/view/Home.vue

15
im-client/src/main/java/com/bx/imclient/IMClient.java

@ -1,14 +1,12 @@
package com.bx.imclient;
import com.bx.imclient.listener.MessageListenerMulticaster;
import com.bx.imclient.sender.IMSender;
import com.bx.imcommon.model.GroupMessageInfo;
import com.bx.imcommon.model.IMGroupMessage;
import com.bx.imcommon.model.IMPrivateMessage;
import com.bx.imcommon.model.PrivateMessageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class IMClient {
@ -30,18 +28,17 @@ public class IMClient {
*
* @param message 私有消息
*/
public void sendPrivateMessage(IMPrivateMessage message){
public void sendPrivateMessage(IMPrivateMessage<?> message){
imSender.sendPrivateMessage(message);
}
/**
* 发送群聊消息发送结果通过MessageListener接收
*
* @param recvIds 群聊用户id列表
* @param messageInfo 消息体将转成json发送到客户端
* @param message 群聊消息
*/
public void sendGroupMessage(List<Long> recvIds, GroupMessageInfo... messageInfo){
imSender.sendGroupMessage(recvIds,messageInfo);
public void sendGroupMessage(IMGroupMessage<?> message){
imSender.sendGroupMessage(message);
}

128
im-client/src/main/java/com/bx/imclient/sender/IMSender.java

@ -22,29 +22,26 @@ public class IMSender {
@Autowired
@Qualifier("IMRedisTemplate")
private RedisTemplate redisTemplate;
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private MessageListenerMulticaster listenerMulticaster;
public void sendPrivateMessage(IMPrivateMessage<?> message) {
List<Integer> terminals = message.getRecvTerminals();
for (Integer terminal : terminals) {
for (Integer terminal : message.getRecvTerminals()) {
// 获取对方连接的channelId
String key = String.join(":",RedisKey.IM_USER_SERVER_ID, message.getRecvId().toString(), terminal.toString());
Integer serverId = (Integer) redisTemplate.opsForValue().get(key);
// 如果对方在线,将数据存储至redis,等待拉取推送
if (serverId != null) {
IMRecvInfo[] recvInfos = new IMRecvInfo[message.getDatas().size()];
String sendKey = RedisKey.IM_UNREAD_PRIVATE_QUEUE + serverId;
String sendKey = String.join(":",RedisKey.IM_UNREAD_PRIVATE_QUEUE,serverId.toString());
for (int i = 0; i < message.getDatas().size(); i++) {
IMRecvInfo recvInfo = new IMRecvInfo();
recvInfo.setCmd(IMCmdType.PRIVATE_MESSAGE.code());
recvInfo.setRecvTerminal(terminal);
recvInfo.setSendResult(message.getSendResult());
List<Long> recvIds = new LinkedList<>();
recvIds.add(message.getRecvId());
recvInfo.setRecvIds(recvIds);
recvInfo.setSender(message.getSender());
recvInfo.setReceivers(Collections.singletonList(new IMUserInfo(message.getRecvId(), terminal)));
recvInfo.setData(message.getDatas().get(i));
recvInfos[i]=recvInfo;
}
@ -53,8 +50,8 @@ public class IMSender {
// 回复消息状态
for (int i = 0; i < message.getDatas().size(); i++) {
SendResult result = new SendResult();
result.setRecvId(message.getRecvId());
result.setRecvTerminal(terminal);
result.setSender(message.getSender());
result.setReceiver(new IMUserInfo(message.getRecvId(), terminal));
result.setCode(IMSendCode.NOT_ONLINE.code());
result.setData(message.getDatas().get(i));
listenerMulticaster.multicast(IMListenerType.PRIVATE_MESSAGE, result);
@ -62,23 +59,21 @@ public class IMSender {
}
// 推送给自己的其他终端
if (message.getSendToSelf() && !message.getSendTerminal().equals(terminal)) {
if (message.getSendToSelf() && !message.getSender().getTerminal().equals(terminal)) {
// 获取终端连接的channelId
key = String.join(":",RedisKey.IM_USER_SERVER_ID, message.getSendId().toString(), terminal.toString());
key = String.join(":",RedisKey.IM_USER_SERVER_ID, message.getSender().getId().toString(), terminal.toString());
serverId = (Integer) redisTemplate.opsForValue().get(key);
// 如果终端在线,将数据存储至redis,等待拉取推送
if (serverId != null) {
String sendKey = RedisKey.IM_UNREAD_PRIVATE_QUEUE + serverId;
String sendKey = String.join(":",RedisKey.IM_UNREAD_PRIVATE_QUEUE, serverId.toString());
IMRecvInfo[] recvInfos = new IMRecvInfo[message.getDatas().size()];
for (int i = 0; i < message.getDatas().size(); i++) {
IMRecvInfo recvInfo = new IMRecvInfo();
recvInfo.setCmd(IMCmdType.PRIVATE_MESSAGE.code());
recvInfo.setRecvTerminal(terminal);
// 自己的消息不需要回推消息结果
recvInfo.setSendResult(false);
LinkedList<Long> recvIds = new LinkedList<>();
recvIds.add(message.getSendId());
recvInfo.setRecvIds(recvIds);
recvInfo.setCmd(IMCmdType.PRIVATE_MESSAGE.code());
recvInfo.setSender(message.getSender());
recvInfo.setReceivers(Collections.singletonList(new IMUserInfo(message.getSender().getId(),terminal)));
recvInfo.setData(message.getDatas().get(i));
recvInfos[i]=recvInfo;
}
@ -88,52 +83,71 @@ public class IMSender {
}
}
public void sendGroupMessage(List<Long> recvIds, GroupMessageInfo... messageInfos) {
public void sendGroupMessage(IMGroupMessage<?> message) {
// 根据群聊每个成员所连的IM-server,进行分组
List<Long> offLineIds = Collections.synchronizedList(new LinkedList<Long>());
Map<Integer, List<Long>> serverMap = new ConcurrentHashMap<>();
recvIds.parallelStream().forEach(id -> {
String key = RedisKey.IM_USER_SERVER_ID + id;
List<IMUserInfo> offLineUsers = Collections.synchronizedList(new LinkedList<>());
// 格式:map<服务器id,list<接收方>>
Map<Integer, List<IMUserInfo>> serverMap = new ConcurrentHashMap<>();
for (Integer terminal : message.getRecvTerminals()) {
message.getRecvIds().parallelStream().forEach(id -> {
String key = String.join(":",RedisKey.IM_USER_SERVER_ID, id.toString(),terminal.toString());
Integer serverId = (Integer)redisTemplate.opsForValue().get(key);
if (serverId != null) {
// 此处需要加锁,否则list可以会被覆盖
synchronized (serverMap) {
if (serverMap.containsKey(serverId)) {
serverMap.get(serverId).add(id);
List<IMUserInfo> list = serverMap.computeIfAbsent(serverId,o->Collections.synchronizedList(new LinkedList<>()));
list.add(new IMUserInfo(id,terminal));
} else {
List<Long> list = Collections.synchronizedList(new LinkedList<Long>());
list.add(id);
serverMap.put(serverId, list);
}
}
} else {
offLineIds.add(id);
// 加入离线列表
offLineUsers.add(new IMUserInfo(id,terminal));
}
});
}
// 逐个server发送
// for (Map.Entry<Integer, List<Long>> entry : serverMap.entrySet()) {
// IMRecvInfo[] recvInfos = new IMRecvInfo[messageInfos.length];
// for (int i = 0; i < messageInfos.length; i++) {
// IMRecvInfo<GroupMessageInfo> recvInfo = new IMRecvInfo<>();
// recvInfo.setCmd(IMCmdType.GROUP_MESSAGE.code());
// recvInfo.setRecvIds(new LinkedList<>(entry.getValue()));
// recvInfo.setData(messageInfos[i]);
// recvInfos[i] = recvInfo;
// }
// String key = RedisKey.IM_UNREAD_GROUP_QUEUE + entry.getKey();
// redisTemplate.opsForList().rightPushAll(key, recvInfos);
// }
// // 不在线的用户,回复消息状态
// for (GroupMessageInfo messageInfo : messageInfos) {
// for (Long id : offLineIds) {
// // 回复消息状态
// SendResult result = new SendResult();
// result.setMessageInfo(messageInfo);
// result.setRecvId(id);
// result.setCode(IMSendCode.NOT_ONLINE);
// listenerMulticaster.multicast(IMListenerType.GROUP_MESSAGE, result);
// }
// }
for (Map.Entry<Integer, List<IMUserInfo>> entry : serverMap.entrySet()) {
IMRecvInfo recvInfo = new IMRecvInfo();
recvInfo.setCmd(IMCmdType.GROUP_MESSAGE.code());
recvInfo.setReceivers(new LinkedList<>(entry.getValue()));
recvInfo.setSender(message.getSender());
recvInfo.setSendResult(message.getSendResult());
recvInfo.setData(message.getData());
// 推送至队列
String key = String.join(":",RedisKey.IM_UNREAD_GROUP_QUEUE,entry.getKey().toString());
redisTemplate.opsForList().rightPush(key, recvInfo);
}
// 对离线用户回复消息状态
if(message.getSendResult()){
for (IMUserInfo offLineUser : offLineUsers) {
SendResult result = new SendResult();
result.setSender(message.getSender());
result.setReceiver(offLineUser);
result.setCode(IMSendCode.NOT_ONLINE.code());
result.setData(message.getData());
listenerMulticaster.multicast(IMListenerType.GROUP_MESSAGE, result);
}
}
// 推送给自己的其他终端
if (message.getSendToSelf()) {
for (Integer terminal : message.getRecvTerminals()) {
if(terminal.equals(message.getSender().getTerminal())){
continue;
}
// 获取终端连接的channelId
String key = String.join(":",RedisKey.IM_USER_SERVER_ID, message.getSender().getId().toString(), terminal.toString());
Integer serverId = (Integer) redisTemplate.opsForValue().get(key);
// 如果终端在线,将数据存储至redis,等待拉取推送
if (serverId != null) {
IMRecvInfo recvInfo = new IMRecvInfo();
recvInfo.setCmd(IMCmdType.GROUP_MESSAGE.code());
recvInfo.setSender(message.getSender());
recvInfo.setReceivers(Collections.singletonList(new IMUserInfo(message.getSender().getId(),terminal)));
// 自己的消息不需要回推消息结果
recvInfo.setSendResult(false);
recvInfo.setData(message.getData());
String sendKey = String.join(":",RedisKey.IM_UNREAD_GROUP_QUEUE,serverId.toString());
redisTemplate.opsForList().rightPush(sendKey, recvInfo);
}
}
}
}
public Boolean isOnline(Long userId) {

5
im-commom/src/main/java/com/bx/imcommon/contant/RedisKey.java

@ -7,13 +7,12 @@ public class RedisKey {
// 用户ID所连接的IM-server的ID
public final static String IM_USER_SERVER_ID = "im:user:server_id";
// 未读私聊消息队列
public final static String IM_UNREAD_PRIVATE_QUEUE = "im:unread:private:";
public final static String IM_UNREAD_PRIVATE_QUEUE = "im:unread:private";
// 未读群聊消息队列
public final static String IM_UNREAD_GROUP_QUEUE = "im:unread:group:";
public final static String IM_UNREAD_GROUP_QUEUE = "im:unread:group";
// 私聊消息发送结果队列
public final static String IM_RESULT_PRIVATE_QUEUE = "im:result:private";
// 群聊消息发送结果队列
public final static String IM_RESULT_GROUP_QUEUE = "im:result:group";
}

43
im-commom/src/main/java/com/bx/imcommon/model/IMGroupMessage.java

@ -0,0 +1,43 @@
package com.bx.imcommon.model;
import com.bx.imcommon.enums.IMTerminalType;
import lombok.Data;
import java.util.List;
@Data
public class IMGroupMessage<T> {
/**
* 发送方
*/
private IMUserInfo sender;
/**
* 接收者id列表(群成员列表)
*/
private List<Long> recvIds;
/**
* 接收者终端类型,默认全部
*/
private List<Integer> recvTerminals = IMTerminalType.codes();
/**
* 是否发送给自己的其他终端,默认true
*/
private Boolean sendToSelf = true;
/**
* 是否需要回推发送结果,默认true
*/
private Boolean sendResult = true;
/**
* 消息内容
*/
private T data;
}

9
im-commom/src/main/java/com/bx/imcommon/model/IMPrivateMessage.java

@ -10,14 +10,9 @@ import java.util.List;
public class IMPrivateMessage<T> {
/**
* 发送者id
* 发送
*/
private Long sendId;
/**
* 发送者终端类型 IMTerminalType
*/
private Integer sendTerminal;
private IMUserInfo sender;
/**
* 接收者id

13
im-commom/src/main/java/com/bx/imcommon/model/IMRecvInfo.java

@ -13,19 +13,14 @@ public class IMRecvInfo {
private Integer cmd;
/*
* 发送者id
* 发送
*/
private Long sendId;
private IMUserInfo sender;
/*
* 接收终端类型 IMTerminalType
* 接收方用户列表
*/
private Integer recvTerminal;
/*
* 接收者id列表
*/
private List<Long> recvIds;
List<IMUserInfo> receivers;
/*
* 是否需要回调发送结果

30
im-commom/src/main/java/com/bx/imcommon/model/IMUserInfo.java

@ -0,0 +1,30 @@
package com.bx.imcommon.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author: 谢绍许
* @date: 2023-09-24 09:23:11
* @version: 1.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class IMUserInfo {
/**
* 用户id
*/
private Long id;
/**
* 用户终端类型 IMTerminalType
*/
private Integer terminal;
}

18
im-commom/src/main/java/com/bx/imcommon/model/SendResult.java

@ -1,21 +1,19 @@
package com.bx.imcommon.model;
import com.bx.imcommon.enums.IMSendCode;
import com.bx.imcommon.enums.IMTerminalType;
import lombok.Data;
@Data
public class SendResult<T> {
public class SendResult {
/*
* 接收者id
/**
* 发送方
*/
private Long recvId;
private IMUserInfo sender;
/*
* 接收者终端类型 IMTerminalType
/**
* 接收
*/
private Integer recvTerminal;
private IMUserInfo receiver;
/*
* 发送状态 IMCmdType
@ -25,6 +23,6 @@ public class SendResult<T> {
/*
* 消息内容
*/
private T data;
private Object data;
}

2
im-platform/src/main/java/com/bx/implatform/contant/RedisKey.java

@ -3,7 +3,7 @@ package com.bx.implatform.contant;
public class RedisKey {
// 已读群聊消息位置(已读最大id)
public final static String IM_GROUP_READED_POSITION = "im:readed:group:position:";
public final static String IM_GROUP_READED_POSITION = "im:readed:group:position";
// webrtc 会话信息
public final static String IM_WEBRTC_SESSION = "im:webrtc:session";
// 缓存前缀

9
im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java

@ -23,14 +23,9 @@ public class GroupMessageListener implements MessageListener {
@Override
public void process(SendResult result){
GroupMessageInfo messageInfo = (GroupMessageInfo) result.getData();
// 提示类数据不记录
if(messageInfo.getType().equals(MessageType.TIP)){
return;
}
// 保存该用户已拉取的最大消息id
if(result.getCode().equals(IMSendCode.SUCCESS)) {
String key = RedisKey.IM_GROUP_READED_POSITION + messageInfo.getGroupId() + ":" + result.getRecvId();
if(result.getCode().equals(IMSendCode.SUCCESS.code())) {
String key = String.join(":",RedisKey.IM_GROUP_READED_POSITION,messageInfo.getGroupId().toString(),result.getReceiver().getId().toString());
redisTemplate.opsForValue().set(key, messageInfo.getId());
}
}

28
im-platform/src/main/java/com/bx/implatform/listener/PrivateMessageListener.java

@ -35,32 +35,6 @@ public class PrivateMessageListener implements MessageListener {
public void process(SendResult result){
PrivateMessageInfo messageInfo = (PrivateMessageInfo) result.getData();
IMSendCode resultCode = IMSendCode.fromCode(result.getCode());
// 提示类数据不记录
if(messageInfo.getType().equals(MessageType.TIP.code())){
return;
}
// 视频通话信令不记录
if(messageInfo.getType() >= MessageType.RTC_CALL.code() && messageInfo.getType()< MessageType.RTC_CANDIDATE.code()){
// // 通知用户呼叫失败了
// if(messageInfo.getType().equals(MessageType.RTC_CALL.code())
// && !resultCode.equals(IMSendCode.SUCCESS)){
// PrivateMessageInfo msgInfo = new PrivateMessageInfo();
// msgInfo.setRecvId(messageInfo.getSendId());
// msgInfo.setSendId(messageInfo.getRecvId());
// msgInfo.setType(MessageType.RTC_FAILED.code());
// msgInfo.setContent(resultCode.description());
// msgInfo.setSendTime(new Date());
//
// IMPrivateMessage sendMessage = new IMPrivateMessage();
// sendMessage.setSendId(messageInfo.getSendId());
// sendMessage.setRecvId(messageInfo.getRecvId());
// sendMessage.setSendTerminal(result.getRecvTerminal());
// sendMessage.setSendToSelf(false);
// sendMessage.setDatas(Arrays.asList(messageInfo));
// imClient.sendPrivateMessage(sendMessage);
// }
return;
}
// 更新消息状态,这里只处理成功消息,失败的消息继续保持未读状态
if(resultCode.equals(IMSendCode.SUCCESS)){
UpdateWrapper<PrivateMessage> updateWrapper = new UpdateWrapper<>();
@ -68,7 +42,7 @@ public class PrivateMessageListener implements MessageListener {
.eq(PrivateMessage::getStatus, MessageStatus.UNREAD.code())
.set(PrivateMessage::getStatus, MessageStatus.ALREADY_READ.code());
privateMessageService.update(updateWrapper);
log.info("消息已读,消息id:{},发送者:{},接收者:{}",messageInfo.getId(),messageInfo.getSendId(),messageInfo.getRecvId());
log.info("消息已读,消息id:{},发送者:{},接收者:{},终端:{}",messageInfo.getId(),result.getSender().getId(),result.getReceiver().getId(),result.getReceiver().getTerminal());
}
}

67
im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java

@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bx.imclient.IMClient;
import com.bx.imcommon.contant.Constant;
import com.bx.imcommon.model.GroupMessageInfo;
import com.bx.imcommon.model.IMGroupMessage;
import com.bx.imcommon.model.IMUserInfo;
import com.bx.implatform.contant.RedisKey;
import com.bx.implatform.entity.Group;
import com.bx.implatform.entity.GroupMember;
@ -18,6 +20,7 @@ import com.bx.implatform.service.IGroupMemberService;
import com.bx.implatform.service.IGroupMessageService;
import com.bx.implatform.service.IGroupService;
import com.bx.implatform.session.SessionContext;
import com.bx.implatform.session.UserSession;
import com.bx.implatform.util.BeanUtils;
import com.bx.implatform.vo.GroupMessageVO;
import lombok.extern.slf4j.Slf4j;
@ -56,7 +59,7 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
*/
@Override
public Long sendMessage(GroupMessageVO vo) {
Long userId = SessionContext.getSession().getUserId();
UserSession session = SessionContext.getSession();
Group group = groupService.getById(vo.getGroupId());
if(group == null){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"群聊不存在");
@ -66,20 +69,24 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
}
// 判断是否在群里
List<Long> userIds = groupMemberService.findUserIdsByGroupId(group.getId());
if(!userIds.contains(userId)){
if(!userIds.contains(session.getUserId())){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"您已不在群聊里面,无法发送消息");
}
// 保存消息
GroupMessage msg = BeanUtils.copyProperties(vo, GroupMessage.class);
msg.setSendId(userId);
msg.setSendId(session.getUserId());
msg.setSendTime(new Date());
this.save(msg);
// 不用发给自己
userIds = userIds.stream().filter(id->userId.equals(id)).collect(Collectors.toList());
userIds = userIds.stream().filter(id->!session.getUserId().equals(id)).collect(Collectors.toList());
// 群发
GroupMessageInfo msgInfo = BeanUtils.copyProperties(msg, GroupMessageInfo.class);
imClient.sendGroupMessage(userIds,msgInfo);
log.info("发送群聊消息,发送id:{},群聊id:{},内容:{}",userId,vo.getGroupId(),vo.getContent());
IMGroupMessage sendMessage = new IMGroupMessage();
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvIds(userIds);
sendMessage.setData(msgInfo);
imClient.sendGroupMessage(sendMessage);
log.info("发送群聊消息,发送id:{},群聊id:{},内容:{}",session.getUserId(),vo.getGroupId(),vo.getContent());
return msg.getId();
}
@ -93,19 +100,19 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
*/
@Override
public void recallMessage(Long id) {
Long userId = SessionContext.getSession().getUserId();
UserSession session = SessionContext.getSession();
GroupMessage msg = this.getById(id);
if(msg == null){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"消息不存在");
}
if(!msg.getSendId().equals(userId)){
if(!msg.getSendId().equals(session.getUserId())){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"这条消息不是由您发送,无法撤回");
}
if(System.currentTimeMillis() - msg.getSendTime().getTime() > Constant.ALLOW_RECALL_SECOND * 1000){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"消息已发送超过5分钟,无法撤回");
}
// 判断是否在群里
GroupMember member = groupMemberService.findByGroupAndUserId(msg.getGroupId(),userId);
GroupMember member = groupMemberService.findByGroupAndUserId(msg.getGroupId(),session.getUserId());
if(member == null){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"您已不在群聊里面,无法撤回消息");
}
@ -115,14 +122,20 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
// 群发
List<Long> userIds = groupMemberService.findUserIdsByGroupId(msg.getGroupId());
// 不用发给自己
userIds = userIds.stream().filter(uid->userId.equals(uid)).collect(Collectors.toList());
userIds = userIds.stream().filter(uid->!session.getUserId().equals(uid)).collect(Collectors.toList());
GroupMessageInfo msgInfo = BeanUtils.copyProperties(msg, GroupMessageInfo.class);
msgInfo.setType(MessageType.TIP.code());
String content = String.format("'%s'撤回了一条消息",member.getAliasName());
msgInfo.setContent(content);
msgInfo.setSendTime(new Date());
imClient.sendGroupMessage(userIds,msgInfo);
log.info("撤回群聊消息,发送id:{},群聊id:{},内容:{}",userId,msg.getGroupId(),msg.getContent());
IMGroupMessage sendMessage = new IMGroupMessage();
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvIds(userIds);
sendMessage.setData(msgInfo);
sendMessage.setSendResult(false);
imClient.sendGroupMessage(sendMessage);
log.info("撤回群聊消息,发送id:{},群聊id:{},内容:{}",session.getUserId(),msg.getGroupId(),msg.getContent());
}
@ -133,18 +146,16 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
*/
@Override
public void pullUnreadMessage() {
Long userId = SessionContext.getSession().getUserId();
List<Long> recvIds = new LinkedList();
recvIds.add(userId);
List<GroupMember> members = groupMemberService.findByUserId(userId);
UserSession session = SessionContext.getSession();
List<GroupMember> members = groupMemberService.findByUserId(session.getUserId());
for(GroupMember member:members){
// 获取群聊已读的最大消息id,只推送未读消息
String key = RedisKey.IM_GROUP_READED_POSITION + member.getGroupId()+":"+userId;
String key = String.join(":",RedisKey.IM_GROUP_READED_POSITION,member.getGroupId().toString(),session.getUserId().toString());
Integer maxReadedId = (Integer)redisTemplate.opsForValue().get(key);
QueryWrapper<GroupMessage> wrapper = new QueryWrapper();
wrapper.lambda().eq(GroupMessage::getGroupId,member.getGroupId())
.gt(GroupMessage::getSendTime,member.getCreatedTime())
.ne(GroupMessage::getSendId, userId)
.ne(GroupMessage::getSendId, session.getUserId())
.ne(GroupMessage::getStatus, MessageStatus.RECALL.code());
if(maxReadedId!=null){
wrapper.lambda().gt(GroupMessage::getId,maxReadedId);
@ -154,15 +165,19 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
if(messages.isEmpty()){
continue;
}
// 组装消息,准备推送
List<GroupMessageInfo> messageInfos = messages.stream().map(m->{
GroupMessageInfo msgInfo = BeanUtils.copyProperties(m, GroupMessageInfo.class);
return msgInfo;
}).collect(Collectors.toList());
// 推送
for (GroupMessage message:messages ){
GroupMessageInfo msgInfo = BeanUtils.copyProperties(message, GroupMessageInfo.class);
IMGroupMessage sendMessage = new IMGroupMessage();
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
// 只推给自己当前终端
sendMessage.setRecvIds(Collections.singletonList(session.getUserId()));
sendMessage.setRecvTerminals(Collections.singletonList(session.getTerminal()));
sendMessage.setData(msgInfo);
imClient.sendGroupMessage(sendMessage);
}
// 发送消息
GroupMessageInfo[] infoArr = messageInfos.toArray(new GroupMessageInfo[messageInfos.size()]);
imClient.sendGroupMessage(Collections.singletonList(userId), infoArr);
log.info("拉取未读群聊消息,用户id:{},群聊id:{},数量:{}",userId,member.getGroupId(),messageInfos.size());
log.info("拉取未读群聊消息,用户id:{},群聊id:{},数量:{}",session.getUserId(),member.getGroupId(),messages.size());
}
}

21
im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java

@ -4,8 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bx.imclient.IMClient;
import com.bx.imcommon.contant.Constant;
import com.bx.imcommon.enums.IMTerminalType;
import com.bx.imcommon.model.IMPrivateMessage;
import com.bx.imcommon.model.IMUserInfo;
import com.bx.imcommon.model.PrivateMessageInfo;
import com.bx.implatform.entity.PrivateMessage;
import com.bx.implatform.enums.MessageStatus;
@ -22,6 +22,7 @@ import com.bx.implatform.vo.PrivateMessageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@ -58,9 +59,8 @@ public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper,
// 推送消息
PrivateMessageInfo msgInfo = BeanUtils.copyProperties(msg, PrivateMessageInfo.class);
IMPrivateMessage<PrivateMessageInfo> sendMessage = new IMPrivateMessage<>();
sendMessage.setSendId(msgInfo.getSendId());
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvId(msgInfo.getRecvId());
sendMessage.setSendTerminal(session.getTerminal());
sendMessage.setSendToSelf(true);
sendMessage.setDatas(Collections.singletonList(msgInfo));
imClient.sendPrivateMessage(sendMessage);
@ -96,9 +96,8 @@ public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper,
msgInfo.setContent("对方撤回了一条消息");
IMPrivateMessage<PrivateMessageInfo> sendMessage = new IMPrivateMessage<>();
sendMessage.setSendId(msgInfo.getSendId());
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvId(msgInfo.getRecvId());
sendMessage.setSendTerminal(session.getTerminal());
sendMessage.setSendToSelf(true);
sendMessage.setDatas(Collections.singletonList(msgInfo));
imClient.sendPrivateMessage(sendMessage);
@ -142,14 +141,14 @@ public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper,
*/
@Override
public void pullUnreadMessage() {
UserSession session = SessionContext.getSession();
// 获取当前连接的channelId
Long userId = SessionContext.getSession().getUserId();
if (!imClient.isOnline(userId)) {
if (!imClient.isOnline(session.getUserId())) {
throw new GlobalException(ResultCode.PROGRAM_ERROR, "用户未建立连接");
}
// 获取当前用户所有未读消息
QueryWrapper<PrivateMessage> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(PrivateMessage::getRecvId, userId)
queryWrapper.lambda().eq(PrivateMessage::getRecvId, session.getUserId())
.eq(PrivateMessage::getStatus, MessageStatus.UNREAD);
List<PrivateMessage> messages = this.list(queryWrapper);
// 上传至redis,等待推送
@ -157,11 +156,13 @@ public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper,
List<PrivateMessageInfo> messageInfos = messages.stream().map(m -> BeanUtils.copyProperties(m, PrivateMessageInfo.class)).collect(Collectors.toList());
// 推送消息
IMPrivateMessage<PrivateMessageInfo> sendMessage = new IMPrivateMessage<>();
sendMessage.setRecvId(userId);
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvId(session.getUserId());
sendMessage.setRecvTerminals(Collections.singletonList(session.getTerminal()));
sendMessage.setSendToSelf(false);
sendMessage.setDatas(messageInfos);
imClient.sendPrivateMessage(sendMessage);
log.info("拉取未读私聊消息,用户id:{},数量:{}", userId, messageInfos.size());
log.info("拉取未读私聊消息,用户id:{},数量:{}", session.getUserId(), messageInfos.size());
}
}
}

22
im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcServiceImpl.java

@ -2,6 +2,7 @@ package com.bx.implatform.service.impl;
import com.bx.imclient.IMClient;
import com.bx.imcommon.model.IMPrivateMessage;
import com.bx.imcommon.model.IMUserInfo;
import com.bx.imcommon.model.PrivateMessageInfo;
import com.bx.implatform.config.ICEServer;
import com.bx.implatform.config.ICEServerConfig;
@ -54,8 +55,7 @@ public class WebrtcServiceImpl implements IWebrtcService {
messageInfo.setContent(offer);
IMPrivateMessage<PrivateMessageInfo> sendMessage = new IMPrivateMessage<>();
sendMessage.setSendId(session.getUserId());
sendMessage.setSendTerminal(session.getTerminal());
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvId(uid);
sendMessage.setSendToSelf(false);
sendMessage.setSendResult(false);
@ -82,8 +82,7 @@ public class WebrtcServiceImpl implements IWebrtcService {
messageInfo.setContent(answer);
IMPrivateMessage<PrivateMessageInfo> sendMessage = new IMPrivateMessage<>();
sendMessage.setSendId(session.getUserId());
sendMessage.setSendTerminal(session.getTerminal());
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvId(uid);
// 告知其他终端已经接受会话,中止呼叫
sendMessage.setSendToSelf(true);
@ -107,8 +106,7 @@ public class WebrtcServiceImpl implements IWebrtcService {
messageInfo.setSendId(session.getUserId());
IMPrivateMessage<PrivateMessageInfo> sendMessage = new IMPrivateMessage<>();
sendMessage.setSendId(session.getUserId());
sendMessage.setSendTerminal(session.getTerminal());
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvId(uid);
// 告知其他终端已经拒绝会话,中止呼叫
sendMessage.setSendToSelf(true);
@ -130,8 +128,7 @@ public class WebrtcServiceImpl implements IWebrtcService {
messageInfo.setSendId(session.getUserId());
IMPrivateMessage<PrivateMessageInfo> sendMessage = new IMPrivateMessage<>();
sendMessage.setSendId(session.getUserId());
sendMessage.setSendTerminal(session.getTerminal());
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvId(uid);
sendMessage.setSendToSelf(false);
sendMessage.setSendResult(false);
@ -154,8 +151,7 @@ public class WebrtcServiceImpl implements IWebrtcService {
messageInfo.setSendId(session.getUserId());
IMPrivateMessage<PrivateMessageInfo> sendMessage = new IMPrivateMessage<>();
sendMessage.setSendId(session.getUserId());
sendMessage.setSendTerminal(session.getTerminal());
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvId(uid);
// 告知其他终端已经会话失败,中止呼叫
sendMessage.setSendToSelf(true);
@ -181,8 +177,7 @@ public class WebrtcServiceImpl implements IWebrtcService {
messageInfo.setSendId(session.getUserId());
IMPrivateMessage<PrivateMessageInfo> sendMessage = new IMPrivateMessage<>();
sendMessage.setSendId(session.getUserId());
sendMessage.setSendTerminal(session.getTerminal());
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvId(uid);
sendMessage.setSendToSelf(false);
sendMessage.setSendResult(false);
@ -206,8 +201,7 @@ public class WebrtcServiceImpl implements IWebrtcService {
messageInfo.setContent(candidate);
IMPrivateMessage<PrivateMessageInfo> sendMessage = new IMPrivateMessage<>();
sendMessage.setSendId(session.getUserId());
sendMessage.setSendTerminal(session.getTerminal());
sendMessage.setSender(new IMUserInfo(session.getUserId(),session.getTerminal()));
sendMessage.setRecvId(uid);
sendMessage.setSendToSelf(false);
sendMessage.setSendResult(false);

53
im-server/src/main/java/com/bx/imserver/netty/processor/GroupMessageProcessor.java

@ -5,6 +5,7 @@ import com.bx.imcommon.enums.IMCmdType;
import com.bx.imcommon.enums.IMSendCode;
import com.bx.imcommon.model.IMRecvInfo;
import com.bx.imcommon.model.IMSendInfo;
import com.bx.imcommon.model.IMUserInfo;
import com.bx.imcommon.model.SendResult;
import com.bx.imserver.netty.UserChannelCtxMap;
import io.netty.channel.ChannelHandlerContext;
@ -26,47 +27,45 @@ public class GroupMessageProcessor extends AbstractMessageProcessor<IMRecvInfo>
@Async
@Override
public void process(IMRecvInfo recvInfo) {
Object data = recvInfo.getData();
List<Long> recvIds = recvInfo.getRecvIds();
log.info("接收到群消息,发送者:{},接收id:{},内容:{}",recvInfo.getSendId(),recvIds,data);
for(Long recvId:recvIds){
IMUserInfo sender = recvInfo.getSender();
List<IMUserInfo> receivers = recvInfo.getReceivers();
log.info("接收到群消息,发送者:{},接收用户数量:{},内容:{}",sender.getId(),receivers.size(),recvInfo.getData());
for(IMUserInfo receiver:receivers){
try {
ChannelHandlerContext channelCtx = UserChannelCtxMap.getChannelCtx(recvId,recvInfo.getRecvTerminal());
ChannelHandlerContext channelCtx = UserChannelCtxMap.getChannelCtx(receiver.getId(),receiver.getTerminal());
if(channelCtx != null){
// 推送消息到用户
IMSendInfo sendInfo = new IMSendInfo();
sendInfo.setCmd(IMCmdType.GROUP_MESSAGE.code());
sendInfo.setData(data);
sendInfo.setData(recvInfo.getData());
channelCtx.channel().writeAndFlush(sendInfo);
// 消息发送成功确认
String key = RedisKey.IM_RESULT_GROUP_QUEUE;
SendResult sendResult = new SendResult();
sendResult.setRecvId(recvId);
sendResult.setCode(IMSendCode.SUCCESS.code());
sendResult.setData(data);
redisTemplate.opsForList().rightPush(key,sendResult);
sendResult(recvInfo,receiver,IMSendCode.SUCCESS);
}else {
// 消息发送失败确认
String key = RedisKey.IM_RESULT_GROUP_QUEUE;
SendResult sendResult = new SendResult();
sendResult.setRecvId(recvId);
sendResult.setCode(IMSendCode.NOT_FIND_CHANNEL.code());
sendResult.setData(data);
redisTemplate.opsForList().rightPush(key,sendResult);
log.error("未找到WS连接,发送者:{},接收id:{},内容:{}",recvInfo.getSendId(),recvId,data);
// 消息发送成功确认
sendResult(recvInfo,receiver,IMSendCode.NOT_FIND_CHANNEL);
log.error("未找到channel,发送者:{},接收id:{},内容:{}",sender.getId(),receiver.getId(),recvInfo.getData());
}
}catch (Exception e){
// 消息发送失败确认
String key = RedisKey.IM_RESULT_GROUP_QUEUE;
SendResult sendResult = new SendResult();
sendResult.setRecvId(recvId);
sendResult.setCode(IMSendCode.UNKONW_ERROR.code());
sendResult.setData(data);
redisTemplate.opsForList().rightPush(key,sendResult);
log.error("发送消息异常,发送者:{},接收id:{},内容:{}",recvInfo.getSendId(),recvId,data);
sendResult(recvInfo,receiver,IMSendCode.UNKONW_ERROR);
log.error("发送消息异常,发送者:{},接收id:{},内容:{}",sender.getId(),receiver.getId(),recvInfo.getData());
}
}
}
private void sendResult(IMRecvInfo recvInfo,IMUserInfo receiver,IMSendCode sendCode){
if(recvInfo.getSendResult()) {
SendResult result = new SendResult();
result.setSender(recvInfo.getSender());
result.setReceiver(receiver);
result.setCode(sendCode.code());
result.setData(recvInfo.getData());
// 推送到结果队列
String key = RedisKey.IM_RESULT_GROUP_QUEUE;
redisTemplate.opsForList().rightPush(key, result);
}
}
}

18
im-server/src/main/java/com/bx/imserver/netty/processor/PrivateMessageProcessor.java

@ -5,6 +5,7 @@ import com.bx.imcommon.enums.IMCmdType;
import com.bx.imcommon.enums.IMSendCode;
import com.bx.imcommon.model.IMRecvInfo;
import com.bx.imcommon.model.IMSendInfo;
import com.bx.imcommon.model.IMUserInfo;
import com.bx.imcommon.model.SendResult;
import com.bx.imserver.netty.UserChannelCtxMap;
import io.netty.channel.ChannelHandlerContext;
@ -22,10 +23,11 @@ public class PrivateMessageProcessor extends AbstractMessageProcessor<IMRecvInfo
@Override
public void process(IMRecvInfo recvInfo) {
Long recvId = recvInfo.getRecvIds().get(0);
log.info("接收到消息,发送者:{},接收者:{},内容:{}",recvInfo.getSendId(),recvId,recvInfo.getData());
IMUserInfo sender = recvInfo.getSender();
IMUserInfo receiver = recvInfo.getReceivers().get(0);
log.info("接收到消息,发送者:{},接收者:{},内容:{}",sender.getId(),receiver.getId(),recvInfo.getData());
try{
ChannelHandlerContext channelCtx = UserChannelCtxMap.getChannelCtx(recvId,recvInfo.getRecvTerminal());
ChannelHandlerContext channelCtx = UserChannelCtxMap.getChannelCtx(receiver.getId(),receiver.getTerminal());
if(channelCtx != null ){
// 推送消息到用户
IMSendInfo sendInfo = new IMSendInfo();
@ -37,23 +39,25 @@ public class PrivateMessageProcessor extends AbstractMessageProcessor<IMRecvInfo
}else{
// 消息推送失败确认
sendResult(recvInfo,IMSendCode.NOT_FIND_CHANNEL);
log.error("未找到WS连接,发送者:{},接收者:{},内容:{}",recvInfo.getSendId(),recvId,recvInfo.getData());
log.error("未找到channel,发送者:{},接收者:{},内容:{}",sender.getId(),receiver.getId(),recvInfo.getData());
}
}catch (Exception e){
// 消息推送失败确认
sendResult(recvInfo,IMSendCode.UNKONW_ERROR);
log.error("发送异常,发送者:{},接收者:{},内容:{}",recvInfo.getSendId(),recvId,recvInfo.getData(),e);
log.error("发送异常,发送者:{},接收者:{},内容:{}",sender.getId(),receiver.getId(),recvInfo.getData(),e);
}
}
private void sendResult(IMRecvInfo recvInfo,IMSendCode sendCode){
if(recvInfo.getSendResult()) {
String key = RedisKey.IM_RESULT_PRIVATE_QUEUE;
SendResult result = new SendResult();
result.setRecvId(recvInfo.getRecvIds().get(0));
result.setSender(recvInfo.getSender());
result.setReceiver(recvInfo.getReceivers().get(0));
result.setCode(sendCode.code());
result.setData(recvInfo.getData());
// 推送到结果队列
String key = RedisKey.IM_RESULT_PRIVATE_QUEUE;
redisTemplate.opsForList().rightPush(key, result);
}
}

1
im-server/src/main/java/com/bx/imserver/task/AbstractPullMessageTask.java

@ -40,7 +40,6 @@ public abstract class AbstractPullMessageTask {
if (serverGroup.isReady()) {
pullMessage();
}
Thread.sleep(100);
} catch (Exception e) {
log.error("任务调度异常", e);
Thread.sleep(200);

13
im-server/src/main/java/com/bx/imserver/task/PullUnreadGroupMessageTask.java

@ -10,8 +10,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
@ -23,16 +22,12 @@ public class PullUnreadGroupMessageTask extends AbstractPullMessageTask {
@Override
public void pullMessage() {
// 从redis拉取未读消息
String key = RedisKey.IM_UNREAD_GROUP_QUEUE + IMServerGroup.serverId;
List recvInfos = redisTemplate.opsForList().range(key,0,-1);
for(Object o: recvInfos){
redisTemplate.opsForList().leftPop(key);
IMRecvInfo recvInfo = (IMRecvInfo)o;
String key = String.join(":",RedisKey.IM_UNREAD_GROUP_QUEUE,IMServerGroup.serverId+"");
IMRecvInfo recvInfo = (IMRecvInfo)redisTemplate.opsForList().leftPop(key,10, TimeUnit.SECONDS);
if(recvInfo != null){
AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.GROUP_MESSAGE);
processor.process(recvInfo);
}
}
}

13
im-server/src/main/java/com/bx/imserver/task/PullUnreadPrivateMessageTask.java

@ -11,9 +11,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
@ -26,14 +24,11 @@ public class PullUnreadPrivateMessageTask extends AbstractPullMessageTask {
@Override
public void pullMessage() {
// 从redis拉取未读消息
String key = RedisKey.IM_UNREAD_PRIVATE_QUEUE + IMServerGroup.serverId;
List recvInfos = redisTemplate.opsForList().range(key,0,-1);
for(Object o: recvInfos){
redisTemplate.opsForList().leftPop(key);
IMRecvInfo recvInfo = (IMRecvInfo)o;
String key = String.join(":",RedisKey.IM_UNREAD_PRIVATE_QUEUE ,IMServerGroup.serverId+"");
IMRecvInfo recvInfo = (IMRecvInfo)redisTemplate.opsForList().leftPop(key,10, TimeUnit.SECONDS);
if(recvInfo != null) {
AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.PRIVATE_MESSAGE);
processor.process(recvInfo);
}
}

10
im-ui/src/components/chat/ChatPrivateVideo.vue

@ -143,7 +143,7 @@
},
handleMessage(msg) {
if (msg.type == this.$enums.MESSAGE_TYPE.RTC_ACCEPT) {
if (msg.sendId == this.$store.state.userStore.userInfo.id) {
if (msg.selfSend) {
//
this.$message.success("已在其他设备接听");
this.close();
@ -163,8 +163,7 @@
}
} else if (msg.type == this.$enums.MESSAGE_TYPE.RTC_REJECT) {
console.log(msg)
if (msg.sendId == this.$store.state.userStore.userInfo.id) {
if (msg.selfSend) {
//
this.$message.success("已在其他设备拒绝通话");
this.close();
@ -195,9 +194,8 @@
this.loading = true;
this.state = 'CONNECTING';
this.audio.play();
});
},
(error) => {
})
},(error) => {
this.$message.error(error);
});

10
im-ui/src/components/chat/ChatVideoAcceptor.vue

@ -18,7 +18,9 @@
export default {
name: "videoAcceptor",
components:{HeadImage},
components: {
HeadImage
},
props: {
friend: {
type: Object
@ -55,7 +57,6 @@
this.close();
},
onCall(msgInfo) {
console.log("onCall")
this.offer = JSON.parse(msgInfo.content);
if (this.$store.state.userStore.state == this.$enums.USER_STATE.BUSY) {
this.failed("对方正忙,暂时无法接听");
@ -72,8 +73,6 @@
//
this.$message.success("对方取消了呼叫");
this.close();
},
handleMessage(msgInfo) {
if (msgInfo.type == this.$enums.MESSAGE_TYPE.RTC_CALL) {
@ -99,7 +98,6 @@
}
}
</script>
<style scoped lang="scss">
@ -122,9 +120,11 @@
.icon {
font-size: 50px;
cursor: pointer;
&.accept {
color: green;
}
&.reject {
color: red;
}

5
im-ui/src/view/Home.vue

@ -87,6 +87,8 @@
this.pullUnreadMessage();
});
this.$wsApi.onmessage((cmd, msgInfo) => {
//
msgInfo.selfSend = msgInfo.sendId==this.$store.state.userStore.userInfo.id;
if (cmd == 2) {
// 线
this.$message.error("您已在其他地方登陆,将被强制下线");
@ -116,7 +118,6 @@
},
handlePrivateMessage(msg) {
//
msg.selfSend = msg.sendId==this.$store.state.userStore.userInfo.id;
let friendId = msg.selfSend?msg.recvId:msg.sendId;
let friend = this.$store.state.friendStore.friends.find((f) => f.id == friendId);
if (friend) {
@ -191,7 +192,7 @@
//
this.$store.commit("insertMessage", msg);
//
this.playAudioTip();
!msg.selfSend && this.playAudioTip();
},
handleExit() {
this.$wsApi.closeWebSocket();

Loading…
Cancel
Save