Netty在IDEA中搭建HelloWorld服务端并对Netty执行流程与重要组件进行介绍
場景
什么是Netty
Netty 是一個利用 Java 的高級網(wǎng)絡(luò)的能力,隱藏其背后的復(fù)雜性而提供一個易于使用的 API 的客戶端/服務(wù)器框架。
Netty 是基于 Java NIO 的異步事件驅(qū)動的網(wǎng)絡(luò)應(yīng)用框架,使用 Netty 可以快速開發(fā)網(wǎng)絡(luò)應(yīng)用,Netty 提供了高層次的抽象來簡化 TCP 和 UDP 服務(wù)器的編程,但是你仍然可以使用底層的 API。
Netty 的內(nèi)部實現(xiàn)是很復(fù)雜的,但是 Netty 提供了簡單易用的API從網(wǎng)絡(luò)處理代碼中解耦業(yè)務(wù)邏輯。Netty 是完全基于 NIO 實現(xiàn)的,所以整個 Netty 都是異步的。
Netty 是最流行的 NIO 框架,它已經(jīng)得到成百上千的商業(yè)、商用項目驗證,許多框架和開源組件的底層 rpc 都是使用的 Netty,如 Dubbo、Elasticsearch 等等。
這里使用IDEA和Gradle,也可以使用Maven作為依賴管理工具。
在Windows中下載配置以及在IDEA中配置Gradle參照如下
https://mp.csdn.net/console/editor/html/108578033
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
關(guān)注公眾號
霸道的程序猿
獲取編程相關(guān)電子書、教程推送與免費下載。
實現(xiàn)
IDEA新建一個Gradle項目
?
配置使用Java并設(shè)置JDK
新建之后的項目目錄
?
此時會自動在build.gradle類似于Maven的pom.xml中引入了junit的依賴。
這里需要引入Netty的依賴。
瀏覽器打開Maven中央倉庫地址
https://mvnrepository.com/
搜索netty-all
?
選擇穩(wěn)定版本這里是4.1.52
?
選擇Gradle的依賴
?
將其復(fù)制進IDEA下的build.gradle中
dependencies {// https://mvnrepository.com/artifact/io.netty/netty-allcompile group: 'io.netty', name: 'netty-all', version: '4.1.52.Final' }因為上面已經(jīng)設(shè)置了自動導(dǎo)入依賴。
所以保存后就能實現(xiàn)自動導(dǎo)入。
?
同樣在上面的gradle的配置的博客中設(shè)置了jar包的存儲位置。
來到配置的jar包的存儲位置就可以看到j(luò)ar包所在的位置。
?
在項目中引入Netty后,在src下新建包,包下新建HelloWorldServer類作為服務(wù)端的啟動類
在啟動類中新建main方法
package com.badao.netty;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel;public class HelloWorldServer {public static void main(String[] args) throws? Exception{EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try{//服務(wù)端啟動類-Netty提供的啟動服務(wù)端的類ServerBootstrap serverBootstrap = new ServerBootstrap();//參數(shù)為兩個事件組 前面的用來接收請求 后面的用來處理//childHandler 設(shè)置請求到了之后進行處理的處理器serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).childHandler(new HelloWorldServerInitializer());//綁定端口ChannelFuture channelFuture = serverBootstrap.bind(70).sync();channelFuture.channel().closeFuture().sync();}finally {//關(guān)閉事件組bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}} }注意這里的都是引入的netty的包,不要引入nio的包。
首先EventLoopGroup是事件循環(huán)組,可以認為是一個死循環(huán),一直監(jiān)聽是否有連接然后處理。
這里使用兩個是Netty官方推薦,一個bossGroup只用來監(jiān)聽連接,然后交由后面的workerGroup進行處理。
ServerBootstrap是Netty的啟動服務(wù)端的類。
分別設(shè)置兩個group并設(shè)置通道為NioServerSocketChannel
然后childHandler是設(shè)置對請求具體處理的處理器。這里新建了一個HelloWorldInititalizer類作為服務(wù)端初始化的類。
下面綁定了70端口。
所以在包下再新建類HelloWorldServerInitializer作為服務(wù)端初始化器,并使其繼承ChannelInitializer
然后重寫initChannel方法,連接一旦被創(chuàng)建后就會執(zhí)行此方法。
package com.badao.netty;import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.http.HttpServerCodec;//服務(wù)端初始化器 public class HelloWorldServerInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {//連接一旦被創(chuàng)建后就會執(zhí)行此方法ChannelPipeline channelPipeline = ch.pipeline();//在最后添加由Netty提供的處理器channelPipeline.addLast("httpServerCodec",new HttpServerCodec());channelPipeline.addLast("helloWorldServerHandler",new HelloWorldServerHandler());} }注意這里的繼承的泛型里面的SocketChannel是在netty包下的。
在方法中在處理的最后添加處理器,第一個添加的是Netty自帶的處理器。
后面再創(chuàng)建一個自定的處理器HelloWorldServerHandler
前面的name可以自己定義。
所以需要在包下再新建HelloWorldServerHandler處理器類并使其繼承SimpleChannelInboundHandler
然后重寫其方法channelRead0
此方法就是讀取客戶端發(fā)送過來的請求并返回響應(yīng)。
package com.badao.netty;import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.*; import io.netty.util.CharsetUtil;//自定義的處理器 public class HelloWorldServerHandler extends SimpleChannelInboundHandler<HttpObject> {//此方法就是讀取客戶端發(fā)送過來的請求并返回響應(yīng)@Overrideprotected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {if(msg instanceof HttpRequest){//構(gòu)造返回內(nèi)容ByteBuf content = Unpooled.copiedBuffer("公眾號:霸道的程序猿", CharsetUtil.UTF_8);//構(gòu)造響應(yīng)FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,content);//設(shè)置響應(yīng)頭類型response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain");//設(shè)置響應(yīng)頭長度response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes());//返回響應(yīng)ctx.writeAndFlush(response);}} }在方法中構(gòu)造返回的內(nèi)容和響應(yīng)頭,然后將其返回響應(yīng)。
這樣一個客戶端,功能是接受到請求時返回字符串"公眾號:霸道的程序猿",就搭建完成了。
找到項目下的.idea下的gradle.xml,將下面的
<option name="delegatedBuild" value="false" />改為false,如果沒有則將這行加上
?
這樣就能使用java運行main方法,gradle就不會認為其是task了。
運行最上面的服務(wù)端的main方法。
如果沒有輸出任何報錯則是運行成功。
?
怎樣去驗證服務(wù)端搭建成功?
這里可以使用curl去進行請求驗證
cURL是一個利用URL語法在命令行下工作的文件傳輸工具,1997年首次發(fā)行。
它支持文件上傳和下載,所以是綜合傳輸工具,但按傳統(tǒng),習(xí)慣稱cURL為下載工具。
cURL還包含了用于程序開發(fā)的libcurl。
cURL支持的通信協(xié)議有FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP。
curl還支持SSL認證、HTTP POST、HTTP PUT、FTP上傳, HTTP form based upload、proxies、HTTP/2、cookies、用戶名+密碼認證(Basic, Plain, Digest, CRAM-MD5, NTLM, Negotiate and Kerberos)、file transfer resume、proxy tunneling。
這里因為是在Windows下,所以需要下載curl
下載地址:
https://curl.haxx.se/windows/
?
這里下載64位的,將其解壓到磁盤上的某目錄。
?
找到其目錄下的bin目錄,即curl.exe所在的目錄。
在此處打開cmd
curl http://localhost:70?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的Netty在IDEA中搭建HelloWorld服务端并对Netty执行流程与重要组件进行介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Gradle在Windows下的下载安装
- 下一篇: Windows下curl的下载与使用