com.hp.message.service.common.SendMsgCallBackService Maven / Gradle / Ivy
package com.hp.message.service.common;
import com.alibaba.fastjson.JSON;
import com.hp.message.domain.EmqxDataMsg;
import com.hp.message.domain.MsgCallBackWrapper;
import com.hp.message.interfaces.ISdkMsgCallBack;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.PreDestroy;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* @author 尚肖磊
* @create 2021-06-25 14:35
* @Description: SDK消息回调管理服务
*/
@Slf4j
@Service
public class SendMsgCallBackService {
@Lazy
@Autowired
private AsyncCallService asyncCallService;
/**
* sdk消息回调映射对象
*/
private Map callbackMap;
public SendMsgCallBackService() {
try {
if (callbackMap == null) {
callbackMap = new ConcurrentHashMap<>();
}
} catch (Exception ex) {
log.error("init MmsgCallbackMap exception", ex);
}
}
/**
* 销毁时 移除所有回到消息
*/
@PreDestroy
private void destorySdkMsgCallbackMap() {
try {
// 停止未回调超时检查任务
destoryCallbackTask();
// 清理等待回调的消息队列
if (callbackMap != null) {
callbackMap.clear();
callbackMap = null;
}
} catch (Exception ex) {
log.error("destory SdkMsgCallbackMap exception", ex);
}
}
/**
* 遍历取消等待回调的 超时检查线程
*/
private void destoryCallbackTask() {
Iterator> entries = callbackMap.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = entries.next();
MsgCallBackWrapper callbackWrapper = entry.getValue();
log.debug("cannecl wait msg callback wrapper {}", JSON.toJSONString(callbackWrapper.getEmqxDataMsg()));
callbackWrapper.getTimeoutTask().cancel(true);
}
}
/**
* 新增 sdk消息CallBack
*
* @param msg 发送消息对象
* @param msgCallBack 响应映射对象
* @return
*/
public synchronized boolean addMsgCallbackWrapper(EmqxDataMsg msg, ISdkMsgCallBack msgCallBack) {
// 判断消息id 是否存在
String msgId = msg.getMsgId();
if (callbackMap.containsKey(msgId)) {
log.error("add msg callback fail, new msg {}", JSON.toJSONString(msg));
return false;
}
// 生成消息超时任务
ScheduledFuture timeoutTask = enqueueTimeout(msgId, msg.getRespConfig().getRespTimeout() + 1);
// 添加新的sdk消息回调映射
callbackMap.put(msgId, new MsgCallBackWrapper(msgCallBack, timeoutTask, msg));
log.debug("add msg callback success, msgId {}", msgId);
log.debug("wait callback msg count {}", callbackMap.size());
return true;
}
/**
* 获取消息回调映射并移除
*
* @param msg 响应消息
* @return
*/
public synchronized MsgCallBackWrapper getMsgCallbackWrapper(EmqxDataMsg msg) {
String msgId = msg.getMsgId();
if (callbackMap.containsKey(msgId)) {
MsgCallBackWrapper msgCallBackWrapper = callbackMap.get(msgId);
return msgCallBackWrapper;
} else {
log.debug("not find wait msg callback, msgId {}", msgId);
return null;
}
}
/**
* 添加响应超时 定时任务
*/
private ScheduledFuture enqueueTimeout(final String msgId, long timeout) {
return asyncCallService.addDelayTask(() -> {
MsgCallBackWrapper wrapper = callbackMap.remove(msgId);
log.error("send msg callback timeout, msgId {}", msgId);
if (wrapper != null) {
wrapper.getMsgCallback().onTimeout(wrapper.getEmqxDataMsg());
}
}, timeout, TimeUnit.SECONDS);
}
/**
* 移除rocket消息失败 移除等待回调映射
*/
public void removeMsgCallBack(EmqxDataMsg msg) {
removeMsgCallBack(msg, true);
}
public void removeMsgCallBack(EmqxDataMsg msg, boolean stopTimeoutTask) {
MsgCallBackWrapper callbackWrapper = callbackMap.remove(msg.getMsgId());
if (callbackWrapper != null) {
//取消延时任务
if (stopTimeoutTask) {
callbackWrapper.getTimeoutTask().cancel(true);
}
}
}
}