Skip to content

Commit 3216cb5

Browse files
committed
issue binarywang#66 对去重逻辑做了一些调整
1 parent 3ff9d26 commit 3216cb5

5 files changed

Lines changed: 55 additions & 13 deletions

File tree

weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageDuplicateChecker.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,19 @@
99
public interface WxMessageDuplicateChecker {
1010

1111
/**
12-
* 检查消息ID是否重复
13-
* @param wxMsgId
12+
* <h2>公众号的排重方式</h2>
13+
*
14+
* <p>普通消息:关于重试的消息排重,推荐使用msgid排重。<a href="http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html">文档参考</a>。</p>
15+
* <p>事件消息:关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。<a href="http://mp.weixin.qq.com/wiki/2/5baf56ce4947d35003b86a9805634b1e.html">文档参考</a></p>
16+
*
17+
* <h2>企业号的排重方式</h2>
18+
*
19+
* 官方文档完全没有写,参照公众号的方式排重。
20+
*
21+
* <p>或者可以采取更简单的方式,如果有MsgId就用MsgId排重,如果没有就用FromUserName+CreateTime排重</p>
22+
* @param messageId messageId需要根据上面讲的方式构造
1423
* @return 如果是重复消息,返回true,否则返回false
1524
*/
16-
public boolean isDuplicate(Long wxMsgId);
25+
public boolean isDuplicate(String messageId);
1726

1827
}

weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateChecker.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChec
2525
/**
2626
* 消息id->消息时间戳的map
2727
*/
28-
private final ConcurrentHashMap<Long, Long> msgId2Timestamp = new ConcurrentHashMap<Long, Long>();
28+
private final ConcurrentHashMap<String, Long> msgId2Timestamp = new ConcurrentHashMap<String, Long>();
2929

3030
/**
3131
* 后台清理线程是否已经开启
@@ -65,7 +65,7 @@ public void run() {
6565
while (true) {
6666
Thread.sleep(clearPeriod);
6767
Long now = System.currentTimeMillis();
68-
for (Map.Entry<Long, Long> entry : msgId2Timestamp.entrySet()) {
68+
for (Map.Entry<String, Long> entry : msgId2Timestamp.entrySet()) {
6969
if (now - entry.getValue() > timeToLive) {
7070
msgId2Timestamp.entrySet().remove(entry);
7171
}
@@ -81,12 +81,12 @@ public void run() {
8181
}
8282

8383
@Override
84-
public boolean isDuplicate(Long wxMsgId) {
85-
if (wxMsgId == null) {
84+
public boolean isDuplicate(String messageId) {
85+
if (messageId == null) {
8686
return false;
8787
}
8888
checkBackgroundProcessStarted();
89-
Long timestamp = msgId2Timestamp.putIfAbsent(wxMsgId, System.currentTimeMillis());
89+
Long timestamp = msgId2Timestamp.putIfAbsent(messageId, System.currentTimeMillis());
9090
if (timestamp == null) {
9191
// 第一次接收到这个消息
9292
return false;

weixin-java-common/src/test/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateCheckerTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@ public void test() throws InterruptedException {
1212

1313
// 第一次检查
1414
for (Long msgId : msgIds) {
15-
boolean result = checker.isDuplicate(msgId);
15+
boolean result = checker.isDuplicate(String.valueOf(msgId));
1616
Assert.assertFalse(result);
1717
}
1818

1919
// 过1秒再检查
2020
Thread.sleep(1000l);
2121
for (Long msgId : msgIds) {
22-
boolean result = checker.isDuplicate(msgId);
22+
boolean result = checker.isDuplicate(String.valueOf(msgId));
2323
Assert.assertTrue(result);
2424
}
2525

2626
// 过1.5秒再检查
2727
Thread.sleep(1500l);
2828
for (Long msgId : msgIds) {
29-
boolean result = checker.isDuplicate(msgId);
29+
boolean result = checker.isDuplicate(String.valueOf(msgId));
3030
Assert.assertFalse(result);
3131
}
3232

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public Rule rule() {
115115
* @param wxMessage
116116
*/
117117
public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage) {
118-
if (messageDuplicateChecker.isDuplicate(wxMessage.getMsgId())) {
118+
if (isDuplicateMessage(wxMessage)) {
119119
// 如果是重复消息,那么就不做处理
120120
return null;
121121
}
@@ -177,6 +177,22 @@ public void run() {
177177
return res;
178178
}
179179

180+
protected boolean isDuplicateMessage(WxCpXmlMessage wxMessage) {
181+
182+
String messageId = "";
183+
if (wxMessage.getMsgId() == null) {
184+
messageId = wxMessage.getFromUserName() + "-" + String.valueOf(wxMessage.getCreateTime());
185+
} else {
186+
messageId = String.valueOf(wxMessage.getMsgId());
187+
}
188+
189+
if (messageDuplicateChecker.isDuplicate(messageId)) {
190+
return true;
191+
}
192+
return false;
193+
194+
}
195+
180196
/**
181197
* 对session的访问结束
182198
* @param wxMessage

weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package me.chanjar.weixin.mp.api;
22

3+
import me.chanjar.weixin.common.api.WxConsts;
34
import me.chanjar.weixin.common.session.*;
45
import me.chanjar.weixin.common.util.WxMessageDuplicateChecker;
56
import me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker;
@@ -113,7 +114,7 @@ public Rule rule() {
113114
* @param wxMessage
114115
*/
115116
public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage) {
116-
if (messageDuplicateChecker.isDuplicate(wxMessage.getMsgId())) {
117+
if (isDuplicateMessage(wxMessage)) {
117118
// 如果是重复消息,那么就不做处理
118119
return null;
119120
}
@@ -175,6 +176,22 @@ public void run() {
175176
return res;
176177
}
177178

179+
protected boolean isDuplicateMessage(WxMpXmlMessage wxMessage) {
180+
181+
String messageId = "";
182+
if (wxMessage.getMsgId() == null) {
183+
messageId = wxMessage.getFromUserName() + "-" + String.valueOf(wxMessage.getCreateTime());
184+
} else {
185+
messageId = String.valueOf(wxMessage.getMsgId());
186+
}
187+
188+
if (messageDuplicateChecker.isDuplicate(messageId)) {
189+
return true;
190+
}
191+
return false;
192+
193+
}
194+
178195
/**
179196
* 对session的访问结束
180197
* @param wxMessage

0 commit comments

Comments
 (0)