├── .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 | ![image](https://user-images.githubusercontent.com/24973360/50372024-5f975d00-0601-11e9-8247-139e145b1123.png) 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 | --------------------------------------------------------------------------------