package com.github.wangxuehui.rpc.snrpc.client; import java.net.InetSocketAddress; import com.github.wangxuehui.rpc.snrpc.SnRpcConnection; import com.github.wangxuehui.rpc.snrpc.serializer.SnRpcRequestEncoder; import com.github.wangxuehui.rpc.snrpc.serializer.SnRpcResponse; import com.github.wangxuehui.rpc.snrpc.serializer.SnRpcRequest; import com.github.wangxuehui.rpc.snrpc.serializer.SnRpcResponseDecoder; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; /** * @author skyim E-mail:wxh64788665@gmail.com */ public class SnNettyRpcConnection extends SimpleChannelInboundHandler<SnRpcResponse> implements SnRpcConnection { private InetSocketAddress inetAddr; private SnRpcResponse response; private Object obj = new Object(); public SnNettyRpcConnection(String host, int port) { this.inetAddr = new InetSocketAddress(host, port); } public SnRpcResponse sendRequest(final SnRpcRequest request) throws Throwable { EventLoopGroup workerGroup = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); // (1) b.group(workerGroup); // (2) b.channel(NioSocketChannel.class); // (3) b.option(ChannelOption.SO_KEEPALIVE, true); // (4) b.handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { //依次处理连接信息SnNettyRpcConnection,Request编码,Response解码 ch.pipeline().addLast(new SnRpcResponseDecoder()); ch.pipeline().addLast(new SnRpcRequestEncoder()); ch.pipeline().addLast(SnNettyRpcConnection.this); } }); Channel ch = b.connect(inetAddr).sync().channel(); //发送rpc调用请求 ch.writeAndFlush(request); //等待收到rpc调用结果 waitForResponse(); //执行到这里一定是收到了服务端的响应 SnRpcResponse resp = this.response; if (resp != null) { ch.closeFuture().sync(); } return resp; } finally { workerGroup.shutdownGracefully(); } } public void waitForResponse() { synchronized (obj) { try { //如果channelRead0收到消息,则说明服务端的响应数据过来了,不需要再等待了, //执行上面方法sendRequest中waitForResponse()后面的语句 obj.wait(); } catch (InterruptedException e) { } } } //如果读取到服务端发送的消息,那么这个消息就是服务端发送的rpc调用结果的响应信息 @Override protected void channelRead0(ChannelHandlerContext ctx, SnRpcResponse msg) throws Exception { response = msg; synchronized (obj) { //触发obj通知有结果了 obj.notifyAll(); } } }