你不要和我說Netty快速入門會很難

2020-10-11 Java技術人

Netty快速入門實例-TCP服務

1、實例要求:使用IDEA創建Netty項目;

2、Netty伺服器在6668埠監聽,客戶端能發送消息給伺服器「hello,伺服器」;

3、伺服器可以回復消息給客戶端「hello,客戶端」;

4、目的:對Netty線程模型有一個初步認識,便於理解Netty模型理論;

伺服器端

public class NettyServer { public static void main(String[] args) throws Exception { /** * 說明 * 1、創建兩個線程組bossGroup 和 workerGroup * 2、bossGroup只是處理連接請求,真正和客戶端業務處理的會交給workerGroup完成 * 3、兩個都是無限循環 */ EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { //創建伺服器端的啟動對象,配置參數 Serverbootstrap bootstrap = new ServerBootstrap(); //使用鏈式編程來進行設置 //設置兩個線程組 ServerBootstrap bootstrap1 = bootstrap.group(bossGroup, workerGroup) //使用NioServerSocketChannel作為伺服器的通道實現 .channel(NioServerSocketChannel.class) //設置線程隊列得到的連接個數 .option(ChannelOption.SO_BACKLOG, 128) //設置保持獲得的連接狀態 .childOption(ChannelOption.SO_KEEPALIVE, true) //創建一個通道測試對象(匿名對象) //給我們的workerGroup的EventLoop對應的管道設置處理器 .childHandler(new ChannelInitializer<SocketChannel>() { //給pipeline設置處理器 @Override protected void initChannel(SocketChannel sc) throws Exception { sc.pipeline().addLast(new NettyServerHandler()); } }); System.out.println("......伺服器 is ready..."); //綁定一個埠並且同步,生成了一個ChannelFuture對象 //啟動伺服器(並綁定埠) ChannelFuture cf = bootstrap.bind(6668).sync(); //對關閉通道進行監聽 cf.channel().closeFuture().sync(); } finally { //優雅關閉 bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }}

伺服器端業務處理器

/** * 1、我們自定義一個Handler,需要繼承netty規定好的某個handlerAdapter(規範) * 2、這時我們自定義一個Handler,才能稱為一個Handler */public class NettyServerHandler extends ChannelInboundHandlerAdapter { /** * 讀取數據(這裡我們可以讀取客戶端發送的消息) * @param ctx 上下文對象,含有管道pipeline,通道channel,地址 * @param msg 就是客戶端發送的數據,默認是Object */ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("server ctx = "+ctx); //將msg轉成一個ByteBuf //ByteBuf 是Netty提供的,不是NIO的ByteBuffer ByteBuf buf = (ByteBuf)msg; System.out.println("客戶端發送的消息是:"+buf.toString(CharsetUtil.UTF_8)); System.out.println("客戶端地址:"+ctx.channel().remoteAddress()); } /** * 數據讀取完畢 * @param ctx */ @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { /** * writeAndFlush 是write+flush * 將數據寫入到緩衝區,並刷新,一般講,我們對這個發送的數據進行編碼 */ ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客戶端",CharsetUtil.UTF_8)); } /** * 處理異常,一般需要關閉通道 */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); }}

客戶端

public class NettyClient { public static void main(String[] args) { //客戶端需要一個事件循環組 NioEventLoopGroup group = new NioEventLoopGroup(); try { //創建客戶端啟動對象,注意客戶端使用不是ServerBootstarp而是Bootstrap Bootstrap bootstrap = new Bootstrap(); //設置相關參數 //設置線程組 bootstrap.group(group) //設置客戶端通道的實現類(反射) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel sc) throws Exception { //加入自己的處理器 sc.pipeline().addLast(new NettyClientHandler()); } }); System.out.println("客戶端 ok..."); //啟動客戶端去連接伺服器端 //關於ChannelFuture要分析,涉及到netty的異步模型 ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6668).sync(); //給關閉通道進行監聽 channelFuture.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { group.shutdownGracefully(); } }}

客戶端業務處理器

public class NettyClientHandler extends ChannelInboundHandlerAdapter { /** * 當通道就緒就會觸發該方法 */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("client "+ctx); ctx.writeAndFlush(Unpooled.copiedBuffer("hello,服務端 ", CharsetUtil.UTF_8)); } /** *當通道有讀取事件時會觸發 */ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; System.out.println("伺服器回復的消息:"+buf.toString(CharsetUtil.UTF_8)); System.out.println("伺服器的地址:"+ctx.channel().remoteAddress()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); }}

Netty快速入門實例-HTTP服務

1、Netty伺服器在6668埠監聽,瀏覽器發出請求「http://localhost:6668」;

2、伺服器可以回復消息給客戶端「Hello 我是伺服器5」,並對特定請求資源進行過濾;

3、目的:Netty可以做Http服務開發,並且理解Handler實例和客戶端及其請求的關係;

服務端代碼

/** * 服務端 */public class TestServer { public static void main(String[] args) { NioEventLoopGroup bossGroup = new NioEventLoopGroup(1); NioEventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class). childHandler(new TestServerInitializer()); ChannelFuture channelFuture = serverBootstrap.bind(6668).sync(); channelFuture.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); }finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }}

TestServerInitializer代碼

public class TestServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { //向管道加入處理器 //得到管道 ChannelPipeline pipeline = ch.pipeline(); //加入一個netty提供的httpServerCodec codec=>[coder - decoder] //HttpserverCodec是netty提供的處理http的 編-解碼器 pipeline.addLast("MyhttpServerCodec",new HttpServerCodec()); //增加一個自定義的handler pipeline.addLast("MyTestHttpServerHandler",new TestHttpServerHandler()); }}

業務處理模塊TestHttpServerHandler

/** * 1、SimpleChannelInboundHandler 是 SimpleChannelInboundHandlerAdapter * 2、HttpObject 客戶端和服務端互相通訊的數據被封裝成 HttpObject */public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> { //讀取客戶端數據 @Override protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception { //判斷msg 是不是HttpRequest if(msg instanceof HttpRequest){ //每開一個瀏覽器都回產生一個新的TestHttpServerHandler,因為http協議用完就關掉 System.out.println("pipeline hashcode "+ctx.pipeline().hashCode()+",TestHttpServerHandler hashcode="+this.hashCode()); System.out.println("msg 類型="+msg.getClass()); System.out.println("客戶端地址"+ctx.channel().remoteAddress()); //獲取到 HttpRequest httpRequest = (HttpRequest) msg; //獲取uri,過濾指定資源 URI uri = new URI(httpRequest.uri()); if("/favicon.ico".equals(uri.getPath())){ System.out.println("請求了faviconicon,不做響應"); return; } //回覆信息給瀏覽器 ByteBuf content = Unpooled.copiedBuffer("hello,我是伺服器", CharsetUtil.UTF_8); //構造一個http的響應,即httpResponse FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content); response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain;charset=utf-8"); response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes()); //將構建好的response返回 ctx.writeAndFlush(response); } }}

測試結果

HTTP請求用例

相關焦點

  • netty快速入門教程
    什麼是nettyNetty 是一個提供 asynchronous event-driven (異步事件驅動)的網絡應用框架,是一個用以快速開發高性能、高可靠性協議的伺服器和客戶端。換句話說,Netty 是一個 NIO 客戶端伺服器框架,使用它可以快速簡單地開發網絡應用程式,比如伺服器和客戶端的協議。
  • Netty學習-Netty 快速入門實例-TCP 服務
    </groupId> <artifactId>netty-all</artifactId> <version>4.1.22.Final</version> </dependency>碼代碼之前,首先看看我的目錄結構,有個心理準備,很簡單就幾個類O(∩_∩)
  • 八、Netty入門服務端代碼
    導論前面幾篇文章我們分別對 、 、 、 、 、 、 等幾個緯度對JAVAIO和NIO體系做了詳細介紹,並由簡到深的根據IO體系的升級過程做了系統分析。如果能深入理解以上兩篇文章,那麼後續對於Netty的學習和理解Netty的Reactor會非常簡單。今天我們先通過入門的角度從Idea中導入Netty包,並且使用Netty構建一個可用於接受數據的服務端。
  • 外籍教授說,python編程入門很難嗎?看完它就能快速入門
    為什麼能快速入門python呢?>它適合各個層次的python開發人員閱讀,無論是入門,還是有一定基礎,都適合。,在這裡,沒有深奧的理論和高級應用,基本上都是圍繞基礎內容展開的。結合常見任務、簡潔的步驟,幫助你快速學習python。
  • 「網絡通信」Netty 入門實戰
    [網絡通信] Netty 入門實戰簡介什麼是 Netty?讓我們帶著問題來跟著官網的 Demo 教程先入個門。依賴實戰丟棄伺服器響應伺服器時間伺服器流數據傳輸對象序列化傳輸關閉小結REFERENCESNetty 是異步事件驅動的Java開源網絡應用程式框架,用於快速開發可維護的高性能協議伺服器和客戶端。
  • 史上最通俗Netty入門長文:基本介紹、環境搭建、動手實戰
    一分鐘帶你讀懂Java的NIO和經典IO的區別》;3)《史上最強Java NIO入門:擔心從入門到放棄的,請讀這篇!》(* 推薦必讀)。一方面:現在物聯網的應用無處不在,大量的項目都牽涉到應用傳感器和伺服器端的數據通信,Netty作為基礎通信組件、能夠輕鬆解決之前有較高門檻的通信系統開發,你不用再為如何解析各類簡單、或複雜的通訊協議而薅頭髮了,有過這方面開發經驗的程式設計師會有更深刻、或者說刻骨銘心的體會。
  • Netty拆包粘包和服務啟動流程分析,一文帶你掌握工作流程
    這裡讓你清楚了解 NioEventLoopGroup,NioEventLoop,Channel 三者之間的關係。這裡讓你清楚了解 ServerBootstrap,Channel 兩者之間的關係。看懂了這塊的理論知識,後面Netty拆包粘包的代碼就非常的簡單。
  • 當Tomcat遇上Netty
    此時,我的思路已經不順暢了,下面是跑偏之路。第十一步,思考在把XssFilter和AuthFilter相繼刪除之後,已經只剩下一個啟動類了,當然,還有一個新加的監控類。第十三步,打車回家在車上的時候,一直在想這個問題,回憶整個過程,會不會是我的方向錯了呢?Spring Cloud Gateway出來也挺久了,沒聽說有內存洩漏的問題啊,此時,我開始自我懷疑了。不行,我回家得自己寫一個項目,使用Spring Cloud Gateway跑一下試試。
  • Python快速入門經典有哪些?談談我見解
    python快速入門,說實話,這不是一個簡單的事情。但既然寫到這個話題,就不妨聊聊我的見解。那麼,如果單講python如何快速入門,如何快速學會基礎,我認為也不一定很難。主要就是你如何學的問題,或者說,你的學習教程。
  • Netty從入門到禿頭:websocket
    --netty的依賴集合,都整合在一個依賴裡面了--> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.6.Final</version>
  • 大家都用 Netty,為什麼不用Java NIO?
    敲黑板:高並發會對伺服器產生多少連接負載?伺服器連接數如何突破百萬?長連接,短連接的場景和優缺點?Netty中的拆包粘包和TCP什麼關係?發送數據為什麼會收不到?如何佔用更少的資源完成更多的並發連接和請求處理?中間件開發中對IO及netty的設計?
  • 解決websocket和netty中無法注入service
    首先,目前我的項目是springboot+netty,在netty-client中注入了service,但是在調用service的時候一直報null空指針異常。剛開始實驗了N次還是無法解決這個問題,以為是自己的寫法問題,並沒有想到是service無法實例化的問題,後來通過度娘,才找到了解決方法。
  • 程式設計師:利用Netty來寫一個簡單的聊天室、心跳檢測
    Netty提供異步的、事件驅動的網絡應用程式框架和工具,用以快速開發高性能、高可靠性的網絡伺服器和客戶端程序。也就是說,Netty 是一個基於NIO的客戶、伺服器端編程框架,使用Netty 可以確保你快速和簡單的開發出一個網絡應用,例如實現了某種協議的客戶、服務端應用。Netty相當於簡化和流線化了網絡應用的編程開發過程,例如:基於TCP和UDP的socket服務開發。
  • 該試試Netty了
    一、前言Netty是一個開源的異步事件驅動的網絡應用程式框架,用於快速開發可維護的高性能協議伺服器和客戶端。Netty的創始人是韓國人trustin lee,他現在韓國line公司工作,早前應用較多的Mina也是這牛人的作品。
  • 哈佛大學教授說,快速入門python,這三個原則是你要知道的
    很多人都說Python是最容易入門的程式語言,但是入門Python,你必須要明白這三個原則。否則,你一定很難入門Python。)我接觸過一些想學Python但沒有基礎的人,他們其中很多都很執著於某一兩個知識點,長時間沒有任何收穫。
  • 超詳細Netty入門,看這篇就夠了
    2.1 NIO的缺點對於這個問題,之前我寫了一篇文章對NIO有比較詳細的介紹,NIO的主要問題是:NIO的類庫和API繁雜,學習成本高,你需要熟練掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。
  • 小白科普:Netty有什麼用?
    敲黑板:高並發會對伺服器產生多少連接負載?長連接,短連接的場景和優缺點?分布式,微服務中RPC,restful的實現細節?Netty中的拆包粘包和TCP什麼關係?發送數據為什麼會收不到?如何佔用更少的資源完成更多的並發連接和請求處理?中間件開發中對IO及netty的設計?
  • Netty的使用:Client端
    最近寫了一個和c++server端按需通信的項目,自己記錄一下。Netty介紹是一款基於NIO(Nonblocking I/O,非阻塞IO)開發的網絡通信框架,提供異步的、事件驅動的網絡應用程式框架和工具,用以快速開發高性能、高可靠性的網絡伺服器和客戶端程序。
  • Netty結合Protostuff傳輸35萬個對象案例
    當然,壓測時我用的數據量大、發送請求非常密集,單機是每秒前100ms發送2萬個對象,其他900ms歇息,死循環發送,共計40臺機器作為客戶端,同時往2臺netty Server伺服器發送對象,那麼平均每個server每秒大概要接收40萬個對象,由於後面還有業務邏輯,邏輯每秒只能處理35萬實測。
  • 不要說阿里很難做,不要說店鋪運營不起來,那是你不懂得規劃
    二、 技術 我說的技術不是說你要掌握多厲害的技巧,是說基本的操作,如果你連最基本的操作都不會的話,那流量來了,你也留不住。不要老想著走捷徑,這也不是好事,就不要惦記這事了,作為賣家們,你們要懂得的是怎麼去推廣,怎麼去優化,搞懂數字營銷就可以了。