| @@ -0,0 +1,88 @@ | |||||
| package me.chanjar.weixin.mp.api; | |||||
| import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | |||||
| import sun.applet.Main; | |||||
| import java.net.SocketTimeoutException; | |||||
| import java.util.Map; | |||||
| import java.util.Random; | |||||
| import java.util.concurrent.ConcurrentHashMap; | |||||
| /** | |||||
| * <pre> | |||||
| * 消息去重拦截器 | |||||
| * 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次 | |||||
| * 使用方法: | |||||
| * WxMpMessageRouter router = new WxMpMessageRouter(); | |||||
| * router | |||||
| * .rule() | |||||
| * .interceptor(new WxMpDuplicateMessageInterceptor()) | |||||
| * .next() | |||||
| * .rule() | |||||
| * .msgType("MSG_TYPE").event("EVENT").eventKey("EVENT_KEY").content("CONTENT") | |||||
| * .interceptor(interceptor, ...).handler(handler, ...) | |||||
| * .end() | |||||
| * .rule() | |||||
| * // 另外一个匹配规则 | |||||
| * .end() | |||||
| * ; | |||||
| * </pre> | |||||
| */ | |||||
| public class WxMpDuplicateMessageInterceptor implements WxMpMessageInterceptor { | |||||
| private static final Long PERIOD = 15 * 1000l; | |||||
| private final ConcurrentHashMap<Long, Long> msgId2timestamp; | |||||
| public WxMpDuplicateMessageInterceptor() { | |||||
| this.msgId2timestamp = new ConcurrentHashMap<Long, Long>(); | |||||
| Thread t = new Thread(new Runnable() { | |||||
| @Override | |||||
| public void run() { | |||||
| try { | |||||
| while (true) { | |||||
| Thread.sleep(PERIOD); | |||||
| Long now = System.currentTimeMillis(); | |||||
| for (Map.Entry<Long, Long> entry : msgId2timestamp.entrySet()) { | |||||
| if (now - entry.getValue() > PERIOD) { | |||||
| msgId2timestamp.entrySet().remove(entry); | |||||
| } | |||||
| } | |||||
| msgId2timestamp.clear(); | |||||
| } | |||||
| } catch (InterruptedException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| } | |||||
| }); | |||||
| t.setDaemon(true); | |||||
| t.start(); | |||||
| } | |||||
| @Override | |||||
| public boolean intercept(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService) { | |||||
| Long now = System.currentTimeMillis(); | |||||
| Long timestamp = msgId2timestamp.putIfAbsent(wxMessage.getMsgId(), now); | |||||
| if (timestamp == null) { | |||||
| return true; | |||||
| } | |||||
| if (timestamp.equals(now)) { | |||||
| // 第一次接收到这个消息 | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| public static void main(String[] args) { | |||||
| WxMpDuplicateMessageInterceptor d = new WxMpDuplicateMessageInterceptor(); | |||||
| Long endTime = System.currentTimeMillis() + 30 * 1000; | |||||
| Random r = new Random(); | |||||
| while(System.currentTimeMillis() < endTime) { | |||||
| WxMpXmlMessage m = new WxMpXmlMessage(); | |||||
| m.setMsgId(r.nextLong() % 100); | |||||
| d.intercept(m, null, null); | |||||
| } | |||||
| } | |||||
| } | |||||