乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      你敢信?就是這個Netty的網(wǎng)絡框架差點把我整瘋了,哭jj

       Coder編程 2021-06-23

      不知道大家對下面的這個圖標眼熟不

      你敢信?就是這個Netty的網(wǎng)絡框架差點把我整瘋了,哭jj

      對,這就是netty,最近差點整瘋了我的一個網(wǎng)絡框架,下方是官網(wǎng)對他的描述,感興趣大家可以去官網(wǎng)看一下,這不是今天的重點,接著往下看:

      你敢信?就是這個Netty的網(wǎng)絡框架差點把我整瘋了,哭jj

      為啥說這玩意快把我整瘋了啊,哎,好奇害死貓啊,我這人是對網(wǎng)絡一竅不通,所以網(wǎng)絡的東西我一般是不去觸碰的,但是,最近公司的人以及各大論壇里面,netty這個技術真的是如日中天,我身邊的朋友去面試的回來也說這個技術問的有點多啊,我好奇心作怪就想去試一下,然后在網(wǎng)上查找了很多資料和代碼實現(xiàn),我就覺得沒啥,于是自己搭建了一下玩玩,比方說下面我要跟大家說的這個重點:netty+springboot實現(xiàn) 長連接 - 心跳 - 自動重連 - 通信

      然后出問題了,我作為程序員的執(zhí)拗,不能有bug,這就出問題了,我們先來看一下網(wǎng)上的源碼
      個人公眾號:Java架構師聯(lián)盟

      package com.gzky.study;
      
      import com.gzky.study.netty.MsgPckDecode;
      import com.gzky.study.netty.MsgPckEncode;
      import io.netty.bootstrap.Bootstrap;
      import io.netty.channel.*;
      import io.netty.channel.nio.NioEventLoopGroup;
      import io.netty.channel.socket.nio.NioSocketChannel;
      import io.netty.handler.timeout.IdleStateHandler;
      
      import java.util.Scanner;
      
      /**
       * @author biws
       * @date 2020/11/20
       **/
      public class TestFor {
          private static NioEventLoopGroup worker = new NioEventLoopGroup();
      
          private static Channel channel;
      
          private static Bootstrap bootstrap;
      
          boolean flag = true;
      
          public static void main(String[] args) {
      
              for (int i = 0; i < 30; i++) {
                  long start = System.currentTimeMillis();
                  Scanner sc= new Scanner(System.in);
                  long end = System.currentTimeMillis();
                  long l1 = end - start;
      
                  long start2 = System.currentTimeMillis();
                  start();
                  long end2 = System.currentTimeMillis();
                  long l2 = end2 - start2;
      
                  if (l1 > l2) {
                      System.out.println("Scanner大,false");
                  } else {
                      System.out.println("true--------------");
                  }
              }
          }
      
          private static void start() {
              bootstrap = new Bootstrap();
              bootstrap.group(worker)
                      .channel(NioSocketChannel.class)
                      .option(ChannelOption.TCP_NODELAY, true)
                      .handler(new ChannelInitializer<Channel>() {
                          @Override
                          protected void initChannel(Channel ch) throws Exception {
                              // TODO Auto-generated method stub
                              ChannelPipeline pipeline = ch.pipeline();
      
                              pipeline.addLast(new IdleStateHandler(3, 3, 5));
      
                              pipeline.addLast(new MsgPckDecode());
      
                              pipeline.addLast(new MsgPckEncode());
      
                          }
                      });
              doConnect();
          }
      
          protected static void doConnect() {
      
              if (channel != null && channel.isActive()) {
                  return;
              }
              ChannelFuture connect = bootstrap.connect("127.0.0.1", 8089);
              //實現(xiàn)監(jiān)聽通道連接的方法
              connect.addListener(new ChannelFutureListener() {
      
                  @Override
                  public void operationComplete(ChannelFuture channelFuture) throws Exception {
      
                      if (channelFuture.isSuccess()) {
                          channel = channelFuture.channel();
                          System.out.println("連接成功");
                      }
                  }
              });
          }
      }
      

      你敢信?就是這個Netty的網(wǎng)絡框架差點把我整瘋了,哭jj

      好了,到這里,沒問題,成功實現(xiàn),我就覺得這也沒啥啊,這不是挺簡單的嘛,難道說他們是在面試的時候問道底層源碼啊,這玩意整不了 啊,可能這就是命啊,我就沒關,讓他執(zhí)行著,喝口飲料休息一下,沒想到突然就報錯了,然后又好了,emmmm,這不是自己給自己找事啊

      通過測試,模擬30次大約有3次失敗的樣子,回看源碼,其實代碼中存在的矛盾不難發(fā)現(xiàn),就是Scanner和Channel誰的創(chuàng)建時間更短。可能在他的電腦上沒有什么問題,但是在我這里就不行,感覺更像是在賭博,看你運氣怎么樣,這樣那行啊,理工科的男孩子怎么能靠賭博呢?

      但是,咋整,我就在這一塊就是一個渣渣啊,沒辦法,最后還是求助了公司的大神,幸好代碼量不是特別大,抽了個周末的下午,俺倆一起在原有的代碼基礎上對客戶端進行可以定程度的改造,現(xiàn)在所有的功能都已經(jīng)實現(xiàn),下面附上改進后的代碼,有需要的朋友可以自己動手實現(xiàn)一下

      還是建議實現(xiàn)一下,畢竟可能我這里可以了,但是在你的pc端又會有其他的而不一樣的問題,當然了,要是有云服務器測試一下更 不錯

      一、pom文件

      <!-- 解碼and編碼器 -->
      <!-- https:///artifact/org.msgpack/msgpack -->
      <dependency>
          <groupId>org.msgpack</groupId>
          <artifactId>msgpack</artifactId>
          <version>0.6.12</version>
      </dependency>
      <!-- 引入netty依賴 -->
      <dependency>
          <groupId>io.netty</groupId>
          <artifactId>netty-all</artifactId>
          <version>4.1.6.Final</version>
      </dependency>
      

      二、配置項

      package com.gzky.study.netty;
      
      /**
       * 配置項
       *
      *
       * @author biws
       * @date 2020/11/20
       **/
      public interface TypeData {
          //客戶端代碼
          byte PING = 1;
      
          //服務端代碼
          byte PONG = 2;
      
          //顧客
          byte CUSTOMER = 3;
      }
      

      三、消息類型分離器

      package com.gzky.study.netty;
      
      import org.msgpack.annotation.Message;
      
      import java.io.Serializable;
      
      /**
       * 消息類型分離器
       *
      *
       * @author biws
       * @date 2020/11/20
       **/
      @Message
      public class Model implements Serializable {
      
          private static final long serialVersionUID = 1L;
      
          //類型
          private int type;
      
          //內容
          private String body;
      
          public int getType() {
              return type;
          }
      
          public void setType(int type) {
              this.type = type;
          }
      
          public String getBody() {
              return body;
          }
      
          public void setBody(String body) {
              this.body = body;
          }
      
          @Override
          public String toString() {
              return "Model{" +
                      "type=" + type +
                      ", body='" + body + '\'' +
                      '}';
          }
      }
      

      四、編碼器

      package com.gzky.study.netty;
      
      import io.netty.buffer.ByteBuf;
      import io.netty.channel.ChannelHandlerContext;
      import io.netty.handler.codec.MessageToByteEncoder;
      import org.msgpack.MessagePack;
      
      /**
       * 編碼器
       *
      *
       * @author biws
       * @date 2020/11/20
       **/
      public class MsgPckEncode extends MessageToByteEncoder<Object> {
      
          @Override
          protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf buf)
                  throws Exception {
              // TODO Auto-generated method stub
              MessagePack pack = new MessagePack();
      
              byte[] write = pack.write(msg);
      
              buf.writeBytes(write);
          }
      }
      

      五、解碼器

      package com.gzky.study.netty;
      
      import io.netty.buffer.ByteBuf;
      import io.netty.channel.ChannelHandlerContext;
      import io.netty.handler.codec.MessageToMessageDecoder;
      import org.msgpack.MessagePack;
      
      import java.util.List;
      
      /**
       * 解碼器
       *
      *
       * @author biws
       * @date 2020/11/20
       **/
      public class MsgPckDecode extends MessageToMessageDecoder<ByteBuf> {
      
          @Override
          protected void decode(ChannelHandlerContext ctx, ByteBuf msg,
                                List<Object> out) throws Exception {
      
              final  byte[] array;
      
              final int length = msg.readableBytes();
      
              array = new byte[length];
      
              msg.getBytes(msg.readerIndex(), array, 0, length);
      
              MessagePack pack = new MessagePack();
      
              out.add(pack.read(array, Model.class));
      
          }
      }
      

      六、公用控制器

      package com.gzky.study.netty;
      
      import io.netty.channel.ChannelHandlerContext;
      import io.netty.channel.ChannelInboundHandlerAdapter;
      import io.netty.handler.timeout.IdleStateEvent;
      
      /**
       * 公用控制器
       *
       * @author biws
       * @date 2020/11/20
       **/
      public abstract class Middleware extends ChannelInboundHandlerAdapter {
          protected String name;
          //記錄次數(shù)
          private int heartbeatCount = 0;
      
          //獲取server and client 傳入的值
          public Middleware(String name) {
              this.name = name;
          }
          /**
           *繼承ChannelInboundHandlerAdapter實現(xiàn)了channelRead就會監(jiān)聽到通道里面的消息
           */
          @Override
          public void channelRead(ChannelHandlerContext ctx, Object msg)
                  throws Exception {
              Model m = (Model) msg;
              int type = m.getType();
              switch (type) {
                  case 1:
                      sendPongMsg(ctx);
                      break;
                  case 2:
                      System.out.println(name + " get  pong  msg  from" + ctx.channel().remoteAddress());
                      break;
                  case 3:
                      handlerData(ctx,msg);
                      break;
                  default:
                      break;
              }
          }
      
          protected abstract void handlerData(ChannelHandlerContext ctx,Object msg);
      
          protected void sendPingMsg(ChannelHandlerContext ctx){
              Model model = new Model();
      
              model.setType(TypeData.PING);
      
              ctx.channel().writeAndFlush(model);
      
              heartbeatCount++;
      
              System.out.println(name + " send ping msg to " + ctx.channel().remoteAddress() + "count :" + heartbeatCount);
          }
      
          private void sendPongMsg(ChannelHandlerContext ctx) {
      
              Model model = new Model();
      
              model.setType(TypeData.PONG);
      
              ctx.channel().writeAndFlush(model);
      
              heartbeatCount++;
      
              System.out.println(name +" send pong msg to "+ctx.channel().remoteAddress() +" , count :" + heartbeatCount);
          }
      
          @Override
          public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
                  throws Exception {
              IdleStateEvent stateEvent = (IdleStateEvent) evt;
      
              switch (stateEvent.state()) {
                  case READER_IDLE:
                      handlerReaderIdle(ctx);
                      break;
                  case WRITER_IDLE:
                      handlerWriterIdle(ctx);
                      break;
                  case ALL_IDLE:
                      handlerAllIdle(ctx);
                      break;
                  default:
                      break;
              }
          }
      
          protected void handlerAllIdle(ChannelHandlerContext ctx) {
              System.err.println("---ALL_IDLE---");
          }
      
          protected void handlerWriterIdle(ChannelHandlerContext ctx) {
              System.err.println("---WRITER_IDLE---");
          }
      
          protected void handlerReaderIdle(ChannelHandlerContext ctx) {
              System.err.println("---READER_IDLE---");
          }
      
          @Override
          public void channelActive(ChannelHandlerContext ctx) throws Exception {
              // TODO Auto-generated method stub
              System.err.println(" ---"+ctx.channel().remoteAddress() +"----- is  action" );
          }
      
          @Override
          public void channelInactive(ChannelHandlerContext ctx) throws Exception {
              // TODO Auto-generated method stub
              System.err.println(" ---"+ctx.channel().remoteAddress() +"----- is  inAction");
          }
      }
      

      七、客戶端

      package com.gzky.study.netty;
      
      import io.netty.bootstrap.Bootstrap;
      import io.netty.channel.*;
      import io.netty.channel.nio.NioEventLoopGroup;
      import io.netty.channel.socket.nio.NioSocketChannel;
      import io.netty.handler.timeout.IdleStateHandler;
      
      import java.util.Scanner;
      import java.util.concurrent.TimeUnit;
      
      /**
       * Client客戶端
      *
       * @author biws
       * @date 2020/11/20
       **/
      public class Client {
          private NioEventLoopGroup worker = new NioEventLoopGroup();
      
          private Channel channel;
      
          private Bootstrap bootstrap;
      
          boolean flag = true;
      
          public static void main(String[] args) {
              Client client = new Client();
      
              client.start();
      
              client.sendData();
      
      //通信結束,關閉客戶端
              client.close();
          }
      
          private void close() {
              channel.close();
              worker.shutdownGracefully();
          }
      
          private void start() {
              bootstrap = new Bootstrap();
              bootstrap.group(worker)
                      .channel(NioSocketChannel.class)
                      .option(ChannelOption.TCP_NODELAY, true)
                      .handler(new ChannelInitializer<Channel>() {
                          @Override
                          protected void initChannel(Channel ch) throws Exception {
                              // TODO Auto-generated method stub
                              ChannelPipeline pipeline = ch.pipeline();
      
                              pipeline.addLast(new IdleStateHandler(3, 3, 5));
      
                              pipeline.addLast(new MsgPckDecode());
      
                              pipeline.addLast(new MsgPckEncode());
      
                              pipeline.addLast(new Client3Handler(Client.this));
                          }
                      });
              doConnect();
          }
      
          /**
           * 連接服務端 and 重連
           */
          protected void doConnect() {
      
              if (channel != null && channel.isActive()) {
                  return;
              }
              ChannelFuture connect = bootstrap.connect("127.0.0.1", 8089);
              //實現(xiàn)監(jiān)聽通道連接的方法
              connect.addListener(new ChannelFutureListener() {
      
                  @Override
                  public void operationComplete(ChannelFuture channelFuture) throws Exception {
      
                      if (channelFuture.isSuccess()) {
                          channel = channelFuture.channel();
                          System.out.println("連接成功");
                      } else {
                          if (flag) {
                              System.out.println("每隔2s重連....");
                              channelFuture.channel().eventLoop().schedule(new Runnable() {
      
                                  @Override
                                  public void run() {
                                      // TODO Auto-generated method stub
                                      doConnect();
                                  }
                              }, 2, TimeUnit.SECONDS);
                          }
                      }
                  }
              });
          }
      
          /**
           * 向服務端發(fā)送消息
           */
          private void sendData() {
          //創(chuàng)建連接成功之前停在這里等待
              while (channel == null || !channel.isActive()) {
                  System.out.println("等待連接···");
                  try {
                      Thread.sleep(1000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
              System.out.println("連接成功等待輸入:");
              flag = true;
              Scanner sc = new Scanner(System.in);
              while (flag) {
                  String nextLine = sc.nextLine();
                  if ("end".equalsIgnoreCase(nextLine)) {
                      flag = false;
                  }
                  Model model = new Model();
                  model.setType(TypeData.CUSTOMER);
                  model.setBody(nextLine);
                  channel.writeAndFlush(model);
              }
          }
      }
      

      八、客戶端控制器

      package com.gzky.study.netty;
      
      import io.netty.channel.ChannelHandlerContext;
      
      /**
       * 客戶端控制器
      *
       * @author biws
       * @date 2020/11/20
       **/
      public class Client3Handler extends Middleware {
          private Client client;
      
          public Client3Handler(Client client) {
              super("client");
              this.client = client;
          }
      
          @Override
          protected void handlerData(ChannelHandlerContext ctx, Object msg) {
              // TODO Auto-generated method stub
              Model model = (Model) msg;
              System.out.println("client  收到數(shù)據(jù): " + model.toString());
          }
          @Override
          protected void handlerAllIdle(ChannelHandlerContext ctx) {
              // TODO Auto-generated method stub
              super.handlerAllIdle(ctx);
              sendPingMsg(ctx);
          }
          @Override
          public void channelInactive(ChannelHandlerContext ctx) throws Exception {
              // TODO Auto-generated method stub
              super.channelInactive(ctx);
              client.doConnect();
          }
          @Override
          public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
                  throws Exception {
              System.out.println(name + "exception :"+ cause.toString());
          }
      }
      

      九、服務端

      package com.gzky.study.netty;
      
      import io.netty.bootstrap.ServerBootstrap;
      import io.netty.channel.*;
      import io.netty.channel.nio.NioEventLoopGroup;
      import io.netty.channel.socket.nio.NioServerSocketChannel;
      import io.netty.handler.timeout.IdleStateHandler;
      
      /**
       * 服務端
      *
       * @author biws
       * @date 2020/11/20
       **/
      public class Server {
          public static void main(String[] args) {
              EventLoopGroup bossGroup = new NioEventLoopGroup(1);
      
              EventLoopGroup workerGroup = new NioEventLoopGroup(4);
              try {
                  ServerBootstrap serverBootstrap = new ServerBootstrap();
      
                  serverBootstrap.group(bossGroup, workerGroup)
                          .channel(NioServerSocketChannel.class)
                          .localAddress(8089)
                          .childHandler(new ChannelInitializer<Channel>() {
      
                              @Override
                              protected void initChannel(Channel ch) throws Exception {
                                  // TODO Auto-generated method stub
                                  ChannelPipeline pipeline = ch.pipeline();
                                  pipeline.addLast(new IdleStateHandler(10,3,10));
                                  pipeline.addLast(new MsgPckDecode());
                                  pipeline.addLast(new MsgPckEncode());
                                  pipeline.addLast(new Server3Handler());
                              }
                          });
                  System.out.println("start server 8089 --");
                  ChannelFuture sync = serverBootstrap.bind().sync();
                  sync.channel().closeFuture().sync();
              } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }finally{
                  //優(yōu)雅的關閉資源
                  bossGroup.shutdownGracefully();
                  workerGroup.shutdownGracefully();
              }
          }
      
      }
      

      十、服務端控制器

      package com.gzky.study.netty;
      
      import io.netty.channel.ChannelHandlerContext;
      
      /**
       * 服務端控制器
       *
       * @author biws
       * @date 2020/11/20
       **/
      public class Server3Handler extends Middleware {
          public Server3Handler() {
              super("server");
              // TODO Auto-generated constructor stub
          }
          @Override
          protected void handlerData(ChannelHandlerContext ctx, Object msg) {
              // TODO Auto-generated method stub
              Model model  = (Model) msg;
              System.out.println("server 接收數(shù)據(jù) : " +  model.toString());
              model.setType(TypeData.CUSTOMER);
              model.setBody("client你好,server已接收到數(shù)據(jù):"+model.getBody());
              ctx.channel().writeAndFlush(model);
              System.out.println("server 發(fā)送數(shù)據(jù): " + model.toString());
          }
          @Override
          protected void handlerReaderIdle(ChannelHandlerContext ctx) {
              // TODO Auto-generated method stub
              super.handlerReaderIdle(ctx);
              System.err.println(" ---- client "+ ctx.channel().remoteAddress().toString() + " reader timeOut, --- close it");
              ctx.close();
          }
          @Override
          public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
                  throws Exception {
              System.err.println( name +"  exception" + cause.toString());
          }
      }
      

      十一、測試

      1、啟動服務端

      你敢信?就是這個Netty的網(wǎng)絡框架差點把我整瘋了,哭jj

      你敢信?就是這個Netty的網(wǎng)絡框架差點把我整瘋了,哭jj

      2、啟動客戶端

      你敢信?就是這個Netty的網(wǎng)絡框架差點把我整瘋了,哭jj

      你敢信?就是這個Netty的網(wǎng)絡框架差點把我整瘋了,哭jj

      3、客戶端發(fā)消息

      在客戶端控制臺輸入:

      你敢信?就是這個Netty的網(wǎng)絡框架差點把我整瘋了,哭jj

      服務端控制臺就可以收到hello,并且回信。

      你敢信?就是這個Netty的網(wǎng)絡框架差點把我整瘋了,哭jj

      好了,到這里,netty - springboot - 長連接 - 心跳 - 自動重連 - 通信就完成了,不知道你實現(xiàn)了沒有,建議你可以先收藏,等有時間了自己實現(xiàn)一下,尤其是剛接觸的,覺得寫得還不錯的,可以轉發(fā)一下,讓更多人看見,謝謝

      新的技術學習必定是充滿BUG的,但是,解決了就是一片光明,這樣一點點的改BUG中,剩下的就是你成長的路徑

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多