概述 本文通过一个简单的demo来介绍Netty在springboot项目中的使用,其中包括了服务器端和客户端的启动代码,客户端向服务器端发送文本消息。maven依赖dependencygroupIdio。nettygroupIdnettyallartifactIdversion4。1。76。Finalversiondependency关键点服务器端在启动的时候开放一个端口:19080客户端在启动的时候通过ip和端口连上服务器端客户端和服务器端都通过Channel对象向彼此发送数据服务器和客户端都通过继承ChannelInboundHandlerAdapter类实现对消息的读取和回写等操作服务器和客户端都通过StringDecoder和StringEncoder实现对消息的解码和转码操作服务器和客户端启动的时候都会阻塞当前线程,因此需要在一个单独的线程中进行启动消息发送的例子本例是一个springbootweb项目,项目占用了8080端口服务器端在启动的时候开放19080端口(注意不要和web端口冲突了)客户端在启动的时候连上服务器端通过webapi向客户端发送数据,客户端再通过Channel对象向服务器端发送数据服务器接收到客户端数据后也通过Channel对象向客户端发送数据server服务器端通过PostConstruct注解的方法进行启动,具体如下packagecom。ckjava。test。importio。netty。bootstrap。ServerBimportio。netty。channel。ChannelIimportio。netty。channel。ChannelOimportio。netty。channel。EventLoopGimportio。netty。channel。nio。NioEventLoopGimportio。netty。channel。socket。SocketCimportio。netty。channel。socket。nio。NioServerSocketCimportio。netty。handler。codec。string。StringDimportio。netty。handler。codec。string。StringEimportlombok。extern。slf4j。Slf4j;importorg。springframework。stereotype。Cimportjavax。annotation。PostCimportjavax。annotation。PreDimportjava。net。InetSocketAimportjava。util。concurrent。ForkJoinPSlf4jComponentpublicclassHelloWorldServer{privatestaticfinalEventLoopGroupbossGroupnewNioEventLoopGroup(1);privatestaticfinalEventLoopGroupworkerGroupnewNioEventLoopGroup();publicvoidstartServer(intport){try{ServerBootstrapsbsnewServerBootstrap()。group(bossGroup,workerGroup)。channel(NioServerSocketChannel。class)。localAddress(newInetSocketAddress(port))。childHandler(newChannelInitializerSocketChannel(){protectedvoidinitChannel(SocketChannelch)throwsException{ch。pipeline()。addLast(framer,newDelimiterBasedFrameDecoder(8192,Delimiters。lineDelimiter()));ch。pipeline()。addLast(decoder,newStringDecoder());ch。pipeline()。addLast(encoder,newStringEncoder());ch。pipeline()。addLast(newHelloWorldServerHandler());}})。option(ChannelOption。SOBACKLOG,128)。childOption(ChannelOption。SOKEEPALIVE,true);绑定端口,开始接收进来的连接sbs。bind(port)。addListener(future{log。info(String。format(服务器启动成功,并监听端口:s,port));});}catch(Exceptione){log。error(启动netty服务器端出现异常,e);}}服务器端启动,并绑定19080端口PostConstructpublicvoidinit(){ForkJoinPool。commonPool()。submit(()startServer(19080));}PreDestroypublicvoiddestroy(){bossGroup。shutdownGracefully();workerGroup。shutdownGracefully();}}服务器端HelloWorldServerHandler如下packagecom。ckjava。test。importio。netty。channel。ChannelHandlerCimportio。netty。channel。ChannelInboundHandlerAimportlombok。extern。slf4j。Slf4j;Slf4jpublicclassHelloWorldServerHandlerextendsChannelInboundHandlerAdapter{服务器端读取到客户端发送过来的数据,然后通过Channel回写数据OverridepublicvoidchannelRead(ChannelHandlerContextctx,Objectmsg){log。info(String。format(服务器端读取到从客户端:s发送过来的数据:s,ctx。channel()。remoteAddress(),msg。toString()));ctx。channel()。writeAndFlush(String。format(serverwrite:s,msg));}捕获到异常的处理OverridepublicvoidexceptionCaught(ChannelHandlerContextctx,Throwablecause){cause。printStackTrace();ctx。close();}}client客户端通过PostConstruct注解的方法进行启动,具体如下packagecom。ckjava。test。importio。netty。bootstrap。Bimportio。netty。channel。Cimportio。netty。channel。ChannelFimportio。netty。channel。ChannelIimportio。netty。channel。ChannelOimportio。netty。channel。ChannelPimportio。netty。channel。EventLoopGimportio。netty。channel。nio。NioEventLoopGimportio。netty。channel。socket。SocketCimportio。netty。channel。socket。nio。NioSocketCimportio。netty。handler。codec。string。StringDimportio。netty。handler。codec。string。StringEimportio。netty。util。concurrent。Fimportio。netty。util。concurrent。GenericFutureLimportlombok。extern。slf4j。Slf4j;importorg。springframework。stereotype。Cimportjavax。annotation。PostCimportjavax。annotation。PreDimportjava。util。concurrent。ForkJoinPSlf4jComponentpublicclassHelloWorldClient{staticfinalintSIZEInteger。parseInt(System。getProperty(size,256));privatefinalEventLoopGroupgroupnewNioEventLoopGroup();privateChannelFuturemChannelFprivatefinalThreadLocalChannelmChannelnewThreadLocal();publicvoidstartClient(Stringhost,intport){Configuretheclient。try{BootstrapbnewBootstrap();b。group(group)。channel(NioSocketChannel。class)。option(ChannelOption。TCPNODELAY,true)。handler(newChannelInitializerSocketChannel(){OverridepublicvoidinitChannel(SocketChannelch)throwsException{ChannelPipelinepch。pipeline();p。addLast(decoder,newStringDecoder());p。addLast(encoder,newStringEncoder());p。addLast(newHelloWorldClientHandler());}});mChannelFutureb。connect(host,port)。addListener(future{log。info(String。format(客户端启动成功,并监听端口:s,port));});}catch(Exceptione){log。error(启动netty客户端出现异常,e);}}客户端通过Channel对象向服务器端发送数据paramdata文本数据publicvoidsend(Stringdata){try{if(mChannel。get()null){mChannel。set(mChannelFuture。channel());}mChannel。get()。writeAndFlush(data);}catch(Exceptione){log。error(this。getClass()。getName()。concat(。sendhaserror),e);}}客户端启动,并连上服务器端PostConstructpublicvoidinit(){ForkJoinPool。commonPool()。submit(()startClient(127。0。0。1,19080));}PreDestroypublicvoiddestroy(){group。shutdownGracefully();}}客户端HelloWorldClientHandler实现如下packagecom。ckjava。test。importio。netty。channel。ChannelHandlerCimportio。netty。channel。ChannelInboundHandlerAimportlombok。extern。slf4j。Slf4j;Slf4jpublicclassHelloWorldClientHandlerextendsChannelInboundHandlerAdapter{客户端激活监听OverridepublicvoidchannelActive(ChannelHandlerContextctx){log。info(客户端激活!);}客户端读取从服务器端发送过来的消息OverridepublicvoidchannelRead(ChannelHandlerContextctx,Objectmsg){log。info(String。format(客户端读取从服务器端发送过来的数据:s,msg));}捕获异常OverridepublicvoidexceptionCaught(ChannelHandlerContextctx,Throwablecause){cause。printStackTrace();ctx。close();}}webapi数据发送入口这里只是通过packagecom。ckjava。test。importcom。ckjava。test。client。HelloWorldCimportio。swagger。annotations。Aimportorg。springframework。web。bind。annotation。GetMimportorg。springframework。web。bind。annotation。RequestMimportorg。springframework。web。bind。annotation。RequestPimportorg。springframework。web。bind。annotation。RestCimportjavax。annotation。Rimportjavax。servlet。http。HttpServletRimportjavax。servlet。http。HttpServletRauthorckjavadate202241823:50ApiRequestMapping(charsetutf8)RestControllerpublicclassHelloNettyCtrl{ResourceprivateHelloWorldClientmHelloWorldCGetMapping(nettyClient)publicvoidnettyClient(RequestParamStringdata)throwsException{mHelloWorldClient。send(data);}}测试执行如下请求curlXGEThttp:localhost:8080nettyClient?dataE4BDA0E5A5BD20ckjavaHaccept:charsetutf8输出如下22:36:00。178〔nioEventLoopGroup41〕INFOc。c。t。server。HelloWorldServerHandler服务器端读取到从客户端:127。0。0。1:9196发送过来的数据:你好ckjava22:36:00。178〔nioEventLoopGroup21〕INFOc。c。t。client。HelloWorldClientHandler客户端读取从服务器端发送过来的数据:serverwrite:你好ckjava