├── README.md
├── pom.xml
└── src
├── main
└── java
│ └── rpc
│ └── xp
│ ├── client
│ ├── Client.java
│ ├── ProxyInterface.java
│ ├── ResponseHandler.java
│ ├── ResultInfo.java
│ └── zk
│ │ └── Observer.java
│ ├── common
│ ├── CommonContext.java
│ ├── RequestDecoder.java
│ ├── RequestEncoder.java
│ ├── ResponseDecoder.java
│ ├── ResponseEncoder.java
│ ├── RpcRequest.java
│ ├── RpcResponse.java
│ ├── SerializationUtil.java
│ ├── ServiceInfo.java
│ └── zk
│ │ ├── InfoCallBack.java
│ │ └── ZkUtil.java
│ └── server
│ ├── Invoker.java
│ ├── RequestHandler.java
│ ├── Server.java
│ └── zk
│ └── Publisher.java
└── test
└── java
├── com
└── xp
│ └── service
│ ├── ITest.java
│ └── TestImpl.java
└── rpc
└── test
├── RpcClient.java
├── RpcServer.java
└── ZkTest.java
/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xpbob/lightrpc/d6b5f1ad0610b4628910813cfe23e2eb08c4599c/README.md
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | nettyTest
5 | nettyTest
6 | 0.0.1-SNAPSHOT
7 |
8 |
9 | io.netty
10 | netty-all
11 | 4.1.24.Final
12 |
13 |
14 | com.dyuproject.protostuff
15 | protostuff-core
16 | 1.0.8
17 |
18 |
19 | com.dyuproject.protostuff
20 | protostuff-runtime
21 | 1.0.8
22 |
23 |
24 |
25 | org.apache.zookeeper
26 | zookeeper
27 | 3.4.9
28 |
29 |
30 | com.alibaba
31 | fastjson
32 | 1.2.47
33 |
34 |
35 |
36 |
37 | org.objenesis
38 | objenesis
39 | 2.1
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/main/java/rpc/xp/client/Client.java:
--------------------------------------------------------------------------------
1 | package rpc.xp.client;
2 |
3 | import io.netty.bootstrap.Bootstrap;
4 | import io.netty.channel.Channel;
5 | import io.netty.channel.ChannelFuture;
6 | import io.netty.channel.ChannelInitializer;
7 | import io.netty.channel.ChannelPipeline;
8 | import io.netty.channel.EventLoopGroup;
9 | import io.netty.channel.nio.NioEventLoopGroup;
10 | import io.netty.channel.socket.nio.NioSocketChannel;
11 | import rpc.xp.common.RequestEncoder;
12 | import rpc.xp.common.ResponseDecoder;
13 |
14 | public class Client {
15 | private Channel channel;
16 | private String id;
17 |
18 | public void connect(String ip, int port) throws InterruptedException {
19 | EventLoopGroup worker = new NioEventLoopGroup();
20 | Bootstrap b = new Bootstrap();
21 | b.group(worker).channel(NioSocketChannel.class).handler(new ChannelInitializer() {
22 |
23 | @Override
24 | protected void initChannel(Channel ch) throws Exception {
25 | ChannelPipeline pipeline = ch.pipeline();
26 | pipeline.addLast(new RequestEncoder());
27 | pipeline.addLast(new ResponseDecoder());
28 | pipeline.addLast(new ResponseHandler());
29 | }
30 |
31 | });
32 |
33 | ChannelFuture sync = b.connect(ip, port).sync();
34 | channel = sync.channel();
35 | id = ip + ":" + port;
36 |
37 | }
38 |
39 |
40 |
41 | @Override
42 | public int hashCode() {
43 | final int prime = 31;
44 | int result = 1;
45 | result = prime * result + ((id == null) ? 0 : id.hashCode());
46 | return result;
47 | }
48 |
49 |
50 |
51 | @Override
52 | public boolean equals(Object obj) {
53 | if (this == obj)
54 | return true;
55 | if (obj == null)
56 | return false;
57 | if (getClass() != obj.getClass())
58 | return false;
59 | Client other = (Client) obj;
60 | if (id == null) {
61 | if (other.id != null)
62 | return false;
63 | } else if (!id.equals(other.id))
64 | return false;
65 | return true;
66 | }
67 |
68 |
69 |
70 | public void write(Object obj) {
71 | channel.writeAndFlush(obj);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/rpc/xp/client/ProxyInterface.java:
--------------------------------------------------------------------------------
1 | package rpc.xp.client;
2 |
3 | import java.lang.reflect.InvocationHandler;
4 | import java.lang.reflect.Method;
5 | import java.lang.reflect.Proxy;
6 | import java.util.UUID;
7 | import java.util.concurrent.SynchronousQueue;
8 |
9 | import rpc.xp.client.zk.Observer;
10 | import rpc.xp.common.RpcRequest;
11 |
12 | public class ProxyInterface {
13 | public static T getProxy(final Class clazz) {
14 | return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, new InvocationHandler() {
15 |
16 | @Override
17 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
18 | RpcRequest request = new RpcRequest();
19 | request.setMethodName(method.getName());
20 | request.setClassName(clazz.getName());
21 | Class>[] parameterTypes = method.getParameterTypes();
22 | request.setArgs(args);
23 | String id = UUID.randomUUID().toString();
24 | request.setId(id);
25 | SynchronousQueue queue = new SynchronousQueue();
26 | ResultInfo.putSunchronousQuee(id, queue);
27 | Observer.send(request, clazz.getName());
28 | return queue.take();
29 | }
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/rpc/xp/client/ResponseHandler.java:
--------------------------------------------------------------------------------
1 | package rpc.xp.client;
2 |
3 | import java.util.concurrent.SynchronousQueue;
4 |
5 | import io.netty.channel.ChannelHandlerContext;
6 | import io.netty.channel.SimpleChannelInboundHandler;
7 | import rpc.xp.common.RpcResponse;
8 |
9 | public class ResponseHandler extends SimpleChannelInboundHandler {
10 |
11 | @Override
12 | protected void channelRead0(ChannelHandlerContext ctx, RpcResponse msg) throws Exception {
13 | String id = msg.getId();
14 | SynchronousQueue synchronousQueue = ResultInfo.getSynchronousQueue(id);
15 | synchronousQueue.put(msg.getResult());
16 | ResultInfo.removeById(id);
17 | }
18 |
19 | @Override
20 | public void channelInactive(ChannelHandlerContext ctx) throws Exception {
21 | ctx.channel().close();
22 | }
23 |
24 | @Override
25 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
26 | ctx.channel().close();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/rpc/xp/client/ResultInfo.java:
--------------------------------------------------------------------------------
1 | package rpc.xp.client;
2 |
3 | import java.util.concurrent.ConcurrentHashMap;
4 | import java.util.concurrent.SynchronousQueue;
5 |
6 | public class ResultInfo {
7 |
8 | private static ConcurrentHashMap mapInfo = new ConcurrentHashMap<>();
9 |
10 | public static void putSunchronousQuee(String id, SynchronousQueue queue) {
11 | mapInfo.put(id, queue);
12 | }
13 |
14 | public static SynchronousQueue getSynchronousQueue(String id) {
15 | return mapInfo.get(id);
16 | }
17 | public static void removeById(String id){
18 | mapInfo.remove(id);
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/rpc/xp/client/zk/Observer.java:
--------------------------------------------------------------------------------
1 | package rpc.xp.client.zk;
2 |
3 | import java.util.HashMap;
4 | import java.util.HashSet;
5 | import java.util.List;
6 | import java.util.Map;
7 | import java.util.Random;
8 | import java.util.Set;
9 |
10 | import com.alibaba.fastjson.JSONObject;
11 |
12 | import rpc.xp.client.Client;
13 | import rpc.xp.common.CommonContext;
14 | import rpc.xp.common.RpcRequest;
15 | import rpc.xp.common.ServiceInfo;
16 | import rpc.xp.common.zk.InfoCallBack;
17 | import rpc.xp.common.zk.ZkUtil;
18 |
19 | public class Observer implements InfoCallBack {
20 |
21 | public static volatile Map> services = new HashMap<>();
22 |
23 | private ZkUtil zkUtil;
24 |
25 | public Observer(String address) {
26 | zkUtil = new ZkUtil(address);
27 | zkUtil.CreateIfNotExist(CommonContext.PATH);
28 | try {
29 | List inofAndWatcher = zkUtil.getInofAndWatcher(CommonContext.PATH, this);
30 | getLastList(inofAndWatcher);
31 | } catch (Exception e) {
32 | e.printStackTrace();
33 | }
34 |
35 | }
36 |
37 | public static void send(RpcRequest request, String className) {
38 | Set set = services.get(className);
39 | if (set != null && !set.isEmpty()) {
40 | Client[] array = set.toArray(new Client[0]);
41 | //random
42 | Client client = array[new Random().nextInt(array.length)];
43 | client.write(request);
44 | }
45 | }
46 |
47 | @Override
48 | public void getLastList(List lists) {
49 | Map> serviceTmp = new HashMap<>();
50 | if (lists != null && !lists.isEmpty()) {
51 | for (String node : lists) {
52 | String info;
53 | try {
54 | info = new String(zkUtil.getData(CommonContext.PATH + "/" + node));
55 | ServiceInfo parse = JSONObject.parseObject(info, ServiceInfo.class);
56 | String address = parse.toString();
57 | List interfaces = parse.getInterfaces();
58 | if (interfaces != null && !interfaces.isEmpty()) {
59 | for (String service : interfaces) {
60 | Set set = serviceTmp.get(service);
61 | if (set == null) {
62 | set = new HashSet();
63 | }
64 | if (!set.contains(address)) {
65 | Client client = new Client();
66 | client.connect(parse.getIp(), parse.getPort());
67 | set.add(client);
68 | }
69 | serviceTmp.put(service, set);
70 |
71 | }
72 | }
73 | } catch (Exception e) {
74 | e.printStackTrace();
75 | }
76 |
77 | }
78 |
79 | }
80 |
81 | services = serviceTmp;
82 |
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/rpc/xp/common/CommonContext.java:
--------------------------------------------------------------------------------
1 | package rpc.xp.common;
2 |
3 | public interface CommonContext {
4 | public static final String PATH = "/xp";
5 | public static final int ZK_TIMEOUT = 5000;
6 |
7 |
8 |
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/rpc/xp/common/RequestDecoder.java:
--------------------------------------------------------------------------------
1 | package rpc.xp.common;
2 |
3 | import java.util.List;
4 |
5 | import io.netty.buffer.ByteBuf;
6 | import io.netty.channel.ChannelHandlerContext;
7 | import io.netty.handler.codec.ByteToMessageDecoder;
8 |
9 | public class RequestDecoder extends ByteToMessageDecoder {
10 |
11 | @Override
12 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List