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、以上代码完整,直接复制粘贴即可使用

欢迎大家有问题和意见可以留言



  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
Netty服务器中,可以通过ChannelHandlerContext对象将响应数据写入到响应缓冲区中,然后通过调用ctx.writeAndFlush()方法将响应数据发送给客户端。在客户端中,可以通过使用Java的NIO库取响应数据,将其解析后显示在页面上。 具体实现步骤如下: 1. 定义响应数据的格式和编码方式。 2. 在Netty服务器中,将响应数据写入到响应缓冲区中。 3. 调用ctx.writeAndFlush()方法将响应数据发送给客户端。 4. 在客户端中,使用Java的NIO库取响应数据。 5. 解析响应数据并显示在页面上。 下面是一个简单的例子,演示了如何在Netty服务器中发送响应数据: ```java public class MyNettyServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { // 解析请求数据 String requestData = (String) msg; // 处理请求,生成响应数据 String responseData = "Hello, " + requestData; // 将响应数据写入到响应缓冲区中 ByteBuf responseBuf = Unpooled.copiedBuffer(responseData.getBytes()); // 发送响应数据 ctx.writeAndFlush(responseBuf); } } ``` 在这个例子中,我们定义了一个简单的处理器类MyNettyServerHandler,它继承自ChannelInboundHandlerAdapter。在channelRead()方法中,我们接收到了客户端的请求数据,然后生成了响应数据,并将其写入到响应缓冲区中。最后,通过调用ctx.writeAndFlush()方法将响应数据发送给客户端。 在客户端中,我们可以通过使用Java的NIO库取响应数据,将其解析后显示在页面上。下面是一个简单的例子,演示了如何在客户端中Netty服务器返回的响应数据: ```java @RestController @RequestMapping("/hello") public class HelloController { @GetMapping("/{name}") public String sayHello(@PathVariable("name") String name) throws Exception { // 创建Netty客户端 Bootstrap bootstrap = new Bootstrap(); bootstrap.group(new NioEventLoopGroup()) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new MyNettyClientHandler()); } }); // 连接Netty服务器 ChannelFuture future = bootstrap.connect("localhost", 8080).sync(); // 发送请求数据 ByteBuf requestBuf = Unpooled.copiedBuffer(name.getBytes()); future.channel().writeAndFlush(requestBuf); // 等待响应数据 future.channel().closeFuture().sync(); // 返回响应数据 return MyNettyClientHandler.responseData; } } public class MyNettyClientHandler extends ChannelInboundHandlerAdapter { public static String responseData; @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { // 解析响应数据 ByteBuf responseBuf = (ByteBuf) msg; byte[] responseBytes = new byte[responseBuf.readableBytes()]; responseBuf.readBytes(responseBytes); responseData = new String(responseBytes); // 关闭连接 ctx.close(); } } ``` 在这个例子中,我们定义了一个简单的控制器类HelloController,它使用Netty客户端向服务器发送请求数据,并等待服务器返回响应数据。在发送请求数据之后,我们调用future.channel().closeFuture().sync()方法等待服务器返回响应数据。在MyNettyClientHandler中,我们接收到了服务器返回的响应数据,然后将其解析成字符串,并将其存储在responseData静态变量中。最后,我们通过调用ctx.close()方法关闭连接。在控制器类中,我们返回了存储在responseData中的响应数据
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值