Netty简单案例

  • 前言
    • 环境准备
  • 前置知识
    • 网络传输的几种实现方式
      • BIO——同步阻塞IO
      • NIO——同步非阻塞IO
      • AIO——异步非阻塞IO
      • 适用范围
    • Netty
      • 简介
      • 特点
      • 核心组件
      • 使用场景
      • 运行简图
  • 案例
    • 简介
    • 关键代码
      • 客户端
      • 服务器端
  • 运行状况
  • 总结

前言

最近学完了Netty,在这里关于Netty中实现NIO做一些小总结,并附上一个小案例,最好读者有一点Netty的基础。这里附上git的地址,看一下netty的各种案例运行一下。github

环境准备

Maven 3.X、JDK15

前置知识

网络传输的几种实现方式

建议看一下之前的一篇文章《Java网络编程之阻塞式IO与非阻塞IO》中关于阻塞和非阻塞IO在Java中的使用。

BIO——同步阻塞IO

阻塞式的IO,服务器以轮询的方式,不断查看是否有新的连接。当然其性能可以使用线程池得到略微改善。

NIO——同步非阻塞IO

通过Selector以及Channel的组合使用,实现了多路复用,虽然实现了服务器的异步处理,但是客户端必须要在服务器响应到达才能发起下一个请求,即客户端需要某线程持续监听是否有响应发送回来。大体流程如下:

AIO——异步非阻塞IO

该模式不仅服务器实现了异步、客户端也实现了异步,能够在请求没有到达之前,继续向服务器发送数据。这里之后补充。

适用范围

  • NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,JDK1.4开始支持。

  • AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如HTTP服务器等,充分调用OS参与并发操作,JDK7开始支持

Netty

简介

Netty是高性能的水平扩展的分布式架构

特点

健壮、安全、高可用、高性能、更新快、易用

核心组件

  • channel:传入、传出的数据载体
  • 回调:给请求的响应
  • Feature:异步编程的的一个任务的开启
  • 事件和ChannelHandler:很多框架,前端后端都包含这类"发布者订阅者"设计思想

使用场景

  • 内部的RPC框架
    低延迟高吞吐量
  • 负载和性能测试
    用于负载和性能测试框架,可以通过Netty和Redis结合,来以最小的负载测试端到端的消息吞吐量。
  • 同步协议的异步客户端
    Netty为同步的协议创建异步的客户端,如Kafka、Memcached。使得在同步和异步之间来回切换,不需要更改任何上有代码。

消息推送、实时流量监控都可以使用Netty,有待大家自己探索。

运行简图

简而言之,服务器监听端口,就是新建一个ServerChannel,客户端建立连接connect也是建立一个连接,之后ServerChannel收到之后通过EventLoopGroup把该channel分配到EventLoop,如果该channel对应的任务已经存在于EventLoop中就直接执行,否则就要放入EventLoop中,等待执行。

  • EventLoopGroup
    EventLoopGroup好比线程池,EventLoop好比线程,Channel的pipeline了所有的Handler

  • EventLoop的Task注册

  • 连接建立示意图

    • 服务器

    • 客户端

案例

简介

客户通过一个终端输入查询的编号,如果问题在库中存在,人工客服返回相应的回答;若不存在,就会返回默认回复——”致电人工客服“;

如果是非法的输入,就直接模拟服务器宕机,所有的连接都断开。

注意 :这里后续作为入门案例展示,如果这里看不太懂,建议看一下git的quickstart部分。这里只展示关键代码

关键代码

客户端

    public void start() {Bootstrap bootstrap = new Bootstrap ( );// 引导类的配置,包括事件组,channel类型以及处理器bootstrap.group (group).channel (NioSocketChannel.class).handler (createInitializer ( ));ChannelFuture future = bootstrap.connect (new InetSocketAddress (8080));future.syncUninterruptibly ( );channel = future.channel ( );}// 注册所有的处理器private ChannelInitializer<Channel> createInitializer() {return new TerminalChatClientInitializer ( );}// 通过控制台不断地询问智能客服static void chat() throws IOException {while (true) {String input = getInputMsg ( );if (!input.equals (OVER)) {channel.writeAndFlush (Unpooled.copiedBuffer (input, StandardCharsets.UTF_8));} else {break;}}}
// 处理器代码
public class TerminalClientInHandler extends SimpleChannelInboundHandler<ByteBuf> {// 把响应打印出来@Overrideprotected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {out.println (LocalDateTime.now ( ).format (DateTimeFormatter.ofPattern ("yyyy/MM/dd HH:mm:ss")));String resp = msg.toString (StandardCharsets.UTF_8);out.println (resp);}// 提示连接成功@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {out.println ("connect to server successfully : " + ctx.channel ( ).remoteAddress ( ));}// 提示连接关闭@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {out.println ("已经关闭连接");}
}

服务器端

    public void start() {// 初始化服务器引导ServerBootstrap server = new ServerBootstrap ( );server.group (mainGroup).channel (NioServerSocketChannel.class).childHandler (createInitializer (channelGroup));// 监听8080端口ChannelFuture future = server.bind (8080);future.syncUninterruptibly ( );channel = future.channel ( );}private ChannelInitializer<Channel> createInitializer(ChannelGroup channelGroup) {return new TerminalChatServerInitializer (channelGroup);}public void destroy() {if (channel != null) {channel.close ( );}mainGroup.shutdownGracefully ( );subGroup.shutdownGracefully ( );}
 // 处理器关键代码  protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {      // 打印收到的时间和消息String input = msg.toString (StandardCharsets.UTF_8);out.println (ctx.channel ().remoteAddress () + "\n" + input);try {// 解析查询的Id,并且响应相应的答案int id = Integer.parseInt (input);String res = resMap.getOrDefault (id, "请致电人工:10086");ctx.writeAndFlush (Unpooled.copiedBuffer (res, StandardCharsets.UTF_8));} catch (Exception e) {// 非法输入,模拟服务器宕机,向所有的客户端发送 服务器关闭消息group.writeAndFlush (Unpooled.copiedBuffer ("不明原因,服务器暂时关闭",StandardCharsets.UTF_8));group.close ();}}// 有新连接,打印客户机地址,并且加入到聊天群组@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {out.println ("client connected successfully : " + ctx.channel ( ).remoteAddress ( ));group.add (ctx.channel ( ));}// 某客户端下线,打印客户机地址,这里不需要手动从群组移除,Netty已经帮我们实现了该功能@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {out.println ("客户端: " + ctx.channel ( ).remoteAddress ( ).toString ( ) + "  结束");}

运行状况

总结

相对于Java原生Nio的消息读取以及消息处理来说,Netty的实现方式更加简单。完整代码放于git上了。

若文章有错误,欢迎大家指正,同时希望大佬能够给予一些指导!

Netty入门——基于NIO实现机器客服案例相关推荐

  1. 智齿客服Android集成流程,一种基于编程语言接入智齿客服的方法以及电子设备与流程...

    技术特征: 1.一种基于编程语言接入智齿客服的方法,其特征在于,包括: A.获取智齿客服的编号信息,通过脚本文件导入所述编号信息,以及配置所述智齿客服的属性信息: B.通过编程语言的内框架承载所述智齿 ...

  2. 定时采用ajax方式获得数据库,《基于Ajax的在线客服系统的设计与实现》-毕业设计论文(学术).doc...

    PAGE 2 西安文理学院 数学与计算机工程学院 本科毕业设计(论文) (2012届) 设计题目 基于Ajax的在线客服系统的设计与实现 Design And Implementation Of On ...

  3. 基于webScoket的在线客服聊天

    什么是webScoket WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信--允许服务器主动发送信息给客户端. 简单的说,WebSock ...

  4. 基于javaweb的在线客服系统

    在线客服系统主要包括前台部分和后台部分,前台部分主要包括客服人员的登录以及在线用户提出问题的解答,在线用户能够通过浏览器向客服人员提出问题.后台部分主要由系统管理员对在线用户,和客服人员进行管理,注册 ...

  5. 在线咨询HTML问题,在线客服案例HTML css样式

    摘要:html> DOM实战模拟智能在线客服系统 div:nth-child(1html> DOM实战模拟智能在线客服系统 div:nth-child(1){ width: 450px; ...

  6. 干货 | 深度学习是如何帮助携程机票客服提高对话效率的

    作者简介 李元上,携程机票研发部高级数据分析师,擅长结合业务经验设计模型方案.目前负责携程值机选座算法设计.机票客服会话机器人的模型开发工作,关注新技术在项目中的应用价值. 一.背景介绍 作为一家&q ...

  7. 人人都在说SaaS热,客服领域里的SaaS巨头可能长什么样呢

    就在移动浪潮铺天盖地席卷了C端市场后,企业级软件市场也从传统PC时代装机卖软件模式过渡到SaaS模式,最近几年,中国SaaS市场以30%的年复合增长率保持着高速增长,企业级SaaS服务的风口正在积聚力 ...

  8. 你不知道的阿里人工智能:618机器人客服帮单店挣1亿

    马云家的人工智能再露锋芒-昨天下午,阿里巴巴人工实验室旗下首款智能硬件产品"天猫精灵X1"正式在北京发布,关注度瞬时爆棚. 但如果你以为阿里的人工智能只有"天猫精灵&qu ...

  9. 2017杭州云栖大会 智能客服专场预热 — 用心服务客户,用云助力客服

    Google的AlphaGo,亚马逊的Alexa,埃隆马斯克的特斯拉...智能技术一次次的刷新着人们对世界的认知.但对于企业来说,高大上的智能技术看上去还是有些缥缈虚幻.在本次云栖大会的智能客服专场中 ...

最新文章

  1. springboot静态资源访问
  2. 银河麒麟更换源及离线下载deb
  3. 神策数据受邀参加“两区”建设签约仪式
  4. zoj-What day is that day?
  5. keras从入门到放弃(四)多分类问题
  6. kali linux解密栅栏密码,最详细bugku加密小白解法---持续更新!
  7. WebApi网关之Bumblebee和Ocelot性能对比
  8. javafx 和swing_集成JavaFX和Swing
  9. c#启动mysql数据库服务器_c# - 使用C#应用程序连接Web服务器中的mysql数据库
  10. react: code-split
  11. 【DotNet 技能系列】VS工具快捷键及常用技巧
  12. python-获取当前文件名
  13. Introduction to Computer Networking学习笔记(十五):End to End Delay 端对端延迟
  14. 升级在谷歌电子市场上传的应用
  15. AAAI2020-一种生成对抗网络的蒸馏方法(Distilling portable Generative Adversarial Networks for Image Translation)
  16. 电信校园网宽带创翼破解,路由器PPPOE拦截法
  17. Android串口通信之概念介绍
  18. 在 2040 年前,实现净零碳排放
  19. 软件工程-软件工程基本概念
  20. 皇家每羊历险记(二)——地形制作

热门文章

  1. ​华硕好屏突破120Hz超高刷新率,笔电界新晋卷王——华硕无双叫人心动
  2. 对es搜索使用fork/join优化搜索
  3. 北大肖臻老师《区块链技术与应用》系列课程学习笔记[7]比特币-分叉
  4. python 凯利公式_Python量化笔记-股票收益率的正态分布检验和凯利公式应用
  5. checksum校验
  6. 得到一件东西的感觉,是不过如此,还是爱不释手‬呢?取决于……
  7. 唐山市高中计算机考试,2010唐山中考信息技术科目模拟考试题库(操作题)
  8. 基于安全芯片NRSEC3000的输电设备状态监测系统介绍
  9. CoovaChilli
  10. 干货 | 18个Python爬虫实战案例(已开源)