文章目录

十、Netty 核心源码剖析

  • 基本说明
  • Netty 启动过程源码剖析
  • Netty 接受请求过程源码剖析
  • Pipeline Handler HandlerContext创建源码剖析
  • ChannelPipeline 调度 handler 的源码剖析
  • Netty 心跳(heartbeat)服务源码剖析
  • Netty 核心组件 EventLoop 源码剖析
  • handler 中加入线程池和Context 中添加线程池的源码剖析
  • 十一、用Netty 自己 实现 dubbo RPC
  • RPC基本介绍
  • RPC调用流程
  • RPC调用流程图
  • PRC调用流程说明
  • 自己实现 dubbo RPC(基于Netty)

十、Netty 核心源码剖析

基本说明

java netty实现客户端_ide

Netty 启动过程源码剖析

java netty实现客户端_java netty实现客户端_02

java netty实现客户端_java netty实现客户端_03

因为在IDEA中的netty包里没显示example包,所以需要找到maven下载的netty包,找到netty-all-4.1.20.Final-sources.jar文件,把后缀jar改为rar,然后解压,点进去就可以找到example包了。

我已经把源码的案例和老师的文档上传到了百度云,需要的可以自行下载:https://pan.baidu.com/s/1txMv9I8YYflztT19DYc7LA    密码: vdei

java netty实现客户端_源码剖析_04

Netty 接受请求过程源码剖析

java netty实现客户端_源码剖析_05

java netty实现客户端_java netty实现客户端_06

java netty实现客户端_java_07

java netty实现客户端_源码剖析_08

Pipeline Handler HandlerContext创建源码剖析

java netty实现客户端_netty_09

java netty实现客户端_ide_10

java netty实现客户端_java_11

java netty实现客户端_netty_12

ChannelPipeline 调度 handler 的源码剖析

java netty实现客户端_ide_13

java netty实现客户端_ide_14

java netty实现客户端_源码剖析_15

java netty实现客户端_java netty实现客户端_16

Netty 心跳(heartbeat)服务源码剖析

java netty实现客户端_ide_17

java netty实现客户端_源码剖析_18

java netty实现客户端_ide_19

Netty 核心组件 EventLoop 源码剖析

java netty实现客户端_ide_20

java netty实现客户端_源码剖析_21

java netty实现客户端_java netty实现客户端_22

handler 中加入线程池和Context 中添加线程池的源码剖析

java netty实现客户端_ide_23

java netty实现客户端_java_24

java netty实现客户端_ide_25

十一、用Netty 自己 实现 dubbo RPC

RPC基本介绍

java netty实现客户端_java_26

java netty实现客户端_java_27

RPC调用流程

RPC调用流程图

java netty实现客户端_java netty实现客户端_28

PRC调用流程说明

java netty实现客户端_源码剖析_29

自己实现 dubbo RPC(基于Netty)

java netty实现客户端_java netty实现客户端_30

java netty实现客户端_java_31

java netty实现客户端_源码剖析_32

publicinterface

//公共接口
public interface HelloService {

    //由服务提供者进行实现,为服务消费者提供服务
    String hello(String mes);
}

provider

public class HelloServiceImpl implements HelloService {

    private static int count = 0;

    //为消费者提供服务,当消费者调用此方法时,返回一个结果
    @Override
    public String hello(String mes) {
        System.out.println("收到客户端消息:" + mes);

        //根据mes返回不同的结果
        if(mes != null){
            return "服务器已收到消息【" + mes + "】" + (++count);
        }else{
            return "服务器已收到消息";
        }
    }
}
//启动服务的提供者(NettyServer)
public class ServerBootstrap {
    public static void main(String[] args) {
        NettyServer.startServer("127.0.0.1", 7000);
    }
}

netty

public class NettyClient {

    //创建线程池(数量:CPU核数)
    private static ExecutorService executor = Executors.newFixedThreadPool(
                                                Runtime.getRuntime().availableProcessors());
    private static NettyClientHandler client;
    private int count;

    //初始化客户端
    private static void initClient(){
        client = new NettyClientHandler();

        EventLoopGroup group = new NioEventLoopGroup();

        Bootstrap bootstrap = new Bootstrap()
                .group(group)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)    //没有延时
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        //解码器
                        pipeline.addLast(new StringDecoder());
                        //编码器
                        pipeline.addLast(new StringEncoder());
                        //业务处理器
                        pipeline.addLast(client);
                    }
                });

        try {
            bootstrap.connect("127.0.0.1", 7000).sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }


    //代理模式获取代理对象
    public Object getBean(final Class<?> serviceClass, final String providerName){
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                new Class<?>[] {serviceClass}, (proxy, method, args) -> {

                    System.out.println("(proxy, method, args)进入..." + (++count));
                    if(client == null){
                        //初始化
                        initClient();
                    }

                    //设置要发给服务器端的信息
                    //providerName为协议头,args[0]客户端调用api hello(xxx) 的参数
                    client.setPara(providerName + args[0]);

                    return executor.submit(client).get();
                });
    }
}
public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable {

    private ChannelHandlerContext context;  //上下文
    private String result;  //调用后返回的结果
    private String para;    //客户端调用方法时,传入的参数

    //设置参数 (2)
    void setPara(String para){
        System.out.println("setPara 被调用");
        this.para = para;
    }

    //与服务器连接成功后,就会被触发调用 (1)
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelActive 被调用");
        //因为在其他方法(call方法)里也要使用到ctx
        context = ctx;
    }

    //收到服务器回复的数据后,触发调用 (4)
    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("channelRead 被调用");
        //保存服务方返回的结果
        result = msg.toString();
        //唤醒等待的线程
        notify();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    //客户端真正发送数据的方法 (3) (5)
    //被代理对象调用,发送数据给服务器 -> 发送完后,wait -> 等待被唤醒(channelRead) -> 服务方返回结果
    //服务器回复结果会发送触发channelRead()方法,由这个方法来唤醒此线程
    @Override
    public synchronized Object call() throws Exception {
        System.out.println("call1 被调用");

        //发送数据给服务器端
        context.writeAndFlush(para);
        //进行wait,等待channelRead()方法获取到服务器回复的结果后唤醒
        wait();
        System.out.println("call2 被调用");
        //服务方返回的结果
        return result;
    }
}
public class NettyServer {

    //对外暴露
    public static void startServer(String hostname, int port){
        startServer0(hostname, port);
    }

    //NettyServer的初始化和启动
    private static void startServer0(String hostname, int port){
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap()
                    .group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            //解码器
                            pipeline.addLast(new StringDecoder());
                            //编码器
                            pipeline.addLast(new StringEncoder());
                            //业务处理器
                            pipeline.addLast(new NettyServerHandler());
                        }
                    });

            ChannelFuture channelFuture = serverBootstrap.bind(hostname, port).sync();
            System.out.println("服务提供者启动成功,开始提供服务~");
            channelFuture.channel().closeFuture().sync();

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //获取客户端发送的消息,并调用服务
        System.out.println("msg=" + msg);

        //客户端在调用服务器api时,需要遵循定义的协议
        //比如:每次发送的消息必须以某个字符串开头 "HelloService#hello#"
        if(msg.toString().startsWith("HelloService#hello#")){
            //截取内容并调用api
            String result = new HelloServiceImpl().hello(msg.toString().substring(
                    msg.toString().lastIndexOf("#") + 1));

            ctx.writeAndFlush(result);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

customer

public class ClientBootstrap {

    //定义协议头
    public static final String providerName = "HelloService#hello#";

    public static void main(String[] args) throws Exception {
        //创建一个消费者
        NettyClient customer = new NettyClient();

        //创建代理对象
        HelloService service = (HelloService) customer.getBean(HelloService.class, providerName);

        while (true){
            Thread.sleep(5 * 1000);
            //通过代理对象调用服务提供者的方法(服务)
            //每次调用时,HelloServiceImpl都会创建新对象
            String res = service.hello("你好,dubbo~");
            System.out.println("调用结果:" + res);
        }
    }
}

学习视频(p92-p116):https://www.bilibili.com/video/BV1DJ411m7NR?p=92