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、以上代碼完整,直接複製粘貼即可使用
歡迎大家有問題和意見可以留言