├── .gitignore
├── README.md
├── pom.xml
└── src
└── main
└── java
└── cn
└── thinkinjava
├── consumer
└── ClientBootstrap.java
├── netty
├── ClientHandler.java
├── NettyClient.java
├── NettyServer.java
└── ServerHandler.java
├── provider
├── HelloServiceImpl.java
└── ServerBootstrap.java
└── publicInterface
└── HelloService.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | .idea
3 | .iml
4 | target/
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rpc-netty-demo
2 |
3 |
4 | 启动 ServerBootstrap ,然后启动 ClientBootstrap,将出现结果。
5 |
6 |
7 | 本人微信,欢迎一起探讨:
8 |
9 | 
10 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | cn.thinkinjava
8 | rpc-demo
9 | 1.0-SNAPSHOT
10 |
11 |
12 |
13 |
14 |
15 | io.netty
16 | netty-all
17 | 4.1.16.Final
18 |
19 |
20 |
21 |
22 |
23 |
24 | org.apache.maven.plugins
25 | maven-compiler-plugin
26 |
27 | 1.6
28 | 1.6
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/main/java/cn/thinkinjava/consumer/ClientBootstrap.java:
--------------------------------------------------------------------------------
1 | package cn.thinkinjava.consumer;
2 |
3 | import cn.thinkinjava.netty.NettyClient;
4 | import cn.thinkinjava.publicInterface.HelloService;
5 |
6 | public class ClientBootstrap {
7 |
8 | public static final String providerName = "HelloService#hello#";
9 |
10 | public static void main(String[] args) throws InterruptedException {
11 |
12 | NettyClient consumer = new NettyClient();
13 | // 创建一个代理对象
14 | HelloService service = (HelloService) consumer.getBean(HelloService.class, providerName);
15 |
16 | for (; ; ) {
17 | Thread.sleep(1000);
18 | System.out.println(service.hello("are you ok ?"));
19 | }
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/cn/thinkinjava/netty/ClientHandler.java:
--------------------------------------------------------------------------------
1 | package cn.thinkinjava.netty;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import java.util.concurrent.Callable;
6 |
7 | public class ClientHandler extends ChannelInboundHandlerAdapter implements Callable {
8 |
9 | private ChannelHandlerContext context;
10 |
11 | private String result;
12 |
13 | private String para;
14 |
15 | /**
16 | * 与服务器的连接已经及建立之后将被调用
17 | * @param ctx
18 | */
19 | @Override
20 | public void channelActive(ChannelHandlerContext ctx) {
21 | context = ctx;
22 | }
23 |
24 | /**
25 | * 收到服务端数据,唤醒等待线程
26 | */
27 | @Override
28 | public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) {
29 | result = msg.toString();
30 | notify();
31 | }
32 |
33 | /**
34 | * 写出数据,开始等待唤醒
35 | */
36 | @Override
37 | public synchronized Object call() throws InterruptedException {
38 | context.writeAndFlush(para);
39 | wait();
40 | return result;
41 | }
42 |
43 | void setPara(String para) {
44 | this.para = para;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/cn/thinkinjava/netty/NettyClient.java:
--------------------------------------------------------------------------------
1 | package cn.thinkinjava.netty;
2 |
3 | import cn.thinkinjava.netty.ClientHandler;
4 | import io.netty.bootstrap.Bootstrap;
5 | import io.netty.channel.ChannelInitializer;
6 | import io.netty.channel.ChannelOption;
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.SocketChannel;
11 | import io.netty.channel.socket.nio.NioSocketChannel;
12 | import io.netty.handler.codec.string.StringDecoder;
13 | import io.netty.handler.codec.string.StringEncoder;
14 | import java.lang.reflect.Proxy;
15 | import java.util.concurrent.ExecutorService;
16 | import java.util.concurrent.Executors;
17 |
18 | public class NettyClient {
19 |
20 | private static ExecutorService executor = Executors
21 | .newFixedThreadPool(Runtime.getRuntime().availableProcessors());
22 |
23 | private static ClientHandler client;
24 |
25 | /**
26 | * 创建一个代理对象
27 | */
28 | public Object getBean(final Class> serviceClass,
29 | final String providerName) {
30 | return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
31 | new Class>[]{serviceClass}, (proxy, method, args) -> {
32 | if (client == null) {
33 | initClient();
34 | }
35 | // 设置参数
36 | client.setPara(providerName + args[0]);
37 | return executor.submit(client).get();
38 | });
39 | }
40 |
41 | /**
42 | * 初始化客户端
43 | */
44 | private static void initClient() {
45 | client = new ClientHandler();
46 | EventLoopGroup group = new NioEventLoopGroup();
47 | Bootstrap b = new Bootstrap();
48 | b.group(group)
49 | .channel(NioSocketChannel.class)
50 | .option(ChannelOption.TCP_NODELAY, true)
51 | .handler(new ChannelInitializer() {
52 | @Override
53 | public void initChannel(SocketChannel ch) throws Exception {
54 | ChannelPipeline p = ch.pipeline();
55 | p.addLast(new StringDecoder());
56 | p.addLast(new StringEncoder());
57 | p.addLast(client);
58 | }
59 | });
60 | try {
61 | b.connect("localhost", 8088).sync();
62 | } catch (InterruptedException e) {
63 | e.printStackTrace();
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/cn/thinkinjava/netty/NettyServer.java:
--------------------------------------------------------------------------------
1 | package cn.thinkinjava.netty;
2 |
3 | import io.netty.bootstrap.ServerBootstrap;
4 | import io.netty.channel.ChannelInitializer;
5 | import io.netty.channel.ChannelPipeline;
6 | import io.netty.channel.nio.NioEventLoopGroup;
7 | import io.netty.channel.socket.SocketChannel;
8 | import io.netty.channel.socket.nio.NioServerSocketChannel;
9 | import io.netty.handler.codec.string.StringDecoder;
10 | import io.netty.handler.codec.string.StringEncoder;
11 |
12 | /**
13 | * 服务端
14 | */
15 | public class NettyServer {
16 |
17 | /**
18 | * 启动客户端
19 | */
20 | public static void startServer(String hostName, int port) {
21 | startServer0(hostName, port);
22 | }
23 |
24 | private static void startServer0(String hostName, int port) {
25 | try {
26 | ServerBootstrap bootstrap = new ServerBootstrap();
27 | NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
28 | bootstrap.group(eventLoopGroup)
29 | .channel(NioServerSocketChannel.class)
30 | .childHandler(new ChannelInitializer() {
31 | @Override
32 | protected void initChannel(SocketChannel ch) throws Exception {
33 | ChannelPipeline p = ch.pipeline();
34 | p.addLast(new StringDecoder());
35 | p.addLast(new StringEncoder());
36 | p.addLast(new ServerHandler());
37 | }
38 | });
39 |
40 | bootstrap.bind(hostName, port).sync();
41 | } catch (InterruptedException e) {
42 | e.printStackTrace();
43 | }
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/cn/thinkinjava/netty/ServerHandler.java:
--------------------------------------------------------------------------------
1 | package cn.thinkinjava.netty;
2 |
3 | import cn.thinkinjava.consumer.ClientBootstrap;
4 | import cn.thinkinjava.provider.HelloServiceImpl;
5 | import io.netty.channel.ChannelHandlerContext;
6 | import io.netty.channel.ChannelInboundHandlerAdapter;
7 |
8 | /**
9 | * 用于处理请求数据
10 | */
11 | public class ServerHandler extends ChannelInboundHandlerAdapter {
12 |
13 | @Override
14 | public void channelRead(ChannelHandlerContext ctx, Object msg) {
15 |
16 | // 如何符合约定,则调用本地方法,返回数据
17 | if (msg.toString().startsWith(ClientBootstrap.providerName)) {
18 | String result = new HelloServiceImpl()
19 | .hello(msg.toString().substring(msg.toString().lastIndexOf("#") + 1));
20 | ctx.writeAndFlush(result);
21 | }
22 |
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/cn/thinkinjava/provider/HelloServiceImpl.java:
--------------------------------------------------------------------------------
1 | package cn.thinkinjava.provider;
2 |
3 | import cn.thinkinjava.publicInterface.HelloService;
4 |
5 | /**
6 | * 实现类
7 | */
8 | public class HelloServiceImpl implements HelloService {
9 |
10 | @Override
11 | public String hello(String msg) {
12 | return msg != null ? msg + " -----> I am fine." : "I am fine.";
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/thinkinjava/provider/ServerBootstrap.java:
--------------------------------------------------------------------------------
1 | package cn.thinkinjava.provider;
2 |
3 | import cn.thinkinjava.netty.NettyServer;
4 |
5 | public class ServerBootstrap {
6 |
7 | public static void main(String[] args) {
8 | NettyServer.startServer("localhost", 8088);
9 |
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/cn/thinkinjava/publicInterface/HelloService.java:
--------------------------------------------------------------------------------
1 | package cn.thinkinjava.publicInterface;
2 |
3 | public interface HelloService {
4 |
5 | String hello(String ping);
6 |
7 | }
8 |
--------------------------------------------------------------------------------