@@ -6,7 +6,7 @@ package me.chanjar.weixin.common.util; | |||
* 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次 | |||
* </pre> | |||
*/ | |||
public interface WxMsgIdDuplicateChecker { | |||
public interface WxMessageDuplicateChecker { | |||
/** | |||
* 检查消息ID是否重复 |
@@ -10,7 +10,7 @@ import java.util.concurrent.atomic.AtomicBoolean; | |||
* 将每个消息id保存在内存里,每隔5秒清理已经过期的消息id,每个消息id的过期时间是15秒 | |||
* </pre> | |||
*/ | |||
public class WxMsgIdMemoryDuplicateChecker implements WxMsgIdDuplicateChecker { | |||
public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChecker { | |||
/** | |||
* 一个消息ID在内存的过期时间:15秒 | |||
@@ -39,7 +39,7 @@ public class WxMsgIdMemoryDuplicateChecker implements WxMsgIdDuplicateChecker { | |||
* 每隔多少周期检查消息ID是否过期:5秒 | |||
* </pre> | |||
*/ | |||
public WxMsgIdMemoryDuplicateChecker() { | |||
public WxMessageInMemoryDuplicateChecker() { | |||
this.timeToLive = 15 * 1000l; | |||
this.clearPeriod = 5 * 1000l; | |||
} | |||
@@ -49,7 +49,7 @@ public class WxMsgIdMemoryDuplicateChecker implements WxMsgIdDuplicateChecker { | |||
* @param timeToLive 一个消息ID在内存的过期时间:毫秒 | |||
* @param clearPeriod 每隔多少周期检查消息ID是否过期:毫秒 | |||
*/ | |||
public WxMsgIdMemoryDuplicateChecker(Long timeToLive, Long clearPeriod) { | |||
public WxMessageInMemoryDuplicateChecker(Long timeToLive, Long clearPeriod) { | |||
this.timeToLive = timeToLive; | |||
this.clearPeriod = clearPeriod; | |||
} |
@@ -4,11 +4,11 @@ import org.testng.Assert; | |||
import org.testng.annotations.Test; | |||
@Test | |||
public class WxMsgIdMemoryDuplicateCheckerTest { | |||
public class WxMessageInMemoryDuplicateCheckerTest { | |||
public void test() throws InterruptedException { | |||
Long[] msgIds = new Long[] { 1l, 2l, 3l, 4l, 5l, 6l, 7l, 8l }; | |||
WxMsgIdMemoryDuplicateChecker checker = new WxMsgIdMemoryDuplicateChecker(2000l, 1000l); | |||
WxMessageInMemoryDuplicateChecker checker = new WxMessageInMemoryDuplicateChecker(2000l, 1000l); | |||
// 第一次检查 | |||
for (Long msgId : msgIds) { |
@@ -7,7 +7,7 @@ | |||
<class name="me.chanjar.weixin.common.bean.WxErrorTest"/> | |||
<class name="me.chanjar.weixin.common.bean.WxMenuTest"/> | |||
<class name="me.chanjar.weixin.common.util.crypto.WxCryptUtilTest"/> | |||
<class name="me.chanjar.weixin.common.util.WxMsgIdMemoryDuplicateCheckerTest"/> | |||
<class name="me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateCheckerTest"/> | |||
</classes> | |||
</test> | |||
</suite> |
@@ -37,11 +37,11 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
this.expiresTime = 0; | |||
} | |||
public void updateAccessToken(WxAccessToken accessToken) { | |||
public synchronized void updateAccessToken(WxAccessToken accessToken) { | |||
updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
} | |||
public void updateAccessToken(String accessToken, int expiresInSeconds) { | |||
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { | |||
this.accessToken = accessToken; | |||
this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l; | |||
} | |||
@@ -1,7 +1,7 @@ | |||
package me.chanjar.weixin.cp.api; | |||
import me.chanjar.weixin.common.util.WxMsgIdDuplicateChecker; | |||
import me.chanjar.weixin.common.util.WxMsgIdMemoryDuplicateChecker; | |||
import me.chanjar.weixin.common.util.WxMessageDuplicateChecker; | |||
import me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker; | |||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | |||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | |||
@@ -43,7 +43,7 @@ import java.util.regex.Pattern; | |||
*/ | |||
public class WxCpMessageRouter { | |||
private static final int DEFAULT_THREAD_POOL_SIZE = 20; | |||
private static final int DEFAULT_THREAD_POOL_SIZE = 100; | |||
private final List<Rule> rules = new ArrayList<Rule>(); | |||
@@ -51,18 +51,12 @@ public class WxCpMessageRouter { | |||
private ExecutorService executorService; | |||
private WxMsgIdDuplicateChecker wxMsgIdDuplicateChecker; | |||
private WxMessageDuplicateChecker wxMessageDuplicateChecker; | |||
public WxCpMessageRouter(WxCpService wxCpService) { | |||
this.wxCpService = wxCpService; | |||
this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE); | |||
this.wxMsgIdDuplicateChecker = new WxMsgIdMemoryDuplicateChecker(); | |||
} | |||
public WxCpMessageRouter(WxCpService wxMpService, int threadPoolSize) { | |||
this.wxCpService = wxMpService; | |||
this.executorService = Executors.newFixedThreadPool(threadPoolSize); | |||
this.wxMsgIdDuplicateChecker = new WxMsgIdMemoryDuplicateChecker(); | |||
this.wxMessageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); | |||
} | |||
/** | |||
@@ -75,10 +69,10 @@ public class WxCpMessageRouter { | |||
/** | |||
* 设置自定义的WxMsgIdDuplicateChecker | |||
* @param wxMsgIdDuplicateChecker | |||
* @param wxMessageDuplicateChecker | |||
*/ | |||
public void setWxMsgIdDuplicateChecker(WxMsgIdDuplicateChecker wxMsgIdDuplicateChecker) { | |||
this.wxMsgIdDuplicateChecker = wxMsgIdDuplicateChecker; | |||
public void setWxMessageDuplicateChecker(WxMessageDuplicateChecker wxMessageDuplicateChecker) { | |||
this.wxMessageDuplicateChecker = wxMessageDuplicateChecker; | |||
} | |||
/** | |||
@@ -94,7 +88,7 @@ public class WxCpMessageRouter { | |||
* @param wxMessage | |||
*/ | |||
public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage) { | |||
if (wxMsgIdDuplicateChecker.isDuplicate(wxMessage.getMsgId())) { | |||
if (wxMessageDuplicateChecker.isDuplicate(wxMessage.getMsgId())) { | |||
// 如果是重复消息,那么就不做处理 | |||
return null; | |||
} | |||
@@ -152,7 +152,6 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||
this.http_proxy_password = http_proxy_password; | |||
} | |||
@Override | |||
public String toString() { | |||
return "WxMpInMemoryConfigStorage{" + | |||
@@ -166,6 +165,8 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||
", http_proxy_port=" + http_proxy_port + | |||
", http_proxy_username='" + http_proxy_username + '\'' + | |||
", http_proxy_password='" + http_proxy_password + '\'' + | |||
", jsapiTicket='" + jsapiTicket + '\'' + | |||
", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' + | |||
'}'; | |||
} | |||
@@ -4,14 +4,13 @@ import me.chanjar.weixin.common.session.InternalSession; | |||
import me.chanjar.weixin.common.session.SessionManagerImpl; | |||
import me.chanjar.weixin.common.session.WxSession; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.common.util.WxMsgIdDuplicateChecker; | |||
import me.chanjar.weixin.common.util.WxMsgIdMemoryDuplicateChecker; | |||
import me.chanjar.weixin.common.util.WxMessageDuplicateChecker; | |||
import me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import javax.swing.text.StyledEditorKit; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
@@ -52,7 +51,7 @@ public class WxMpMessageRouter { | |||
protected final Logger log = LoggerFactory.getLogger(WxMpMessageRouter.class); | |||
private static final int DEFAULT_THREAD_POOL_SIZE = 20; | |||
private static final int DEFAULT_THREAD_POOL_SIZE = 100; | |||
private final List<Rule> rules = new ArrayList<Rule>(); | |||
@@ -60,24 +59,22 @@ public class WxMpMessageRouter { | |||
private ExecutorService executorService; | |||
private WxMsgIdDuplicateChecker wxMsgIdDuplicateChecker; | |||
private WxMessageDuplicateChecker wxMessageDuplicateChecker; | |||
protected WxSessionManager sessionManager = new SessionManagerImpl(); | |||
private WxSessionManager sessionManager; | |||
public WxMpMessageRouter(WxMpService wxMpService) { | |||
this.wxMpService = wxMpService; | |||
this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE); | |||
this.wxMsgIdDuplicateChecker = new WxMsgIdMemoryDuplicateChecker(); | |||
} | |||
public WxMpMessageRouter(WxMpService wxMpService, int threadPoolSize) { | |||
this.wxMpService = wxMpService; | |||
this.executorService = Executors.newFixedThreadPool(threadPoolSize); | |||
this.wxMsgIdDuplicateChecker = new WxMsgIdMemoryDuplicateChecker(); | |||
this.wxMessageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); | |||
this.sessionManager = new SessionManagerImpl(); | |||
} | |||
/** | |||
* 设置自定义的ExecutorService | |||
* <pre> | |||
* 设置自定义的 {@link ExecutorService} | |||
* 如果不调用该方法,默认使用 Executors.newFixedThreadPool(100) | |||
* </pre> | |||
* @param executorService | |||
*/ | |||
public void setExecutorService(ExecutorService executorService) { | |||
@@ -85,11 +82,25 @@ public class WxMpMessageRouter { | |||
} | |||
/** | |||
* 设置自定义的WxMsgIdDuplicateChecker | |||
* @param wxMsgIdDuplicateChecker | |||
* <pre> | |||
* 设置自定义的 {@link me.chanjar.weixin.common.util.WxMessageDuplicateChecker} | |||
* 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker} | |||
* </pre> | |||
* @param wxMessageDuplicateChecker | |||
*/ | |||
public void setWxMessageDuplicateChecker(WxMessageDuplicateChecker wxMessageDuplicateChecker) { | |||
this.wxMessageDuplicateChecker = wxMessageDuplicateChecker; | |||
} | |||
/** | |||
* <pre> | |||
* 设置自定义的{@link me.chanjar.weixin.common.session.WxSessionManager} | |||
* 如果不调用该方法,默认使用 {@linke SessionManagerImpl} | |||
* </pre> | |||
* @param sessionManager | |||
*/ | |||
public void setWxMsgIdDuplicateChecker(WxMsgIdDuplicateChecker wxMsgIdDuplicateChecker) { | |||
this.wxMsgIdDuplicateChecker = wxMsgIdDuplicateChecker; | |||
public void setSessionManager(WxSessionManager sessionManager) { | |||
this.sessionManager = sessionManager; | |||
} | |||
/** | |||
@@ -105,7 +116,7 @@ public class WxMpMessageRouter { | |||
* @param wxMessage | |||
*/ | |||
public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage) { | |||
if (wxMsgIdDuplicateChecker.isDuplicate(wxMessage.getMsgId())) { | |||
if (wxMessageDuplicateChecker.isDuplicate(wxMessage.getMsgId())) { | |||
// 如果是重复消息,那么就不做处理 | |||
return null; | |||
} | |||
@@ -167,6 +178,10 @@ public class WxMpMessageRouter { | |||
return res; | |||
} | |||
/** | |||
* 对session的访问结束 | |||
* @param wxMessage | |||
*/ | |||
protected void sessionEndAccess(WxMpXmlMessage wxMessage) { | |||
WxSession session = sessionManager.getSession(wxMessage.getFromUserName(), false); | |||
if (session != null) { | |||