| @@ -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); | |||
| } | |||
| } | |||
| } | |||