一,引入pom依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.45.Final</version>
</dependency>
</dependencies>
二,搭建netty-server服務端
package com.example.netty.server; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import lombok.extern.slf4j.Slf4j; import java.net.InetSocketAddress; /** * 服務啟動監聽器 **/ @Slf4j public class NettyServer { public void start(InetSocketAddress socketAddress) { //new 一個主線程組 EventLoopGroup bossGroup = new NioEventLoopGroup(1); //new 一個工作線程組 EventLoopGroup workGroup = new NioEventLoopGroup(200); ServerBootstrap bootstrap = new ServerBootstrap() .group(bossGroup, workGroup) .channel(NioServerSocketChannel.class) .childHandler(new ServerChannelInitializer()) .localAddress(socketAddress) //設置隊列大小 .option(ChannelOption.SO_BACKLOG, 1024) // 兩小時內沒有數據的通信時,TCP會自動發送一個活動探測數據報文 .childOption(ChannelOption.SO_KEEPALIVE, true); //綁定端口,開始接收進來的連接 try { ChannelFuture future = bootstrap.bind(socketAddress).sync(); log.info("服務器啟動開始監聽端口: {}", socketAddress.getPort()); future.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { //關閉主線程組 bossGroup.shutdownGracefully(); //關閉工作線程組 workGroup.shutdownGracefully(); } } }
package com.example.netty.server; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import lombok.extern.slf4j.Slf4j; /** * netty服務端處理器 **/ @Slf4j public class NettyServerHandler extends ChannelInboundHandlerAdapter { /** * 客戶端連接會觸發 */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { log.info("Channel active......"); } /** * 客戶端發消息會觸發 */ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { log.info("服務器收到消息: {}", msg.toString()); ctx.write("你也好哦"); ctx.flush(); } /** * 發生異常觸發 */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }
package com.example.netty.server; import io.netty.channel.ChannelInitializer; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.util.CharsetUtil; import io.netty.channel.socket.SocketChannel; /** * netty服務初始化器 **/ public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { //添加編解碼 socketChannel.pipeline().addLast("decoder", new StringDecoder(CharsetUtil.UTF_8)); socketChannel.pipeline().addLast("encoder", new StringEncoder(CharsetUtil.UTF_8)); socketChannel.pipeline().addLast(new NettyServerHandler()); } }
package com.example.netty.server; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import java.net.InetSocketAddress; @SpringBootApplication public class NettyServerApplication { public static void main(String[] args) { SpringApplication.run(NettyServerApplication.class, args); //啟動服務端 NettyServer nettyServer = new NettyServer(); nettyServer.start(new InetSocketAddress("127.0.0.1", 8090)); } }
三,搭建netty-client客戶端
package com.example.netty.client; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import lombok.extern.slf4j.Slf4j; @Slf4j public class NettyClient { public void start() { EventLoopGroup group = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap() .group(group) //該參數的作用就是禁止使用Nagle算法,使用於小數據即時傳輸 .option(ChannelOption.TCP_NODELAY, true) .channel(NioSocketChannel.class) .handler(new NettyClientInitializer()); try { ChannelFuture future = bootstrap.connect("127.0.0.1", 8090).sync(); log.info("客戶端成功...."); //發送消息 future.channel().writeAndFlush("你好啊"); // 等待連接被關閉 future.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); }finally { group.shutdownGracefully(); } } }
package com.example.netty.client; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import lombok.extern.slf4j.Slf4j; /** * 客戶端處理器 **/ @Slf4j public class NettyClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { log.info("客戶端Active ....."); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { log.info("客戶端收到消息: {}", msg.toString()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }
package com.example.netty.client; 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; /** * 客戶端初始化器 **/ public class NettyClientInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast("decoder", new StringDecoder()); socketChannel.pipeline().addLast("encoder", new StringEncoder()); socketChannel.pipeline().addLast(new NettyClientHandler()); } }
package com.example.netty.client; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class NettyClientApplication { public static void main(String[] args) { SpringApplication.run(NettyClientApplication.class, args); //啟動netty客戶端 NettyClient nettyClient = new NettyClient(); nettyClient.start(); } }
收工!