Netty5實現接收服務端返回數據

1、開發spring boot微服務中,需要和第三方服務器做報文交換數據,用netty來實現客戶端,並做一個同步接受數據。一下用的是netty5,其它版本的相似即可。

2、pom.xml引入

        <dependency>
		<groupId>io.netty</groupId>
		<artifactId>netty-all</artifactId>
		<version>5.0.0.Alpha1</version>
	</dependency>

3、ClientInitializer編寫

import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.ReadTimeoutHandler;
public class ClientInitializer extends ChannelInitializer<SocketChannel>{
	private CountDownLatch lathc;
	public ClientInitializer(CountDownLatch lathc) {
		this.lathc = lathc;
	}
	private ClientHandler handler;
	@Override
	protected void initChannel(SocketChannel sc) throws Exception {
		handler =  new ClientHandler(lathc);
		sc.pipeline().addLast(new StringDecoder());//進行字符串的編解碼設置
		sc.pipeline().addLast(new StringEncoder());
		sc.pipeline().addLast(new ReadTimeoutHandler(60));//設置超時時間
		sc.pipeline().addLast(handler);
	}
	public String getServerResult(){
        return handler.getResult();
    }
    public void resetLathc(CountDownLatch lathc) {
        handler.resetLatch(lathc);
    }

}

4、ClientHandler編碼實現

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import java.util.concurrent.CountDownLatch;
public class ClientHandler extends ChannelHandlerAdapter{
	
	private CountDownLatch lathc;
	private String result;
	public ClientHandler(CountDownLatch lathc) {
        this.lathc = lathc;
        }
	
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {

	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		result = (String) msg;
		lathc.countDown();// 消息接收後釋放同步鎖,lathc是從Client加一傳回來的
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		ctx.close();
	}
	public void resetLatch(CountDownLatch lathc) {
		this.lathc = lathc;
	}

	public String getResult() {
		return result;
	}

	
}

5、Client端運行主程序編寫

import java.util.concurrent.CountDownLatch;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;;
public class Client {//編寫客戶端單例模式方便系統調用
	private static class SingletonHolder {
		static final Client instance = new Client();
	}
	public static Client getInstance(){
		return SingletonHolder.instance;
	}
	private EventLoopGroup group;
	private Bootstrap b;
	private ChannelFuture cf ;
	private ClientInitializer clientInitializer;
	private CountDownLatch lathc;
	private Client(){
		    lathc = new CountDownLatch(0);
		    clientInitializer = new ClientInitializer(lathc);
			group = new NioEventLoopGroup();
			b = new Bootstrap();
			b.group(group)
			 .channel(NioSocketChannel.class)
			 .handler(clientInitializer);
	}
	public void connect(){
		//192.168.43.51測試端口8766 192.168.43.102 線上端口8765
		try {
			this.cf = b.connect("127.0.01", 8888).sync();
			System.out.println("遠程服務器已經連接, 可以進行數據交換..");
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
		}
	}
	public ChannelFuture getChannelFuture(){
		if(this.cf == null) {
			this.connect();
		}
		if(!this.cf.channel().isActive()){
			this.connect();
		}
		return this.cf;
	}
	public void close(){
		try {
			this.cf.channel().closeFuture().sync();
			this.group.shutdownGracefully();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	 public String setMessage(String msg) throws InterruptedException{
	    	ChannelFuture cf =getInstance().getChannelFuture();//單例模式獲取ChannelFuture對象
	    	cf.channel().writeAndFlush(msg);
	    	//發送數據控制門閂加一
	    	lathc = new CountDownLatch(1);
	        clientInitializer.resetLathc(lathc);
	        lathc.await();//開始等待結果返回後執行下面的代碼
	        return clientInitializer.getServerResult();
	  }
	 public static void main(String[] args) throws Exception {
	    System.out.println(Client.getInstance().setMessage("123"));//測試等待數據返回
	 }
}

6、以上代碼完整,直接複製粘貼即可使用

歡迎大家有問題和意見可以留言

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章