前言:
  就如前文所讲述的, 聊天室往往是最基本的网络编程的学习案例. 本文以WebSocket为底层协议, 实现一个简单的基于web客户端的Echo服务.
  服务器采用Netty 4.x来实现, 源于其对websocket的超强支持, 基于卓越的性能和稳定.
  本系列的文章链接如下:
  1). websocket协议和javascript版的api

要点提示:
  Netty作为高性能网络编程框架, 其所有的网络IO操作皆为异步方式驱动. 而其核心的概念之一: ChannelHandler. 由一组ChannelHandler构成了ChannelPipeline, 决定了其编解码(Codec)/数据流(DataFlow)/业务处理(Logic Handler)的具体行为.
  ChannelHanlder的自由组合和清晰的职责划分, 让Netty更加的灵活和重要.

  
  WebSocket协议包括握手数据传输这两个阶段. 前者的握手是基于HTTP/HTTPS协议的, 而后者的数据传输则基于TCP的双向通讯模式. 数据以Frame的方式来组织和交互.
  本文不是Netty的学习文章, 这边就略为带过, 具体见后边的解释代码.

服务端:
  基于之上的要点提要, 我们迅速来进行服务端的代码编写.
  使用netty 4.x版本, 其maven的依赖配置如下:

  1. <dependency>
  2. <groupId>io.netty</groupId>
  3. <artifactId>netty-all</artifactId>
  4. <version>4.0.29.Final</version>
  5. </dependency>

  服务端的代码如下:

  1. EventLoopGroup bossGroup = new NioEventLoopGroup();
  2. EventLoopGroup workerGroup = new NioEventLoopGroup();
  3.  
  4. try {
  5.   ServerBootstrap serverBootstrap = new ServerBootstrap();
  6.  
  7.   serverBootstrap.group(bossGroup, workerGroup)
  8.     .channel(NioServerSocketChannel.class)
  9.     .childHandler(new ChannelInitializer<SocketChannel>() {
  10.       @Override
  11.       protected void initChannel(SocketChannel socketChannel) throws Exception {
  12.         // pipeline的设置, 参看下面
  13.       }
  14.     });
  15.  
  16.   ChannelFuture f = serverBootstrap.bind(8123).sync();
  17.   f.channel().closeFuture().sync();
  18. } finally {
  19.   bossGroup.shutdownGracefully();
  20.   workerGroup.shutdownGracefully();
  21. }

  注: 这边是主体的服务器配置和启动代码, 其一如既然的简洁.
  核心的pipeline设置代码如下所示:

  1. ChannelPipeline cp = socketChannel.pipeline();
  2. // *) 支持http协议的解析
  3. cp.addLast(new HttpServerCodec());
  4. cp.addLast(new HttpObjectAggregator(65535));
  5. // *) 对于大文件支持 chunked方式写
  6. cp.addLast(new ChunkedWriteHandler());
  7. // *) 对websocket协议的处理--握手处理, ping/pong心跳, 关闭
  8. cp.addLast(new WebSocketServerProtocolHandler("/echoserver"));
  9. // *) 对TextWebSocketFrame的处理
  10. cp.addLast(new SimpleChannelInboundHandler<TextWebSocketFrame>() {
  11.   @Override
  12.   protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
  13.     // *) echo 逻辑
  14.     ctx.writeAndFlush(new TextWebSocketFrame(msg.text()));
  15.   }
  16. });

  注: HttpServerCodec和HttpObjectAggregator已经帮我们封装好了WebSocket的握手FullHttpRequest/FullHttpResponse包和各类数据Frame包. WebSocketServerProtocolHandler隐藏了握手的细节处理, 以及心跳处理和关闭响应. 多个ChannelHanlder的叠加和WebSocket协议本身的复杂是密切先关的.

客户端:
  这边只是个演示项目, 因此尽量简洁地去实现.

  1. <div style="margin:0 auto; width: 800px;">
  2.   <textarea id="taMessages" style="width: 360px; height: 200px;" readonly ></textarea>
  3.   <br />
  4.   <input id="btnMessage" type="text" style="float:left; width:300px;" />
  5.   <input id="btnSend" type="button" value="Send" disabled="disabled" onclick="sendMessage();"/>
  6. </div>
  7.  
  8. <script>
  9.   /* 注意浏览器js的执行顺序 */
  10.   var wsServer = 'ws://localhost:8123/echoserver'; //服务器地址
  11.   var websocket = new WebSocket(wsServer); //创建WebSocket对象
  12.  
  13.   websocket.onopen = function(evt) {
  14.     document.getElementById("btnSend").disabled = false;
  15.   }
  16.   websocket.onmessage = function(evt) {
  17.     document.getElementById("taMessages").value += evt.data;
  18.   }
  19.   websocket.onclose = function(evt) {
  20.   }
  21.   websocket.onerror = function(evt) {
  22.   }
  23.  
  24.   function sendMessage() {
  25.     var message = document.getElementById('btnMessage').value;
  26.     if ( websocket.readyState == WebSocket.OPEN ) {
  27.       websocket.send(message);
  28.     }
  29.     document.getElementById('btnMessage').value = '';
  30.   }
  31. </script>

  注: 发送数据到服务端, 然后把服务端返回的数据追加到文本区域中.

效果:
  在chrome浏览器中, 效果如下:
  
  点击send按钮后, 经服务器返回其消息.
  
  消息在大文本区域中展示. 看来Echo服务一切正常.
  其实这是个悲伤的故事, 你觉得呢?

写在最后:
  
如果你觉得这篇文章对你有帮助, 请小小打赏下. 其实我想试试, 看看写博客能否给自己带来一点小小的收益. 无论多少, 都是对楼主一种由衷的肯定.

  

在线聊天室的实现(2)--基于Netty 4.x的Echo服务器实现的更多相关文章

  1. 基于Server-Sent Event的简单在线聊天室

    Web即时通信 所谓Web即时通信,就是说我们可以通过一种机制在网页上立即通知用户一件事情的发生,是不需要用户刷新网页的.Web即时通信的用途有很多,比如实时聊天,即时推送等.如当我们在登陆浏览知乎时 ...

  2. Node.js下基于Express + Socket.io 搭建一个基本的在线聊天室

    一.聊天室简单介绍 采用nodeJS设计,基于express框架,使用WebSocket编程之 socket.io机制.聊天室增加了 注册登录模块 ,并将用户个人信息和聊天记录存入数据库. 数据库采用 ...

  3. 基于JQuery+JSP的无数据库无刷新多人在线聊天室

    JQuery是一款非常强大的javascript插件,本文就针对Ajax前台和JSP后台来实现一个无刷新的多人在线聊天室,该实现的数据全部存储在服务端内存里,没有用到数据库,本文会提供所有源程序,需要 ...

  4. 基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。

    基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍.最后我们将会实现一个基于S ...

  5. 基于Java的在线聊天室

    概述 Java socket编程,实现一个在线聊天室, 实现在线用户群聊,私聊,发送文件等功能. 详细 代码下载:http://www.demodashi.com/demo/13623.html 一. ...

  6. 在线聊天室的实现(1)--websocket协议和javascript版的api

    前言: 大家刚学socket编程的时候, 往往以聊天室作为学习DEMO, 实现简单且上手容易. 该Demo被不同语言实现和演绎, 网上相关资料亦不胜枚举. 以至于很多技术书籍在讲解网络相关的编程时, ...

  7. 百度前端面试题-类似slack的在线聊天室

    别人国庆出去玩,我在家写代码的感觉也是很不错哒. 首先介绍一下技术架构吧! 使用了js框架:FFF,zepto,jquery,md5.min.js 前端框架:Bootstrap 后端:野狗,部分PHP ...

  8. Asp.NET MVC 使用 SignalR 实现推送功能二(Hubs 在线聊天室 获取保存用户信息)

    简单介绍 关于SignalR的简单实用 请参考 Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室) 在上一篇中,我们只是介绍了简单的消息推送,今天我们来修改一下,实现 ...

  9. 三、jQuery--jQuery基础--jQuery基础课程--第12章 jQuery在线聊天室

    在线聊天室案例 一.功能简介: 1.用户需要登录后才能进入聊天室交流 2.已无刷新的方式,动态展示交流后的内容和在线人员的基本信息 3.登录后的用户可以提交文字和表情图标 技术重点:利用ajax的无刷 ...

随机推荐

  1. Python 基础练习

    今天接触了python,了解了一下 python 的基础语法,于是想着手训练一下,在本习题集中,参考代码为提供的参考答案,前面的代码为自己思考的代码,最后每道题给出练习的时间. Python 基础练习 ...

  2. 讲解Python中的递归函数

    本文的最重要的收获在于:尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式. 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. 举个例 ...

  3. Ubuntu安装Vim编辑器

    1 安装Vim编辑器 由于Ubuntu预安装的是tiny版本,就会导致我们在使用上的产生不便. 所以我们要安装vim的full版本. 1.1 卸载旧版vi sudo apt-get remove vi ...

  4. python 高级特性

    from http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 set set和dict ...

  5. Logistic 分类器与 softmax分类器

    首先说明啊:logistic分类器是以Bernoulli(伯努利) 分布为模型建模的,它可以用来分两种类别:而softmax分类器以多项式分布(Multinomial Distribution)为模型 ...

  6. Spring中@Async注解实现“方法”的异步调用

    原文:http://www.cnblogs.com/zhengbin/p/6104502.html 简单介绍: Spring为任务调度与异步方法执行提供了注解支持.通过在方法上设置@Async注解,可 ...

  7. js 排序Json数组

    由于对用java处理数据需要各种数据类型的转换,非常郁闷,个人更偏向于用js做数据处理,直接上code,希望对你有帮助: function sortJsonArr(jsonArr, sortName, ...

  8. 用 python 实现各种排序算法(转)

    常见几种排序的算法: 归并排序 归并排序也称合并排序,是分治法的典型应用.分治思想是将每个问题分解成个个小问题,将每个小问题解决,然后合并. 具体的归并排序就是,将一组无序数按n/2递归分解成只有一个 ...

  9. 学习JQ

    目前我对jq的了解还很少,只知道jq比js简单很多,只需引入一个js文件,然后,在js中很多行才能实现的代码,jq中或许一行就搞掂了,比如根据类名获取元素,$(".类名")即可,对 ...

  10. 基础向量运算-2D镜面反射

    如图M为镜面,A为入射光,B为反射光,已知A与M的向量坐标,求B的向量表示. 我们添加辅助向量C. 有以下性质. B = 2 * C - A. [1] |C| = |A| * cos(alpah).A ...