Netty+ProtoBuf+Jdk 动态代理=手写简单Rpc

  • rpc 远程处理调用

  • 本地客户端 Consumer(客户端)

  • 远程服务提供者 Provider(服务端)

  • consumer 和 provider 需要有相同的接口

    • 我们在使用feign或者之类的rpc都是类似(个人理解)
  • 使用netty完成连接 在连接中使用动态代理

    • 客户端在动态代理的方法调用中(Invoke) 使用netty 所维持的 channel 完成request 的发送 并异步等待返回结果
    • 服务端在接受特定的请求后解析自定义协议中的数据,使用代理完成请求任务,并且返回respons
  • 服务端动态代理没写了(因为cglib不是很熟)

一、Consumer
1.启动程序
public class ConsumerBootStrap {
   
    EventLoopGroup consumer;
    Bootstrap bootstrap;

    public ConsumerBootStrap() {
   
        consumer = new NioEventLoopGroup();
        bootstrap = new Bootstrap();
    }

    public void boot(String hostName, int port) {
   
        boot0(hostName, port);
    }

    private void boot0(String hostName, int port) {
   
        ChannelFuture channelFuture = bootstrap.group(consumer)
                .handler(new RpcChannelHandlerInitializerClient())
                .channel(NioSocketChannel.class)
                .connect(hostName, port);
        try {
   
            channelFuture.sync();
        } catch (InterruptedException interruptedException) {
   
            interruptedException.printStackTrace();
        }

    }

}
2.协议解码
public class RpcConsumerDecoder extends ReplayingDecoder<RpcMessage.RpcMessagePojo> {
   
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
   
        Charset charset = CharsetUtil.UTF_8;
        RpcMessage.RpcMessagePojo.Builder builder = RpcMessage.RpcMessagePojo.newBuilder();
        RpcMessage.Response.Builder responseBuilder = RpcMessage.Response.newBuilder();
        builder.setMessageType(RpcMessage.RpcMessagePojo.MessageType.RESPONSE);


        int responseHeaderSize = in.readInt();
        String string=in.readBytes(responseHeaderSize).toString(charset);
        responseBuilder.setResponseHeader(string);

        int descriptionSize = in.readInt();
        string=in.readBytes(descriptionSize).toString(charset);
        System.out.println(string+"----");
        responseBuilder.setDescription(string);
        int resultSize = in.readInt();
        responseBuilder.setResult(in.readBytes(resultSize).toString(charset));
        out.add(builder.setResponse(responseBuilder.build()).build());
        //自由返回对应类型才会被指定了对应类型的handle 捕捉处理
    }
}
3、业务handler
public class RpcConsumerHandler extends SimpleChannelInboundHandler<RpcMessage.RpcMessagePojo> implements Callable<RpcMessage.RpcMessagePojo> {
   


    ChannelHandlerContext ctx;
    RpcMessage.RpcMessagePojo request;
    RpcMessage.RpcMessagePojo response;

    @Override
    protected synchronized void channelRead0(ChannelHandlerContext ctx, RpcMessage.RpcMessagePojo msg) throws Exception {
   
        response = msg;
        notify();
        //唤醒线程继续执行call
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
   
        System.out.println("active");
        this.ctx = ctx;
    }



    @Override
    public synchronized RpcMessage.RpcMessagePojo call() throws Exception {
   
        ctx.writeAndFlush(request);
        //传送到服务端
        //开始等待
        wait();
        return response
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值