|
|
|
@ -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) { |
|
|
|
|