com.feingto.iot.server.cache.MessageCache Maven / Gradle / Ivy
package com.feingto.iot.server.cache;
import com.feingto.iot.common.model.mqtt.SendMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.ignite.IgniteCache;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
/**
* Mqtt 消息队列缓存
*
* @author longfei
*/
@Slf4j
public class MessageCache {
private static MessageCache instance;
/**
* 消息队列缓存 [clientId, [messageId, SendMessage]]
*/
private static IgniteCache> igniteCache;
public static MessageCache getInstance(IgniteCache> cache) {
if (instance == null) {
instance = new MessageCache();
igniteCache = cache;
}
return instance;
}
/**
* 根据clientId获取消息
*/
public List findBylientId(String clientId) {
List messages = new ArrayList<>();
igniteCache.forEach(entry -> {
if (clientId.equals(entry.getKey())) {
messages.addAll(entry.getValue().values());
}
});
log.debug(">>> client:[{}] match {} messages", clientId, messages.size());
return messages;
}
/**
* 根据messageId获取消息
*/
public List findByMessageId(Integer messageId) {
List messages = new ArrayList<>();
igniteCache.forEach(entry -> {
if (entry.getValue().containsKey(messageId)) {
messages.add(entry.getValue().get(messageId));
}
});
log.debug(">>> message:[{}] match {} messages", messageId, messages.size());
return messages;
}
/**
* 根据clientId和messageId获取消息
*/
public SendMessage get(String clientId, Integer messageId) {
return findBylientId(clientId).stream()
.filter(message -> messageId.equals(message.id()))
.findFirst()
.orElse(null);
}
/**
* 保存消息
*/
public void put(String clientId, SendMessage message) {
Assert.notNull(clientId, "The clientId parameter cannot be empty");
ConcurrentHashMap map = igniteCache.containsKey(clientId) ?
igniteCache.get(clientId) : new ConcurrentHashMap<>();
// 保存一个messageId的pubrec消息, 之后再次收到同一个messageId的消息, 不做处理
log.debug(">>> client:[{}] save message:[{}]", clientId, +message.id());
map.putIfAbsent(message.id(), message);
igniteCache.put(clientId, map);
}
/**
* 移除clientId消息
*/
public void remove(String clientId) {
Assert.notNull(clientId, "The clientId parameter cannot be empty");
igniteCache.forEach(entry -> {
if (clientId.equals(entry.getKey())) {
igniteCache.remove(clientId);
}
});
}
/**
* 移除messageId消息
*/
public void remove(Integer messageId) {
igniteCache.forEach(entry -> {
ConcurrentHashMap map = entry.getValue();
if (map.containsKey(messageId)) {
map.remove(messageId);
if (map.size() > 0) {
igniteCache.put(entry.getKey(), map);
} else {
igniteCache.remove(entry.getKey());
}
}
});
}
/**
* 移除clientId的messageId消息
*/
public void remove(String clientId, Integer messageId) {
Assert.notNull(clientId, "The clientId parameter cannot be empty");
Assert.notNull(messageId, "The messageId parameter cannot be empty");
Optional.ofNullable(igniteCache.get(clientId))
.ifPresent(map -> {
map.remove(messageId);
if (map.size() > 0) {
igniteCache.put(clientId, map);
} else {
igniteCache.remove(clientId);
}
});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy