├── dubbo-remoting-newnetty ├── .gitignore ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ ├── org.maven.ide.eclipse.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── dubbo │ │ │ └── internal │ │ │ └── com.alibaba.dubbo.remoting.Transporter │ │ └── java │ │ └── com │ │ └── yam │ │ └── dubbo │ │ └── remoting │ │ └── transport │ │ └── netty │ │ ├── NettyTransporter.java │ │ ├── NettyHelper.java │ │ ├── NettyHandler.java │ │ ├── NettyServer.java │ │ ├── NettyCodecAdapter.java │ │ ├── NettyChannel.java │ │ └── NettyClient.java ├── .project ├── pom.xml └── .classpath ├── dubbo-serialize-protobuf ├── .gitignore ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── dubbo │ │ │ └── internal │ │ │ └── com.alibaba.dubbo.common.serialize.Serialization │ │ └── java │ │ └── com │ │ └── yam │ │ └── dubbo │ │ └── serialize │ │ └── protobuf │ │ ├── SpecialSerializeFactory.java │ │ ├── Hessian2WithProtobufSerialization.java │ │ ├── Hessian2WithSpecialObjectOutput.java │ │ ├── ProtobufSerializeFactory.java │ │ ├── Hessian2WithSpecialObjectInput.java │ │ └── ProtobufUtil.java ├── .project ├── pom.xml └── .classpath ├── .gitignore └── README.md /dubbo-remoting-newnetty/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.remoting.Transporter: -------------------------------------------------------------------------------- 1 | newnetty=com.yam.dubbo.remoting.transport.netty.NettyTransporter -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.common.serialize.Serialization: -------------------------------------------------------------------------------- 1 | protobufmix=com.yam.dubbo.serialize.protobuf.Hessian2WithProtobufSerialization 2 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding/=UTF-8 6 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding/=UTF-8 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # ignore folder # 12 | target 13 | 14 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 15 | hs_err_pid* 16 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/.settings/org.maven.ide.eclipse.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | fullBuildGoals=process-test-resources 4 | resolveWorkspaceProjects=true 5 | resourceFilterGoals=process-resources resources\:testResources 6 | skipCompilerPlugin=true 7 | version=1 8 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 4 | org.eclipse.jdt.core.compiler.compliance=1.5 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.5 9 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 4 | org.eclipse.jdt.core.compiler.compliance=1.6 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.6 9 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | dubbo-serialize-protobuf 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dubbo-ext 2 | dubbo extension 3 | 在[原生dubbo](https://github.com/alibaba/dubbo) 的基础上做功能扩展,目前主要是在2.5.4-SNAPSHOT的基础上扩展,如果用于其他版本需要自测。 4 | 5 | ###1.dubbo-serialize-protobuf 6 | dubbo的默认序列化方式hessian是不支持protobuf的,要支持protobuf需要使用java默认的序列化。 7 | 8 | protobuf虽然对java默认序列化有支持,但如果应用中还是用了非protobuf的实体,采用java序列化效率就低了。 9 | 10 | dubbo-serialize-protobuf在hessian的基础上进行扩展,对于普通实体依然采用hessian,对于protobuf则直接利用protobuf框架的能力。让你的应用既可以支持protobuf实体,也可以支持普通的java对象,且保持高效率。 11 | 12 | 使用方式: 13 | 14 | 15 | 16 | ###2.dubbu-remoting-newnetty 17 | dubbo使用netty3作为其默认的网络传输框架。而netty目前已经发展到netty4(稳定版),netty4中引入了内存池,能够大大降低gc的频率。由于netty3与netty4无法兼容,这里将dubbo中的netty3升级到了netty4。 18 | 19 | 使用方式: 20 | 21 | 22 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | dubbo-remoting-newnetty 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.maven.ide.eclipse.maven2Builder 15 | 16 | 17 | 18 | 19 | org.eclipse.m2e.core.maven2Builder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.m2e.core.maven2Nature 26 | org.eclipse.jdt.core.javanature 27 | org.maven.ide.eclipse.maven2Nature 28 | 29 | 30 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/src/main/java/com/yam/dubbo/serialize/protobuf/SpecialSerializeFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.serialize.protobuf; 9 | 10 | import java.io.IOException; 11 | 12 | /** 13 | * 14 | * @Description: TODO 15 | * @author youaremoon 16 | * @date 2015年12月25日 下午10:01:01 17 | * 18 | */ 19 | public interface SpecialSerializeFactory { 20 | 21 | /** 22 | * 是否支持指定类型的反序列化 23 | * @param 24 | * @return 25 | */ 26 | boolean supportDeserialize(int type); 27 | 28 | /** 29 | * 解析数据 30 | * @param 31 | * @return 32 | */ 33 | Object parse(Hessian2WithSpecialObjectInput input) throws IOException; 34 | 35 | /** 36 | * 尝试序列化指定对象,如果无法处理则返回false 37 | * @param 38 | * @return 39 | */ 40 | boolean trySerializeObject(Hessian2WithSpecialObjectOutput output, Object obj) throws IOException; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/src/main/java/com/yam/dubbo/remoting/transport/netty/NettyTransporter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.remoting.transport.netty; 9 | 10 | import com.alibaba.dubbo.common.URL; 11 | import com.alibaba.dubbo.remoting.ChannelHandler; 12 | import com.alibaba.dubbo.remoting.Client; 13 | import com.alibaba.dubbo.remoting.RemotingException; 14 | import com.alibaba.dubbo.remoting.Server; 15 | import com.alibaba.dubbo.remoting.Transporter; 16 | 17 | /** 18 | * @Description: 新版本(4.0以上)的netty集成 19 | * @author youaremoon 20 | * @date 2015年12月25日 下午9:55:17 21 | * 22 | */ 23 | public class NettyTransporter implements Transporter { 24 | 25 | public static final String NAME = "newnetty"; 26 | 27 | public Server bind(URL url, ChannelHandler listener) throws RemotingException { 28 | return new NettyServer(url, listener); 29 | } 30 | 31 | public Client connect(URL url, ChannelHandler listener) throws RemotingException { 32 | return new NettyClient(url, listener); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.yam.dubbo 5 | dubbo-serialize-protobuf 6 | 0.0.1-SNAPSHOT 7 | jar 8 | 9 | ${project.artifactId} 10 | support protobuf in dubbo project 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | true 16 | 17 | 18 | 19 | 20 | com.alibaba 21 | dubbo-common 22 | 2.5.4-SNAPSHOT 23 | 24 | 25 | com.google.protobuf 26 | protobuf-java 27 | 2.6.1 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.yam.dubbo 5 | dubbo-remoting-newnetty 6 | 0.0.1-SNAPSHOT 7 | jar 8 | 9 | ${project.artifactId} 10 | The netty4 remoting module of dubbo project 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | true 16 | 17 | 18 | 19 | 20 | com.alibaba 21 | dubbo-remoting-api 22 | 2.5.4-SNAPSHOT 23 | 24 | 25 | 26 | io.netty 27 | netty-all 28 | 4.0.33.Final 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/src/main/java/com/yam/dubbo/remoting/transport/netty/NettyHelper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.remoting.transport.netty; 9 | 10 | import io.netty.buffer.ByteBuf; 11 | 12 | import com.alibaba.dubbo.remoting.buffer.ChannelBuffer; 13 | 14 | /** 15 | * 16 | * @Description: TODO 17 | * @author youaremoon 18 | * @date 2015年12月25日 下午9:57:25 19 | * 20 | */ 21 | final class NettyHelper { 22 | 23 | /** 24 | * 从ByteBuf获取byte[]数据 25 | * @param 26 | * @return 27 | */ 28 | public static byte[] getBytesFromByteBuf(ByteBuf bb) { 29 | byte[] data = null; 30 | 31 | int readableBytes = bb.readableBytes(); 32 | if(bb.hasArray() && bb.arrayOffset() == 0 && readableBytes == bb.capacity()) { 33 | data = bb.array(); 34 | } else { 35 | data = new byte[readableBytes]; 36 | bb.getBytes(0, data, 0, readableBytes); 37 | } 38 | 39 | return data; 40 | } 41 | 42 | public static byte[] getBytesFromChannelBuffer(ChannelBuffer cb) { 43 | byte[] data; 44 | 45 | int readableBytes = cb.readableBytes(); 46 | if (cb.hasArray() && cb.arrayOffset() == 0 && readableBytes == cb.capacity()) { 47 | data = cb.array(); 48 | } else { 49 | data = new byte[readableBytes]; 50 | cb.getBytes(0, data, 0, readableBytes); 51 | } 52 | 53 | return data; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/src/main/java/com/yam/dubbo/serialize/protobuf/Hessian2WithProtobufSerialization.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.serialize.protobuf; 9 | 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.io.OutputStream; 13 | 14 | import com.alibaba.dubbo.common.URL; 15 | import com.alibaba.dubbo.common.extension.Adaptive; 16 | import com.alibaba.dubbo.common.serialize.ObjectInput; 17 | import com.alibaba.dubbo.common.serialize.ObjectOutput; 18 | import com.alibaba.dubbo.common.serialize.Serialization; 19 | 20 | /** 21 | * 22 | * @Description: TODO 23 | * @author youaremoon 24 | * @date 2015年12月25日 下午9:59:54 25 | * 26 | */ 27 | public class Hessian2WithProtobufSerialization implements Serialization { 28 | 29 | @Override 30 | public byte getContentTypeId() { 31 | return 17; 32 | } 33 | 34 | @Override 35 | public String getContentType() { 36 | return "x-application/hessian2-spec"; 37 | } 38 | 39 | @Override 40 | @Adaptive 41 | public ObjectOutput serialize(URL url, OutputStream output) throws IOException { 42 | return new Hessian2WithSpecialObjectOutput(output, ProtobufSerializeFactory.INSTANCE); 43 | } 44 | 45 | @Override 46 | @Adaptive 47 | public ObjectInput deserialize(URL url, InputStream input) throws IOException { 48 | return new Hessian2WithSpecialObjectInput(input, ProtobufSerializeFactory.INSTANCE); 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/src/main/java/com/yam/dubbo/serialize/protobuf/Hessian2WithSpecialObjectOutput.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.serialize.protobuf; 9 | 10 | import java.io.IOException; 11 | import java.io.OutputStream; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | import com.alibaba.dubbo.common.serialize.support.hessian.Hessian2ObjectOutput; 16 | 17 | /** 18 | * 19 | * @Description: TODO 20 | * @author youaremoon 21 | * @date 2015年12月25日 下午10:00:27 22 | * 23 | */ 24 | public class Hessian2WithSpecialObjectOutput extends Hessian2ObjectOutput { 25 | 26 | private List factoryList; 27 | 28 | public Hessian2WithSpecialObjectOutput(OutputStream os) { 29 | super(os); 30 | } 31 | 32 | public Hessian2WithSpecialObjectOutput(OutputStream os, SpecialSerializeFactory... factories) { 33 | super(os); 34 | 35 | if (null != factories) { 36 | factoryList = new ArrayList(); 37 | for (SpecialSerializeFactory factory : factories) { 38 | factoryList.add(factory); 39 | } 40 | } 41 | } 42 | 43 | public void addSerializeFactory(SpecialSerializeFactory factory) { 44 | if (null == factoryList) { 45 | factoryList = new ArrayList(); 46 | } 47 | 48 | factoryList.add(factory); 49 | } 50 | 51 | public void writeObject(Object obj) throws IOException { 52 | if (null != factoryList) { 53 | for (SpecialSerializeFactory factory : factoryList) { 54 | if (factory.trySerializeObject(this, obj)) { 55 | return; 56 | } 57 | } 58 | } 59 | 60 | // 无法处理则按照正常的hessian写入 61 | super.writeInt(ProtobufUtil.TYPE_NORMAL); 62 | super.writeObject(obj); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/src/main/java/com/yam/dubbo/serialize/protobuf/ProtobufSerializeFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.serialize.protobuf; 9 | 10 | import java.io.IOException; 11 | 12 | import com.google.protobuf.MessageLite; 13 | 14 | /** 15 | * 16 | * @Description: TODO 17 | * @author youaremoon 18 | * @date 2015年12月25日 下午10:00:38 19 | * 20 | */ 21 | public class ProtobufSerializeFactory implements SpecialSerializeFactory { 22 | 23 | public static final ProtobufSerializeFactory INSTANCE = new ProtobufSerializeFactory(); 24 | 25 | @Override 26 | public boolean supportDeserialize(int type) { 27 | if (type == ProtobufUtil.TYPE_PROTOBUF) { 28 | return true; 29 | } 30 | 31 | return false; 32 | } 33 | 34 | @Override 35 | public Object parse(Hessian2WithSpecialObjectInput input) throws IOException { 36 | String className = input.readUTF(); 37 | byte[] data = input.readBytes(); 38 | 39 | return ProtobufUtil.parseFrom(className, data); 40 | } 41 | 42 | @Override 43 | public boolean trySerializeObject(Hessian2WithSpecialObjectOutput output, Object obj) throws IOException { 44 | int type = ProtobufUtil.TYPE_NORMAL; 45 | boolean isMessageLiteBuilder = false; 46 | if (obj instanceof MessageLite.Builder) { 47 | isMessageLiteBuilder = true; 48 | type = ProtobufUtil.TYPE_PROTOBUF; 49 | } else if (obj instanceof MessageLite) { 50 | type = ProtobufUtil.TYPE_PROTOBUF; 51 | } 52 | 53 | if (type == ProtobufUtil.TYPE_PROTOBUF) { 54 | // 如果是protobuf则按照protobuf写入数据 55 | output.writeInt(ProtobufUtil.TYPE_PROTOBUF); //标记位 56 | output.writeUTF(obj.getClass().getName()); //class name 57 | if (isMessageLiteBuilder) { 58 | output.writeBytes(((MessageLite.Builder)obj).build().toByteArray()); //数据 59 | } else { 60 | output.writeBytes(((MessageLite)obj).toByteArray()); //数据 61 | } 62 | 63 | return true; 64 | } 65 | 66 | return false; 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/src/main/java/com/yam/dubbo/serialize/protobuf/Hessian2WithSpecialObjectInput.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.serialize.protobuf; 9 | 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.lang.reflect.Type; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | import com.alibaba.dubbo.common.serialize.support.hessian.Hessian2ObjectInput; 17 | 18 | /** 19 | * 20 | * @Description: TODO 21 | * @author youaremoon 22 | * @date 2015年12月25日 下午10:00:05 23 | * 24 | */ 25 | public class Hessian2WithSpecialObjectInput extends Hessian2ObjectInput { 26 | 27 | private List factoryList; 28 | 29 | public Hessian2WithSpecialObjectInput(InputStream is) { 30 | super(is); 31 | } 32 | 33 | public Hessian2WithSpecialObjectInput(InputStream is, SpecialSerializeFactory... factories) { 34 | super(is); 35 | 36 | if (null != factories) { 37 | factoryList = new ArrayList(); 38 | for (SpecialSerializeFactory factory : factories) { 39 | factoryList.add(factory); 40 | } 41 | } 42 | } 43 | 44 | public void addSerializeFactory(SpecialSerializeFactory factory) { 45 | if (null == factoryList) { 46 | factoryList = new ArrayList(); 47 | } 48 | 49 | factoryList.add(factory); 50 | } 51 | 52 | @Override 53 | public Object readObject() throws IOException { 54 | // 根据标记位判断Object类型 55 | int type = super.readInt(); 56 | if (null != factoryList) { 57 | for (SpecialSerializeFactory factory : factoryList) { 58 | if (factory.supportDeserialize(type)) { 59 | return factory.parse(this); 60 | } 61 | } 62 | } 63 | 64 | return super.readObject(); 65 | } 66 | 67 | @SuppressWarnings("unchecked") 68 | public T readObject(Class cls) throws IOException, ClassNotFoundException { 69 | return (T)readObject(); 70 | } 71 | 72 | @SuppressWarnings("unchecked") 73 | public T readObject(Class cls, Type type) throws IOException, ClassNotFoundException { 74 | return (T)readObject(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /dubbo-serialize-protobuf/src/main/java/com/yam/dubbo/serialize/protobuf/ProtobufUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.serialize.protobuf; 9 | 10 | import java.io.IOException; 11 | import java.lang.reflect.InvocationTargetException; 12 | import java.lang.reflect.Method; 13 | import java.util.Map; 14 | import java.util.concurrent.ConcurrentHashMap; 15 | 16 | import com.google.protobuf.MessageLite; 17 | 18 | 19 | /** 20 | * 21 | * @Description: TODO 22 | * @author youaremoon 23 | * @date 2015年12月25日 下午10:00:46 24 | * 25 | */ 26 | public class ProtobufUtil { 27 | /** 28 | * 普通的Object 29 | */ 30 | public static final int TYPE_NORMAL = 0; 31 | 32 | /** 33 | * protobuf类型的对象 34 | */ 35 | public static final int TYPE_PROTOBUF = 1; 36 | 37 | private static final String BUILDER_CLASS_SUFFIX = "$Builder"; 38 | 39 | private static final Map BUILDER_CACHE = new ConcurrentHashMap(); 40 | 41 | /** 42 | * 根据protobuf类型解析 43 | * @param 44 | * @return 45 | */ 46 | public static Object parseFrom(String className, byte[] data) throws IOException { 47 | try { 48 | boolean isBuilderClass = className.endsWith(BUILDER_CLASS_SUFFIX); 49 | if (isBuilderClass) { 50 | className = className.substring(0, className.length() - BUILDER_CLASS_SUFFIX.length()); 51 | } 52 | 53 | MessageLite.Builder builder = getPbBuilder(className); 54 | builder.mergeFrom(data); 55 | 56 | if (isBuilderClass) { 57 | return builder; 58 | } else { 59 | return builder.buildPartial(); 60 | } 61 | } catch (Exception ex) { 62 | if (ex instanceof IOException) { 63 | throw (IOException)ex; 64 | } else { 65 | throw new IOException(ex); 66 | } 67 | } 68 | } 69 | 70 | @SuppressWarnings({ "rawtypes", "unchecked" }) 71 | private static MessageLite.Builder getPbBuilder(String className) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { 72 | MessageLite.Builder builder = BUILDER_CACHE.get(className); 73 | if (null == builder) { 74 | Class messageClass = Class.forName(className); 75 | 76 | Method newBuilder = messageClass.getMethod("newBuilder"); 77 | builder = (MessageLite.Builder)newBuilder.invoke(null); 78 | 79 | BUILDER_CACHE.put(className, builder); 80 | } 81 | 82 | return builder.clone(); 83 | } 84 | } 85 | 86 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/src/main/java/com/yam/dubbo/remoting/transport/netty/NettyHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.remoting.transport.netty; 9 | 10 | import io.netty.channel.ChannelDuplexHandler; 11 | import io.netty.channel.ChannelHandler.Sharable; 12 | import io.netty.channel.ChannelHandlerContext; 13 | import io.netty.channel.ChannelPipeline; 14 | import io.netty.channel.ChannelPromise; 15 | 16 | import java.net.InetSocketAddress; 17 | import java.util.Map; 18 | import java.util.concurrent.ConcurrentHashMap; 19 | 20 | import com.alibaba.dubbo.common.URL; 21 | import com.alibaba.dubbo.common.utils.NetUtils; 22 | import com.alibaba.dubbo.remoting.Channel; 23 | import com.alibaba.dubbo.remoting.ChannelHandler; 24 | 25 | /** 26 | * 27 | * @Description: TODO 28 | * @author youaremoon 29 | * @date 2015年12月25日 下午9:57:18 30 | * 31 | */ 32 | @Sharable 33 | public class NettyHandler extends ChannelDuplexHandler { 34 | 35 | private final Map channels = new ConcurrentHashMap(); // 36 | 37 | private final URL url; 38 | 39 | private final ChannelHandler handler; 40 | 41 | public NettyHandler(URL url, ChannelHandler handler){ 42 | if (url == null) { 43 | throw new IllegalArgumentException("url == null"); 44 | } 45 | if (handler == null) { 46 | throw new IllegalArgumentException("handler == null"); 47 | } 48 | this.url = url; 49 | this.handler = handler; 50 | } 51 | 52 | public Map getChannels() { 53 | return channels; 54 | } 55 | 56 | @Override 57 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 58 | NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler); 59 | try { 60 | if (channel != null) { 61 | channels.put(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()), channel); 62 | } 63 | handler.connected(channel); 64 | } finally { 65 | NettyChannel.removeChannelIfDisconnected(ctx.channel()); 66 | } 67 | } 68 | 69 | /** 70 | * Calls {@link ChannelHandlerContext#fireChannelInactive()} to forward 71 | * to the next {@link ChannelHandler} in the {@link ChannelPipeline}. 72 | * 73 | * Sub-classes may override this method to change behavior. 74 | */ 75 | @Override 76 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 77 | NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler); 78 | try { 79 | channels.remove(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress())); 80 | handler.disconnected(channel); 81 | } finally { 82 | NettyChannel.removeChannelIfDisconnected(ctx.channel()); 83 | } 84 | } 85 | 86 | @Override 87 | public void channelRead(ChannelHandlerContext ctx, Object msg) 88 | throws Exception { 89 | NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler); 90 | try { 91 | handler.received(channel, msg); 92 | } finally { 93 | NettyChannel.removeChannelIfDisconnected(ctx.channel()); 94 | } 95 | } 96 | 97 | @Override 98 | public void write(ChannelHandlerContext ctx, final Object msg, ChannelPromise promise) throws Exception { 99 | ctx.writeAndFlush(msg, promise); 100 | NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler); 101 | try { 102 | handler.sent(channel, msg); 103 | } finally { 104 | NettyChannel.removeChannelIfDisconnected(ctx.channel()); 105 | } 106 | } 107 | 108 | @Override 109 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception { 110 | NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler); 111 | try { 112 | handler.caught(channel, e.getCause()); 113 | } finally { 114 | NettyChannel.removeChannelIfDisconnected(ctx.channel()); 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/src/main/java/com/yam/dubbo/remoting/transport/netty/NettyServer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.remoting.transport.netty; 9 | 10 | import io.netty.bootstrap.ServerBootstrap; 11 | import io.netty.channel.ChannelInitializer; 12 | import io.netty.channel.ChannelOption; 13 | import io.netty.channel.ChannelPipeline; 14 | import io.netty.channel.nio.NioEventLoopGroup; 15 | import io.netty.channel.socket.SocketChannel; 16 | import io.netty.channel.socket.nio.NioServerSocketChannel; 17 | 18 | import java.net.InetSocketAddress; 19 | import java.util.Collection; 20 | import java.util.HashSet; 21 | import java.util.Map; 22 | 23 | import com.alibaba.dubbo.common.Constants; 24 | import com.alibaba.dubbo.common.URL; 25 | import com.alibaba.dubbo.common.logger.Logger; 26 | import com.alibaba.dubbo.common.logger.LoggerFactory; 27 | import com.alibaba.dubbo.common.utils.ExecutorUtil; 28 | import com.alibaba.dubbo.common.utils.NamedThreadFactory; 29 | import com.alibaba.dubbo.common.utils.NetUtils; 30 | import com.alibaba.dubbo.remoting.Channel; 31 | import com.alibaba.dubbo.remoting.ChannelHandler; 32 | import com.alibaba.dubbo.remoting.RemotingException; 33 | import com.alibaba.dubbo.remoting.Server; 34 | import com.alibaba.dubbo.remoting.transport.AbstractServer; 35 | import com.alibaba.dubbo.remoting.transport.dispatcher.ChannelHandlers; 36 | 37 | /** 38 | * 39 | * @Description: TODO 40 | * @author youaremoon 41 | * @date 2015年12月25日 下午9:56:02 42 | * 43 | */ 44 | public class NettyServer extends AbstractServer implements Server { 45 | private static final Logger logger = LoggerFactory.getLogger(NettyServer.class); 46 | 47 | private Map channels; // 48 | 49 | private ServerBootstrap bootstrap; 50 | 51 | private io.netty.channel.Channel channel; 52 | 53 | public NettyServer(URL url, ChannelHandler handler) throws RemotingException{ 54 | super(url, ChannelHandlers.wrap(handler, ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME))); 55 | } 56 | 57 | @Override 58 | protected void doOpen() throws Throwable { 59 | ServerBootstrap bootstrap = new ServerBootstrap(); 60 | //reuseAddress选项设置为true将允许将套接字绑定到已在使用中的地址 61 | bootstrap.childOption(ChannelOption.TCP_NODELAY, true); 62 | //keep-alive 63 | bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); 64 | 65 | int childThreadCount = getUrl().getPositiveParameter(Constants.IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS); 66 | 67 | bootstrap.group(new NioEventLoopGroup(0, new NamedThreadFactory("NettyParentGroup", true)), 68 | new NioEventLoopGroup(childThreadCount, new NamedThreadFactory("NettyChildGroup", true))) 69 | .channel(NioServerSocketChannel.class) 70 | .localAddress(getBindAddress()); 71 | 72 | final NettyHandler nettyHandler = new NettyHandler(getUrl(), this); 73 | channels = nettyHandler.getChannels(); 74 | bootstrap.childHandler(new ChannelInitializer() { 75 | @Override 76 | protected void initChannel(SocketChannel ch) throws Exception { 77 | NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec() ,getUrl(), NettyServer.this); 78 | ChannelPipeline pipeline = ch.pipeline(); 79 | /*int idleTimeout = getIdleTimeout(); 80 | if (idleTimeout > 10000) { 81 | pipeline.addLast("timer", new IdleStateHandler(timer, idleTimeout / 1000, 0, 0)); 82 | }*/ 83 | pipeline.addLast("decoder", adapter.getDecoder()); 84 | pipeline.addLast("encoder", adapter.getEncoder()); 85 | pipeline.addLast("handler", nettyHandler); 86 | } 87 | }); 88 | 89 | // bind 90 | channel = bootstrap.bind().sync().channel(); 91 | } 92 | 93 | @Override 94 | protected void doClose() throws Throwable { 95 | try { 96 | if (channel != null) { 97 | // unbind. 98 | channel.close(); 99 | } 100 | } catch (Throwable e) { 101 | logger.warn(e.getMessage(), e); 102 | } 103 | try { 104 | Collection channels = getChannels(); 105 | if (channels != null && channels.size() > 0) { 106 | for (com.alibaba.dubbo.remoting.Channel channel : channels) { 107 | try { 108 | channel.close(); 109 | } catch (Throwable e) { 110 | logger.warn(e.getMessage(), e); 111 | } 112 | } 113 | } 114 | } catch (Throwable e) { 115 | logger.warn(e.getMessage(), e); 116 | } 117 | try { 118 | if (bootstrap != null) { 119 | // release external resource. 120 | bootstrap.group().shutdownGracefully(); 121 | bootstrap.childGroup().shutdownGracefully(); 122 | } 123 | } catch (Throwable e) { 124 | logger.warn(e.getMessage(), e); 125 | } 126 | try { 127 | if (channels != null) { 128 | channels.clear(); 129 | } 130 | } catch (Throwable e) { 131 | logger.warn(e.getMessage(), e); 132 | } 133 | } 134 | 135 | public Collection getChannels() { 136 | Collection chs = new HashSet(); 137 | for (Channel channel : this.channels.values()) { 138 | if (channel.isConnected()) { 139 | chs.add(channel); 140 | } else { 141 | channels.remove(NetUtils.toAddressString(channel.getRemoteAddress())); 142 | } 143 | } 144 | return chs; 145 | } 146 | 147 | public Channel getChannel(InetSocketAddress remoteAddress) { 148 | return channels.get(NetUtils.toAddressString(remoteAddress)); 149 | } 150 | 151 | public boolean isBound() { 152 | return channel.isRegistered(); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/src/main/java/com/yam/dubbo/remoting/transport/netty/NettyCodecAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.remoting.transport.netty; 9 | 10 | import io.netty.buffer.ByteBuf; 11 | import io.netty.channel.ChannelHandler; 12 | import io.netty.channel.ChannelHandler.Sharable; 13 | import io.netty.channel.ChannelHandlerContext; 14 | import io.netty.handler.codec.MessageToMessageDecoder; 15 | import io.netty.handler.codec.MessageToMessageEncoder; 16 | 17 | import java.io.IOException; 18 | import java.util.List; 19 | 20 | import com.alibaba.dubbo.common.Constants; 21 | import com.alibaba.dubbo.common.URL; 22 | import com.alibaba.dubbo.remoting.Codec2; 23 | import com.alibaba.dubbo.remoting.buffer.DynamicChannelBuffer; 24 | 25 | /** 26 | * 27 | * @Description: TODO 28 | * @author youaremoon 29 | * @date 2015年12月25日 下午9:57:13 30 | * 31 | */ 32 | final class NettyCodecAdapter { 33 | 34 | private final ChannelHandler encoder = new InternalEncoder(); 35 | 36 | private final ChannelHandler decoder = new InternalDecoder2(); 37 | 38 | private final Codec2 codec; 39 | 40 | private final URL url; 41 | 42 | private final int bufferSize; 43 | 44 | private final com.alibaba.dubbo.remoting.ChannelHandler handler; 45 | 46 | public NettyCodecAdapter(Codec2 codec, URL url, com.alibaba.dubbo.remoting.ChannelHandler handler) { 47 | this.codec = codec; 48 | this.url = url; 49 | this.handler = handler; 50 | int b = url.getPositiveParameter(Constants.BUFFER_KEY, Constants.DEFAULT_BUFFER_SIZE); 51 | this.bufferSize = b >= Constants.MIN_BUFFER_SIZE && b <= Constants.MAX_BUFFER_SIZE ? b : Constants.DEFAULT_BUFFER_SIZE; 52 | } 53 | 54 | public ChannelHandler getEncoder() { 55 | return encoder; 56 | } 57 | 58 | public ChannelHandler getDecoder() { 59 | return decoder; 60 | } 61 | 62 | @Sharable 63 | private class InternalEncoder extends MessageToMessageEncoder { 64 | 65 | @Override 66 | protected void encode(ChannelHandlerContext ctx, Object msg, List out) throws Exception { 67 | com.alibaba.dubbo.remoting.buffer.ChannelBuffer buffer = 68 | com.alibaba.dubbo.remoting.buffer.ChannelBuffers.dynamicBuffer(1024); 69 | NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler); 70 | try { 71 | codec.encode(channel, buffer, msg); 72 | } finally { 73 | NettyChannel.removeChannelIfDisconnected(ctx.channel()); 74 | } 75 | 76 | ByteBuf bb = ctx.alloc().buffer().writeBytes(NettyHelper.getBytesFromChannelBuffer(buffer)); 77 | out.add(bb); 78 | } 79 | } 80 | 81 | private class InternalDecoder2 extends MessageToMessageDecoder { 82 | private com.alibaba.dubbo.remoting.buffer.ChannelBuffer buffer = 83 | com.alibaba.dubbo.remoting.buffer.ChannelBuffers.EMPTY_BUFFER; 84 | 85 | @Override 86 | protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List out) throws Exception { 87 | int readable = buf.readableBytes(); 88 | if (readable <= 0) { 89 | return; 90 | } 91 | 92 | byte[] writeBytes = NettyHelper.getBytesFromByteBuf(buf); 93 | com.alibaba.dubbo.remoting.buffer.ChannelBuffer message; 94 | if (buffer.readable()) { 95 | if (buffer instanceof DynamicChannelBuffer) { 96 | buffer.writeBytes(writeBytes); 97 | message = buffer; 98 | } else { 99 | int size = buffer.readableBytes() + buf.readableBytes(); 100 | message = com.alibaba.dubbo.remoting.buffer.ChannelBuffers.dynamicBuffer( 101 | size > bufferSize ? size : bufferSize); 102 | message.writeBytes(buffer, buffer.readableBytes()); 103 | message.writeBytes(writeBytes); 104 | } 105 | } else { 106 | message = com.alibaba.dubbo.remoting.buffer.ChannelBuffers.wrappedBuffer(writeBytes); 107 | } 108 | 109 | NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler); 110 | Object msg; 111 | int saveReaderIndex; 112 | 113 | try { 114 | // decode object. 115 | do { 116 | saveReaderIndex = message.readerIndex(); 117 | try { 118 | msg = codec.decode(channel, message); 119 | } catch (IOException e) { 120 | buffer = com.alibaba.dubbo.remoting.buffer.ChannelBuffers.EMPTY_BUFFER; 121 | throw e; 122 | } 123 | if (msg == Codec2.DecodeResult.NEED_MORE_INPUT) { 124 | message.readerIndex(saveReaderIndex); 125 | break; 126 | } else { 127 | if (saveReaderIndex == message.readerIndex()) { 128 | buffer = com.alibaba.dubbo.remoting.buffer.ChannelBuffers.EMPTY_BUFFER; 129 | throw new IOException("Decode without read data."); 130 | } 131 | 132 | if (msg != null) { 133 | out.add(msg); 134 | } 135 | } 136 | } while (message.readable()); 137 | } finally { 138 | if (message.readable()) { 139 | message.discardReadBytes(); 140 | buffer = message; 141 | } else { 142 | buffer = com.alibaba.dubbo.remoting.buffer.ChannelBuffers.EMPTY_BUFFER; 143 | } 144 | 145 | NettyChannel.removeChannelIfDisconnected(ctx.channel()); 146 | } 147 | } 148 | } 149 | } -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/src/main/java/com/yam/dubbo/remoting/transport/netty/NettyChannel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.remoting.transport.netty; 9 | 10 | import io.netty.channel.ChannelFuture; 11 | 12 | import java.net.InetSocketAddress; 13 | import java.util.Map; 14 | import java.util.concurrent.ConcurrentHashMap; 15 | import java.util.concurrent.ConcurrentMap; 16 | 17 | import com.alibaba.dubbo.common.Constants; 18 | import com.alibaba.dubbo.common.URL; 19 | import com.alibaba.dubbo.common.logger.Logger; 20 | import com.alibaba.dubbo.common.logger.LoggerFactory; 21 | import com.alibaba.dubbo.remoting.ChannelHandler; 22 | import com.alibaba.dubbo.remoting.RemotingException; 23 | import com.alibaba.dubbo.remoting.transport.AbstractChannel; 24 | 25 | /** 26 | * @Description: TODO 27 | * @author youaremoon 28 | * @date 2015年12月25日 下午9:56:51 29 | * 30 | */ 31 | final class NettyChannel extends AbstractChannel { 32 | 33 | private static final Logger logger = LoggerFactory.getLogger(NettyChannel.class); 34 | 35 | private static final ConcurrentMap channelMap = new ConcurrentHashMap(); 36 | 37 | private final io.netty.channel.Channel channel; 38 | 39 | private final Map attributes = new ConcurrentHashMap(); 40 | 41 | private NettyChannel(io.netty.channel.Channel channel, URL url, ChannelHandler handler){ 42 | super(url, handler); 43 | if (channel == null) { 44 | throw new IllegalArgumentException("netty channel == null;"); 45 | } 46 | this.channel = channel; 47 | } 48 | 49 | static NettyChannel getOrAddChannel(io.netty.channel.Channel ch, URL url, ChannelHandler handler) { 50 | if (ch == null) { 51 | return null; 52 | } 53 | 54 | NettyChannel ret = channelMap.get(ch); 55 | if (ret == null) { 56 | NettyChannel nc = new NettyChannel(ch, url, handler); 57 | if (ch.isActive()) { 58 | ret = channelMap.putIfAbsent(ch, nc); 59 | } 60 | if (ret == null) { 61 | ret = nc; 62 | } 63 | } 64 | return ret; 65 | } 66 | 67 | static void removeChannelIfDisconnected(io.netty.channel.Channel ch) { 68 | if (ch != null && ! ch.isActive()) { 69 | channelMap.remove(ch); 70 | } 71 | } 72 | 73 | public InetSocketAddress getLocalAddress() { 74 | return (InetSocketAddress) channel.localAddress(); 75 | } 76 | 77 | public InetSocketAddress getRemoteAddress() { 78 | return (InetSocketAddress) channel.remoteAddress(); 79 | } 80 | 81 | public boolean isConnected() { 82 | return channel.isActive(); 83 | } 84 | 85 | public void send(Object message, boolean sent) throws RemotingException { 86 | super.send(message, sent); 87 | 88 | boolean success = true; 89 | int timeout = 0; 90 | try { 91 | ChannelFuture future = channel.writeAndFlush(message); 92 | if (sent) { 93 | timeout = getUrl().getPositiveParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT); 94 | success = future.await(timeout); 95 | } 96 | Throwable cause = future.cause(); 97 | if (cause != null) { 98 | throw cause; 99 | } 100 | } catch (Throwable e) { 101 | throw new RemotingException(this, "Failed to send message " + message + " to " + getRemoteAddress() + ", cause: " + e.getMessage(), e); 102 | } 103 | 104 | if(! success) { 105 | throw new RemotingException(this, "Failed to send message " + message + " to " + getRemoteAddress() 106 | + "in timeout(" + timeout + "ms) limit"); 107 | } 108 | } 109 | 110 | public void close() { 111 | try { 112 | super.close(); 113 | } catch (Exception e) { 114 | logger.warn(e.getMessage(), e); 115 | } 116 | try { 117 | removeChannelIfDisconnected(channel); 118 | } catch (Exception e) { 119 | logger.warn(e.getMessage(), e); 120 | } 121 | try { 122 | attributes.clear(); 123 | } catch (Exception e) { 124 | logger.warn(e.getMessage(), e); 125 | } 126 | try { 127 | if (logger.isInfoEnabled()) { 128 | logger.info("Close netty channel " + channel); 129 | } 130 | channel.close(); 131 | } catch (Exception e) { 132 | logger.warn(e.getMessage(), e); 133 | } 134 | } 135 | 136 | public boolean hasAttribute(String key) { 137 | return attributes.containsKey(key); 138 | } 139 | 140 | public Object getAttribute(String key) { 141 | return attributes.get(key); 142 | } 143 | 144 | public void setAttribute(String key, Object value) { 145 | if (value == null) { // The null value unallowed in the ConcurrentHashMap. 146 | attributes.remove(key); 147 | } else { 148 | attributes.put(key, value); 149 | } 150 | } 151 | 152 | public void removeAttribute(String key) { 153 | attributes.remove(key); 154 | } 155 | 156 | @Override 157 | public int hashCode() { 158 | final int prime = 31; 159 | int result = 1; 160 | result = prime * result + ((channel == null) ? 0 : channel.hashCode()); 161 | return result; 162 | } 163 | 164 | @Override 165 | public boolean equals(Object obj) { 166 | if (this == obj) return true; 167 | if (obj == null) return false; 168 | if (getClass() != obj.getClass()) return false; 169 | NettyChannel other = (NettyChannel) obj; 170 | if (channel == null) { 171 | if (other.channel != null) return false; 172 | } else if (!channel.equals(other.channel)) return false; 173 | return true; 174 | } 175 | 176 | @Override 177 | public String toString() { 178 | return "NettyChannel [channel=" + channel + "]"; 179 | } 180 | 181 | } -------------------------------------------------------------------------------- /dubbo-remoting-newnetty/src/main/java/com/yam/dubbo/remoting/transport/netty/NettyClient.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright: Copyright (c) 2015 3 | * 4 | * @author youaremoon 5 | * @date 2015年12月25日 6 | * @version V1.0 7 | */ 8 | package com.yam.dubbo.remoting.transport.netty; 9 | 10 | import io.netty.bootstrap.Bootstrap; 11 | import io.netty.channel.Channel; 12 | import io.netty.channel.ChannelFuture; 13 | import io.netty.channel.ChannelInitializer; 14 | import io.netty.channel.ChannelOption; 15 | import io.netty.channel.ChannelPipeline; 16 | import io.netty.channel.nio.NioEventLoopGroup; 17 | import io.netty.channel.socket.SocketChannel; 18 | import io.netty.channel.socket.nio.NioSocketChannel; 19 | 20 | import java.util.concurrent.TimeUnit; 21 | 22 | import com.alibaba.dubbo.common.Constants; 23 | import com.alibaba.dubbo.common.URL; 24 | import com.alibaba.dubbo.common.Version; 25 | import com.alibaba.dubbo.common.logger.Logger; 26 | import com.alibaba.dubbo.common.logger.LoggerFactory; 27 | import com.alibaba.dubbo.common.utils.NetUtils; 28 | import com.alibaba.dubbo.remoting.ChannelHandler; 29 | import com.alibaba.dubbo.remoting.RemotingException; 30 | import com.alibaba.dubbo.remoting.transport.AbstractClient; 31 | 32 | /** 33 | * 34 | * @Description: TODO 35 | * @author youaremoon 36 | * @date 2015年12月25日 下午9:57:06 37 | * 38 | */ 39 | public class NettyClient extends AbstractClient { 40 | 41 | private static final Logger logger = LoggerFactory.getLogger(NettyClient.class); 42 | 43 | private Bootstrap bootstrap; 44 | 45 | private volatile Channel channel; // volatile, please copy reference to use 46 | // private static final int OP_READ_WRITE = SelectionKey.OP_WRITE | SelectionKey.OP_READ; 47 | 48 | public NettyClient(final URL url, final ChannelHandler handler) throws RemotingException{ 49 | super(url, wrapChannelHandler(url, handler)); 50 | } 51 | 52 | @Override 53 | protected void doOpen() throws Throwable { 54 | bootstrap = new Bootstrap(); 55 | bootstrap.group(getEventLoopGroup()).channel(NioSocketChannel.class); 56 | 57 | bootstrap.option(ChannelOption.TCP_NODELAY, true); 58 | bootstrap.option(ChannelOption.SO_KEEPALIVE, true); 59 | 60 | bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, getTimeout()); 61 | 62 | final NettyHandler nettyHandler = new NettyHandler(getUrl(), this); 63 | bootstrap.handler(new ChannelInitializer(){ 64 | @Override 65 | protected void initChannel(SocketChannel channel) throws Exception { 66 | NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyClient.this); 67 | ChannelPipeline pipeline = channel.pipeline(); 68 | pipeline.addLast("decoder", adapter.getDecoder()); 69 | pipeline.addLast("encoder", adapter.getEncoder()); 70 | pipeline.addLast("handler", nettyHandler); 71 | } 72 | }); 73 | } 74 | 75 | protected NioEventLoopGroup getEventLoopGroup() { 76 | return new NioEventLoopGroup(Constants.DEFAULT_IO_THREADS); 77 | } 78 | 79 | protected void doConnect() throws Throwable { 80 | long start = System.currentTimeMillis(); 81 | ChannelFuture future = bootstrap.connect(getConnectAddress()); 82 | try{ 83 | boolean ret = future.awaitUninterruptibly(getConnectTimeout(), TimeUnit.MILLISECONDS); 84 | 85 | if (ret && future.isSuccess()) { 86 | Channel newChannel = future.channel(); 87 | // newChannel.setInterestOps(OP_READ_WRITE); 88 | try { 89 | // 关闭旧的连接 90 | Channel oldChannel = NettyClient.this.channel; // copy reference 91 | if (oldChannel != null) { 92 | try { 93 | if (logger.isInfoEnabled()) { 94 | logger.info("Close old netty channel " + oldChannel + " on create new netty channel " + newChannel); 95 | } 96 | oldChannel.close(); 97 | } finally { 98 | NettyChannel.removeChannelIfDisconnected(oldChannel); 99 | } 100 | } 101 | } finally { 102 | if (NettyClient.this.isClosed()) { 103 | try { 104 | if (logger.isInfoEnabled()) { 105 | logger.info("Close new netty channel " + newChannel + ", because the client closed."); 106 | } 107 | newChannel.close(); 108 | } finally { 109 | NettyClient.this.channel = null; 110 | NettyChannel.removeChannelIfDisconnected(newChannel); 111 | } 112 | } else { 113 | NettyClient.this.channel = newChannel; 114 | } 115 | } 116 | } else if (future.cause() != null) { 117 | throw new RemotingException(this, "client(url: " + getUrl() + ") failed to connect to server " 118 | + getRemoteAddress() + ", error message is:" + future.cause().getMessage(), future.cause()); 119 | } else { 120 | throw new RemotingException(this, "client(url: " + getUrl() + ") failed to connect to server " 121 | + getRemoteAddress() + " client-side timeout " 122 | + getConnectTimeout() + "ms (elapsed: " + (System.currentTimeMillis() - start) + "ms) from netty client " 123 | + NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion()); 124 | } 125 | }finally{ 126 | if (! isConnected()) { 127 | future.cancel(true); 128 | } 129 | } 130 | } 131 | 132 | @Override 133 | protected void doDisConnect() throws Throwable { 134 | try { 135 | NettyChannel.removeChannelIfDisconnected(channel); 136 | } catch (Throwable t) { 137 | logger.warn(t.getMessage()); 138 | } 139 | } 140 | 141 | @Override 142 | protected void doClose() throws Throwable { 143 | /*try { 144 | bootstrap.releaseExternalResources(); 145 | } catch (Throwable t) { 146 | logger.warn(t.getMessage()); 147 | }*/ 148 | if (null != bootstrap) { 149 | bootstrap.group().shutdownGracefully(); 150 | } 151 | } 152 | 153 | @Override 154 | protected com.alibaba.dubbo.remoting.Channel getChannel() { 155 | Channel c = channel; 156 | if (c == null || ! c.isActive()) 157 | return null; 158 | return NettyChannel.getOrAddChannel(c, getUrl(), this); 159 | } 160 | 161 | } --------------------------------------------------------------------------------