添加@ChannelHandler.Sharable

This commit is contained in:
jinyu 2016-11-01 11:34:35 +08:00
parent e02b1da3af
commit 363aa4bc9b
5 changed files with 73 additions and 48 deletions

View File

@ -1,5 +1,6 @@
package com.foxinmy.weixin4j.socket; package com.foxinmy.weixin4j.socket;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.handler.codec.MessageToMessageEncoder;
import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLogger;
@ -21,6 +22,7 @@ import com.foxinmy.weixin4j.util.ServerToolkits;
* @since JDK 1.6 * @since JDK 1.6
* @see com.foxinmy.weixin4j.response.SingleResponse * @see com.foxinmy.weixin4j.response.SingleResponse
*/ */
@ChannelHandler.Sharable
public class SingleResponseEncoder extends public class SingleResponseEncoder extends
MessageToMessageEncoder<SingleResponse> { MessageToMessageEncoder<SingleResponse> {

View File

@ -1,5 +1,6 @@
package com.foxinmy.weixin4j.socket; package com.foxinmy.weixin4j.socket;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest;
@ -31,6 +32,7 @@ import com.foxinmy.weixin4j.xml.EncryptMessageHandler;
* href="http://mp.weixin.qq.com/wiki/0/61c3a8b9d50ac74f18bdf2e54ddfc4e0.html">加密接入指引</a> * href="http://mp.weixin.qq.com/wiki/0/61c3a8b9d50ac74f18bdf2e54ddfc4e0.html">加密接入指引</a>
* @see com.foxinmy.weixin4j.request.WeixinRequest * @see com.foxinmy.weixin4j.request.WeixinRequest
*/ */
@ChannelHandler.Sharable
public class WeixinMessageDecoder extends public class WeixinMessageDecoder extends
MessageToMessageDecoder<FullHttpRequest> { MessageToMessageDecoder<FullHttpRequest> {
private final InternalLogger logger = InternalLoggerFactory private final InternalLogger logger = InternalLoggerFactory
@ -50,9 +52,7 @@ public class WeixinMessageDecoder extends
AesToken token = aesTokenMap.get(asetoken.getWeixinId()); AesToken token = aesTokenMap.get(asetoken.getWeixinId());
if (token != null) if (token != null)
return -1; return -1;
aesTokenMap.put(asetoken.getWeixinId(), asetoken); aesTokenMap.put(asetoken.getWeixinId(), asetoken);
return 0; return 0;
} }

View File

@ -1,5 +1,6 @@
package com.foxinmy.weixin4j.socket; package com.foxinmy.weixin4j.socket;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.handler.codec.MessageToMessageEncoder;
import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLogger;
@ -26,6 +27,7 @@ import com.foxinmy.weixin4j.util.ServerToolkits;
* href="http://mp.weixin.qq.com/wiki/0/61c3a8b9d50ac74f18bdf2e54ddfc4e0.html">加密接入指引</a> * href="http://mp.weixin.qq.com/wiki/0/61c3a8b9d50ac74f18bdf2e54ddfc4e0.html">加密接入指引</a>
* @see com.foxinmy.weixin4j.response.WeixinResponse * @see com.foxinmy.weixin4j.response.WeixinResponse
*/ */
@ChannelHandler.Sharable
public class WeixinResponseEncoder extends public class WeixinResponseEncoder extends
MessageToMessageEncoder<WeixinResponse> { MessageToMessageEncoder<WeixinResponse> {

View File

@ -38,7 +38,6 @@ public class WeixinServerInitializer extends ChannelInitializer<SocketChannel> {
@Override @Override
protected void initChannel(SocketChannel channel) { protected void initChannel(SocketChannel channel) {
ChannelPipeline pipeline = channel.pipeline(); ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536)); pipeline.addLast(new HttpObjectAggregator(65536));

View File

@ -45,7 +45,8 @@ import com.foxinmy.weixin4j.util.AesToken;
*/ */
public final class WeixinServerBootstrap { public final class WeixinServerBootstrap {
private final InternalLogger logger = InternalLoggerFactory.getInstance(getClass()); private final InternalLogger logger = InternalLoggerFactory
.getInstance(getClass());
/** /**
* boss线程数,默认设置为cpu的核数 * boss线程数,默认设置为cpu的核数
@ -99,7 +100,10 @@ public final class WeixinServerBootstrap {
/** /**
* 明文模式 & 兼容模式 & 密文模式 * 明文模式 & 兼容模式 & 密文模式
* <dl><font color="red">值得注意的是企业号服务时需要在服务器URL后面加多一个`encrypt_type=aes`的参数</font></dl> * <dl>
* <font
* color="red">值得注意的是企业号服务时需要在服务器URL后面加多一个`encrypt_type=aes`的参数</font>
* </dl>
* *
* @param weixinId * @param weixinId
* 公众号的应用ID(appid/corpid) 密文&兼容模式下需要填写 * 公众号的应用ID(appid/corpid) 密文&兼容模式下需要填写
@ -114,10 +118,14 @@ public final class WeixinServerBootstrap {
} }
/** /**
* 多个公众号的支持 * 多个公众号的支持 <dt>值得注意的是
* <dt>值得注意的是 * <dl>
* <dl><font color="red">1).企业号服务时需要在服务器URL后面加多一个`encrypt_type=aes`的参数</font></dl> * <font color="red">1).企业号服务时需要在服务器URL后面加多一个`encrypt_type=aes`的参数</font>
* <dl><font color="red">2).非明文模式下需要在服务器URL后面加多一个`weixin_id=对应的appid/corpid`的参数</font></dl> * </dl>
* <dl>
* <font
* color="red">2).非明文模式下需要在服务器URL后面加多一个`weixin_id=对应的appid/corpid`的参数</font>
* </dl>
* *
* @param aesTokens * @param aesTokens
* 多个公众号 * 多个公众号
@ -128,10 +136,14 @@ public final class WeixinServerBootstrap {
} }
/** /**
* 多个公众号的支持 * 多个公众号的支持 <dt>值得注意的是
* <dt>值得注意的是 * <dl>
* <dl><font color="red">1).企业号服务时需要在服务器URL后面加多一个`encrypt_type=aes`的参数</font></dl> * <font color="red">1).企业号服务时需要在服务器URL后面加多一个`encrypt_type=aes`的参数</font>
* <dl><font color="red">2).非明文模式下需要在服务器URL后面加多一个`weixin_id=对应的appid/corpid`的参数</font></dl> * </dl>
* <dl>
* <font
* color="red">2).非明文模式下需要在服务器URL后面加多一个`weixin_id=对应的appid/corpid`的参数</font>
* </dl>
* *
* @param messageMatcher * @param messageMatcher
* 消息匹配器 * 消息匹配器
@ -139,7 +151,8 @@ public final class WeixinServerBootstrap {
* 公众号信息 * 公众号信息
* @return * @return
*/ */
public WeixinServerBootstrap(WeixinMessageMatcher messageMatcher, AesToken... aesTokens) { public WeixinServerBootstrap(WeixinMessageMatcher messageMatcher,
AesToken... aesTokens) {
if (messageMatcher == null) { if (messageMatcher == null) {
throw new IllegalArgumentException("MessageMatcher not be null"); throw new IllegalArgumentException("MessageMatcher not be null");
} }
@ -184,7 +197,8 @@ public final class WeixinServerBootstrap {
* @return * @return
* @throws WeixinException * @throws WeixinException
*/ */
public void startup(int bossThreads, int workerThreads, final int serverPort) throws WeixinException { public void startup(int bossThreads, int workerThreads, final int serverPort)
throws WeixinException {
messageDispatcher.setMessageHandlerList(messageHandlerList); messageDispatcher.setMessageHandlerList(messageHandlerList);
messageDispatcher.setMessageInterceptorList(messageInterceptorList); messageDispatcher.setMessageInterceptorList(messageInterceptorList);
@ -192,19 +206,25 @@ public final class WeixinServerBootstrap {
EventLoopGroup workerGroup = new NioEventLoopGroup(workerThreads); EventLoopGroup workerGroup = new NioEventLoopGroup(workerThreads);
try { try {
wechatInitializer = new WeixinServerInitializer(aesTokenMap, messageDispatcher); wechatInitializer = new WeixinServerInitializer(aesTokenMap,
messageDispatcher);
ServerBootstrap b = new ServerBootstrap(); ServerBootstrap b = new ServerBootstrap();
b.option(ChannelOption.SO_BACKLOG, 1024); b.option(ChannelOption.SO_BACKLOG, 1024);
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).handler(new LoggingHandler()) b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler())
.childHandler(wechatInitializer); .childHandler(wechatInitializer);
Channel ch = b.bind(serverPort).addListener(new FutureListener<Void>() { Channel ch = b.bind(serverPort)
.addListener(new FutureListener<Void>() {
@Override @Override
public void operationComplete(Future<Void> future) throws Exception { public void operationComplete(Future<Void> future)
throws Exception {
if (future.isSuccess()) { if (future.isSuccess()) {
logger.info("weixin4j server startup OK:{}", serverPort); logger.info("weixin4j server startup OK:{}",
serverPort);
} else { } else {
logger.info("weixin4j server startup FAIL:{}", serverPort); logger.info("weixin4j server startup FAIL:{}",
serverPort);
} }
} }
}).sync().channel(); }).sync().channel();
@ -224,7 +244,8 @@ public final class WeixinServerBootstrap {
* 消息处理器 * 消息处理器
* @return * @return
*/ */
public WeixinServerBootstrap addHandler(WeixinMessageHandler... messageHandler) { public WeixinServerBootstrap addHandler(
WeixinMessageHandler... messageHandler) {
if (messageHandler == null) { if (messageHandler == null) {
throw new IllegalArgumentException("messageHandler not be null"); throw new IllegalArgumentException("messageHandler not be null");
} }
@ -239,7 +260,8 @@ public final class WeixinServerBootstrap {
* 消息拦截器 * 消息拦截器
* @return * @return
*/ */
public WeixinServerBootstrap addInterceptor(WeixinMessageInterceptor... messageInterceptor) { public WeixinServerBootstrap addInterceptor(
WeixinMessageInterceptor... messageInterceptor) {
if (messageInterceptor == null) { if (messageInterceptor == null) {
throw new IllegalArgumentException("messageInterceptor not be null"); throw new IllegalArgumentException("messageInterceptor not be null");
} }
@ -254,9 +276,11 @@ public final class WeixinServerBootstrap {
* 消息处理器所在的包名 * 消息处理器所在的包名
* @return * @return
*/ */
public WeixinServerBootstrap handlerPackagesToScan(String... messageHandlerPackages) { public WeixinServerBootstrap handlerPackagesToScan(
String... messageHandlerPackages) {
if (messageHandlerPackages == null) { if (messageHandlerPackages == null) {
throw new IllegalArgumentException("messageHandlerPackages not be null"); throw new IllegalArgumentException(
"messageHandlerPackages not be null");
} }
messageDispatcher.setMessageHandlerPackages(messageHandlerPackages); messageDispatcher.setMessageHandlerPackages(messageHandlerPackages);
return this; return this;
@ -269,11 +293,14 @@ public final class WeixinServerBootstrap {
* 消息拦截器所在的包名 * 消息拦截器所在的包名
* @return * @return
*/ */
public WeixinServerBootstrap interceptorPackagesToScan(String... messageInterceptorPackages) { public WeixinServerBootstrap interceptorPackagesToScan(
String... messageInterceptorPackages) {
if (messageInterceptorPackages == null) { if (messageInterceptorPackages == null) {
throw new IllegalArgumentException("messageInterceptorPackages not be null"); throw new IllegalArgumentException(
"messageInterceptorPackages not be null");
} }
messageDispatcher.setMessageInterceptorPackages(messageInterceptorPackages); messageDispatcher
.setMessageInterceptorPackages(messageInterceptorPackages);
return this; return this;
} }
@ -298,7 +325,8 @@ public final class WeixinServerBootstrap {
* 消息类 * 消息类
* @return * @return
*/ */
public WeixinServerBootstrap registMessageClass(WeixinMessageKey messageKey, public WeixinServerBootstrap registMessageClass(
WeixinMessageKey messageKey,
Class<? extends WeixinMessage> messageClass) { Class<? extends WeixinMessage> messageClass) {
messageDispatcher.registMessageClass(messageKey, messageClass); messageDispatcher.registMessageClass(messageKey, messageClass);
return this; return this;
@ -312,19 +340,13 @@ public final class WeixinServerBootstrap {
return this; return this;
} }
/** /**
* aesTokenMap 最好是线程安全的 * aesTokenMap 最好是线程安全的
*
* @param aesToken * @param aesToken
* @return * @return
*/ */
public int addAesToken(AesToken aesToken) { public int addAesToken(AesToken aesToken) {
AesToken token = aesTokenMap.get(aesToken.getWeixinId());
if (token != null)
return -1;
this.aesTokenMap.put(aesToken.getWeixinId(), aesToken);
return wechatInitializer.addAesToken(aesToken); return wechatInitializer.addAesToken(aesToken);
} }