rpc基于netty异步调用后,捕获对应响应结果的实现

由于netty通信是异步的,客户端请求之后就不再阻塞等待服务端的结果返回了,客户端可以去做其他的事情,而服务端处理完之后会将响应结果输出给客户端,这些客户端并不知道这个响应结果是属于哪次请求的结果。所有需要一套机制去实现响应结果隶属于是属于哪次调用的结果。

通过netty客户端请求服务端流程如下:

下面用代码实现一次完整的,rpc通过netty调用之后,找到对应请求的response:

首先定义一个netty客户端:

public class InvokerClient {

    private static Channel channel;

    public void init() throws Exception {
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(new NioEventLoopGroup()).channel(NioSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        // 处理来自服务端的响应信息
                        socketChannel.pipeline().addLast(new ReceiveHandle());
                    }
                });

        ChannelFuture cf = bootstrap.connect("127.0.0.1", 3344).sync();
        channel = cf.channel();
    }

    public Object call(Request request) {
        RequestFactory.put(request.getSeq(), null);
        channel.writeAndFlush("hello");
        return RequestFactory.getResponse(request.getSeq());
    }
}

其中Request是请求对象:

public class Request {

    private static final UUID uuid = UUID.randomUUID();
    
    //生成一个唯一请求id,netty的返回响应结果时也会带上此id,从而把请求与响应结果绑定了
    private String seq = uuid.toString();

    private Object object;

    public Object getObject() {
        return object;
    }

    public Request setObject(Object object) {
        this.object = object;
        return this;
    }

    public String getSeq() {
        return seq;
    }
}
ReceiveHandle
用于客户端专门处理服务端返回数据的handle
public class ReceiveHandle extends SimpleChannelInboundHandler {

    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
       RequestFactory.put(o.getSeq(),o);
    }
}
RequestFactory
是请求工厂,专门放对应请求的seq,其中value为响应的返回结果

public class RequestFactory {

    private static final Map<String, Object> map = new ConcurrentHashMap<String, Object>();

    public static void put(String uuid, Object object) {
        map.put(uuid, object);
    }

    public static Object get(String uuid) {
        return map.get(uuid);
    }
}

从而一次完整的rpc异步调用,对应的响应结果获取代码结束。原理就是请求时生成一个唯一请求id,然后缓存起来,netty返回响应结果时,也带上这个id,从来可以识别响应结果对应着那个请求

猜你喜欢

转载自blog.csdn.net/CSDNzhangtao5/article/details/103104510