zoukankan      html  css  js  c++  java
  • Netty基础介绍与框架搭建

    问题所在:

            目前为止,互联网上的通讯都是通过已有的应用程序或者软件库来实现。例如,我们最常使用的就是利用HTTP协议客户端(浏览器或者其他)从远程服务器上获取信息或者远程web服务。但是,大多数协议都不是为了我们的应用而特殊定制的,就像我们几乎不会用HTTP协议来传输大规模文件,发送电子邮件或是进行实时通讯。我们需要的是一个高度优化的应用框架可以支持我们特殊的需求。例如,你可以搭建一个HTTP server却能同时支持优化的AJAX聊天应用,大型文件传输等等。你甚至可以设计自己的一个网络通讯协议。

    解决方法:

            Netty是一个高效的、异步的、基于事件驱动的网络通讯框架。使用Netty 可以快速开发出可维护的,高性能、高扩展能力的协议服务及其客户端应用。也就是说,Netty 是一个基于NIO的客户,服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。

           “快速”和“简单”并不意味着会让你的最终应用产生维护性或性能上的问题。Netty是一个吸收了多种协议的实现经验,这些协议包括FTP,SMPT,HTTP,各种二进制,文本协议,并经过相当精心设计的项目,最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。

           一些用户可能找到了某些同样声称具有这些特性的编程框架,因此你们可能想问Netty又有什么不一样的地方。这个问题的答案是Netty项目的设计哲学。从创立之初,无论是在API还是在其实现上Netty都致力于为你提供最为舒适的使用体验。虽然这并不是显而易见的,但你终将会认识到这种设计哲学将令你在阅读本指南和使用Netty时变得更加得轻松和容易。

    客户端与服务器的搭建:
            在详细介绍使用之前,先给出客户端与服务器端基本框架的搭建,以下程序以一个简单的时间服务为例,即客户端向服务器发送连接请求,服务器在收到请求之后就向客户端发送当前系统时间。在后续博客中会介绍每个环节的具体注意事项。废话就不多说了,先上代码:

    服务器端:

    TimeServer.java:

    1. package org.jboss.netty.example.time;  
    2.   
    3. import java.net.InetSocketAddress;  
    4. import java.util.concurrent.Executors;  
    5.   
    6. import org.jboss.netty.bootstrap.ServerBootstrap;  
    7. import org.jboss.netty.channel.Channel;  
    8. import org.jboss.netty.channel.ChannelFactory;  
    9. import org.jboss.netty.channel.ChannelPipeline;  
    10. import org.jboss.netty.channel.ChannelPipelineFactory;  
    11. import org.jboss.netty.channel.Channels;  
    12. import org.jboss.netty.channel.group.ChannelGroup;  
    13. import org.jboss.netty.channel.group.ChannelGroupFuture;  
    14. import org.jboss.netty.channel.group.DefaultChannelGroup;  
    15. import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;  
    16.   
    17. public class TimeServer {  
    18.       
    19.     //DefaultChannelGroup requires the name of the group as a constructor parameter. The group   
    20.     //name is solely used to distinguish one group from others.   
    21.     static final ChannelGroup allChannels = new DefaultChannelGroup("time-server" );  
    22.       
    23.     public static void main(String[] args) throws Exception{  
    24.         ChannelFactory factory = new NioServerSocketChannelFactory(  
    25.                 Executors.newCachedThreadPool(),  
    26.                 Executors.newCachedThreadPool());  
    27.           
    28.         ServerBootstrap bootstrap = new ServerBootstrap(factory);  
    29.         bootstrap.setPipelineFactory(new ChannelPipelineFactory(){  
    30.             public ChannelPipeline getPipeline(){  
    31.                 return Channels.pipeline(  
    32.                         new TimeServerHandler(),  
    33.                         new TimeEncoder()  
    34.                         );  
    35.             }  
    36.         });  
    37.         bootstrap.setOption("child.tcpNoDelay"true);  
    38.         bootstrap.setOption("child.keepAlive"true);  
    39.           
    40.         Channel channel = bootstrap.bind(new InetSocketAddress(8080));  
    41.   
    42.         allChannels.add(channel);  
    43.         waitForShutdownCommand();  
    44.         ChannelGroupFuture future = allChannels.close();  
    45.         future.awaitUninterruptibly();  
    46.         factory.releaseExternalResources();  
    47.     }  
    48. }  


    TimeServerHandler.java:

    1. package org.jboss.netty.example.time;  
    2.   
    3. import org.jboss.netty.channel.Channel;  
    4. import org.jboss.netty.channel.ChannelFuture;  
    5. import org.jboss.netty.channel.ChannelFutureListener;  
    6. import org.jboss.netty.channel.ChannelHandlerContext;  
    7. import org.jboss.netty.channel.ChannelStateEvent;  
    8. import org.jboss.netty.channel.ExceptionEvent;  
    9. import org.jboss.netty.channel.SimpleChannelHandler;  
    10.   
    11. public class TimeServerHandler extends SimpleChannelHandler{  
    12. //  @Override   
    13. //  public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e){   
    14. //      Channel ch = e.getChannel();   
    15. //      ChannelBuffer time =  ChannelBuffers.buffer(4);   
    16. //      time.writeInt((int)(System.currentTimeMillis()/1000));   
    17. //         
    18. //      ChannelFuture f = ch.write(time);   
    19. //      f.addListener(new ChannelFutureListener(){   
    20. //          public void operationComplete(ChannelFuture future){   
    21. //              Channel ch = future.getChannel();   
    22. //              ch.close();   
    23. //          }   
    24. //      });   
    25. //  }   
    26.     private static String a = "Hello";  
    27.     public TimeServerHandler(){  
    28.         System.out.println("Hello world " + a);  
    29.     }  
    30.       
    31.     @Override  
    32.     public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {  
    33.         UnixTime time = new UnixTime(System.currentTimeMillis() / 1000);  
    34.         ChannelFuture f = e.getChannel().write(time);  
    35.         f.addListener(ChannelFutureListener.CLOSE);  
    36.     }  
    37.       
    38.     @Override  
    39.     public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) {  
    40.         TimeServer.allChannels.add(e.getChannel());  
    41.     }  
    42.       
    43.     @Override  
    44.     public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e){  
    45.         e.getCause().printStackTrace();  
    46.           
    47.         Channel ch = e.getChannel();  
    48.         ch.close();  
    49.     }  
    50. }  

    TimeEncoder.java:

    1. package org.jboss.netty.example.time;  
    2.   
    3.   
    4. import static org.jboss.netty.buffer.ChannelBuffers.buffer;  
    5.   
    6. import org.jboss.netty.buffer.ChannelBuffer;  
    7. import org.jboss.netty.channel.ChannelHandlerContext;  
    8. import org.jboss.netty.channel.Channels;  
    9. import org.jboss.netty.channel.MessageEvent;  
    10. import org.jboss.netty.channel.SimpleChannelHandler;  
    11.   
    12. public class TimeEncoder extends SimpleChannelHandler{  
    13.     @Override  
    14.     public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) {  
    15.         UnixTime time = (UnixTime) e.getMessage();  
    16.         ChannelBuffer buf = buffer(4);  
    17.         buf.writeInt((int)time.getValue());  
    18.         Channels.write(ctx, e.getFuture(), buf);  
    19.     }  
    20. }  


    客户端代码:

    TimeClient.java:

    1. package org.jboss.netty.example.time;  
    2.   
    3. import java.net.InetSocketAddress;  
    4. import java.util.concurrent.Executors;  
    5.   
    6. import org.jboss.netty.bootstrap.ClientBootstrap;  
    7. import org.jboss.netty.channel.ChannelFactory;  
    8. import org.jboss.netty.channel.ChannelFuture;  
    9. import org.jboss.netty.channel.ChannelPipeline;  
    10. import org.jboss.netty.channel.ChannelPipelineFactory;  
    11. import org.jboss.netty.channel.Channels;  
    12. import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;  
    13.   
    14.   
    15. public class TimeClient {  
    16.     public static void main(String[] args) throws Exception{  
    17.         String host = args[0];  
    18.         int port = Integer.parseInt(args[1]);  
    19. //      String host = "localhost";   
    20. //      int port = 8080;           
    21.         ChannelFactory factory = new NioClientSocketChannelFactory(  
    22.                 Executors.newCachedThreadPool(),  
    23.                 Executors.newCachedThreadPool());  
    24.           
    25.         ClientBootstrap bootstrap = new  ClientBootstrap(factory);  
    26.           
    27.         bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
    28.             public ChannelPipeline getPipeline(){  
    29.                 return Channels.pipeline(  
    30.                         new TimeDecoder(),  
    31.                         new TimeClientHandler());  
    32.             }  
    33.         });  
    34.           
    35.         bootstrap.setOption("tcpNoDelay"true);  
    36.         bootstrap.setOption("keepAlive"true);  
    37.           
    38.         ChannelFuture future = bootstrap.connect(new InetSocketAddress(host,port));  
    39.         future.awaitUninterruptibly();  
    40.         if (!future.isSuccess()) {  
    41.             future.getCause().printStackTrace();  
    42.         }  
    43.         future.getChannel().getCloseFuture().awaitUninterruptibly();  
    44.         factory.releaseExternalResources();  
    45.     }  
    46. }  


    TimeDecoder.java:

    1. package org.jboss.netty.example.time;  
    2.   
    3. import org.jboss.netty.buffer.ChannelBuffer;  
    4. import org.jboss.netty.channel.Channel;  
    5. import org.jboss.netty.channel.ChannelHandlerContext;  
    6. import org.jboss.netty.handler.codec.frame.FrameDecoder;  
    7.   
    8. public class TimeDecoder extends FrameDecoder{  
    9. //  @Override   
    10. //  protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer){   
    11. //      if(buffer.readableBytes() < 4){   
    12. //          return null;   
    13. //      }   
    14. //      return buffer.readBytes(4);   
    15. //  }   
    16.       
    17.     @Override  
    18.     protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer){  
    19.         if(buffer.readableBytes() < 4){  
    20.             return null;  
    21.         }  
    22.           
    23.         return new UnixTime(buffer.readInt());  
    24.     }  
    25. }  

    TimeClientHandler.java:

    1. package org.jboss.netty.example.time;  
    2.   
    3. import java.util.Date;  
    4.   
    5. import org.jboss.netty.buffer.ChannelBuffer;  
    6. import org.jboss.netty.channel.ChannelHandlerContext;  
    7. import org.jboss.netty.channel.MessageEvent;  
    8. import org.jboss.netty.channel.SimpleChannelHandler;  
    9.   
    10. public class TimeClientHandler extends SimpleChannelHandler{  
    11. //  @Override   
    12. //  public void messageReceived(ChannelHandlerContext ctx, MessageEvent e){   
    13. //      ChannelBuffer buf = (ChannelBuffer)e.getMessage();   
    14. //      long currentTimeMillis = buf.readInt() * 1000L;   
    15. //      System.out.println(new Date(currentTimeMillis));   
    16. //      e.getChannel().close();   
    17. //  }   
    18.       
    19.     @Override  
    20.     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e){  
    21.         UnixTime m = (UnixTime)e.getMessage();  
    22.         System.out.println(m);  
    23.         e.getChannel().close();  
    24.     }  
    25. }  


    共用数据结构:

    UnixTime.java:

    1. package org.jboss.netty.example.time;  
    2.   
    3. import java.util.Date;  
    4.   
    5. public class UnixTime {  
    6.     private final long value;  
    7.     public UnixTime(long value){  
    8.         this.value = value;  
    9.     }  
    10.       
    11.     public long getValue(){  
    12.         return value;  
    13.     }  
    14.       
    15.     @Override  
    16.     public String toString(){  
    17.         return new Date(value * 1000L).toString();  
    18.     }  
    19.   
    20. }  



  • 相关阅读:
    数据可视化之 图表篇(七)柱形图
    数据可视化之 图表篇(六)桑基图
    数据可视化之 图表篇(五) PowerBI图表不够炫酷?来看看这个
    数据可视化之 图表篇(四) 那些精美的Power BI可视化图表
    数据可视化之 图表篇(三)体验Power BI最新发布的AI图表:分解树
    数据可视化之 图表篇(二)如何用Power BI制作疫情地图?
    数据可视化之 图表篇(一)Power BI可视化,几张图表认识疫情现状
    MCMC随机采样
    Linux中的计划作业
    Linux进程
  • 原文地址:https://www.cnblogs.com/sunyingyuan/p/3686264.html
Copyright © 2011-2022 走看看