From 85168a14aa9833fa4f9af85c378bbdb1a518f975 Mon Sep 17 00:00:00 2001 From: Daniel Qian Date: Mon, 19 Jan 2015 17:25:41 +0800 Subject: [PATCH] =?UTF-8?q?issue=20#66=20=E6=B6=88=E6=81=AF=E5=8E=BB?= =?UTF-8?q?=E9=87=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/WxMpDuplicateMessageInterceptor.java | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDuplicateMessageInterceptor.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDuplicateMessageInterceptor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDuplicateMessageInterceptor.java new file mode 100644 index 00000000..970bbba4 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDuplicateMessageInterceptor.java @@ -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; + +/** + *
+ * 消息去重拦截器
+ * 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次
+ * 使用方法:
+ * 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()
+ * ;
+ * 
+ */ +public class WxMpDuplicateMessageInterceptor implements WxMpMessageInterceptor { + + private static final Long PERIOD = 15 * 1000l; + + private final ConcurrentHashMap msgId2timestamp; + + public WxMpDuplicateMessageInterceptor() { + this.msgId2timestamp = new ConcurrentHashMap(); + Thread t = new Thread(new Runnable() { + @Override + public void run() { + try { + while (true) { + Thread.sleep(PERIOD); + Long now = System.currentTimeMillis(); + for (Map.Entry 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 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); + } + + } +}