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