netty搭建web聊天室(2)群聊

上节课完成了netty的后端搭建,搞定了简单的http请求响应,今天来结合前端websocket来完成群聊功能。话不多说先上图:
图片描述

前端构建

  • 不使用复杂构建工具直接静态页面走起

使用了zui样式库 http://zui.sexy/?#/,非常不错,有好多模板。我使用的是聊天模板改造

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/zui/1.8.1/css/zui.min.css">
    <link rel="stylesheet" href="zui-theme.css">
  • 主体部分
<div class="container">
    <h1>mike多人聊天室,等你来聊</h1>
    <div class="comments">
  <section class="comments-list" id="chatlist">
    <div class="comment">
      <a href="###" class="avatar">
        <i class="icon-user icon-2x"></i>
      </a>
      <div class="content">
        <div><strong>其他人</strong></div>
        <div class="text">其他人的聊天内容</div>
      </div>
    </div>

    <div class="comment">
      <a href="###" class="avatar pull-right">
        <i class="icon-user icon-2x"></i>
      </a>
      <div class="content pull-right">
        <div><strong>我</strong></div>
        <div class="text">我说话的内容</div>
      </div>
    </div>
  </section>
  <footer>
    <div class="reply-form" id="commentReplyForm1">
      <form class="form">
          <div class="form-group">
      <div class="input-control has-label-left">
            <input id="userName" type="text" class="form-control" placeholder="">
            <label for="inputAccountExample2" class="input-control-label-left">昵称:</label>
      </div>
    </div>
    </form>

      <a href="###" class="avatar"><i class="icon-user icon-2x"></i></a>
      <form class="form">
        <div class="form-group">
          <textarea id="inputMsg" class="form-control new-comment-text" rows="2" value="" placeholder="开始聊天...  输入enter 发送消息"></textarea>
        </div>
      </form>
    </div>
  </footer>
</div>
</div>
  • 引入依赖js
    <!-- ZUI Javascript 依赖 jQuery -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/zui/1.8.1/lib/jquery/jquery.js"></script>
    <!-- ZUI 标准版压缩后的 JavaScript 文件 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/zui/1.8.1/js/zui.min.js"></script>
  • websocket的js代码以及业务代码
  <script type="text/javascript">
         window.CHAT = {
            me: "",
            WS:{},
            init: function () {
              if (window.WebSocket) {
                this.WS = new WebSocket("ws://A156B7L58CCNY4B:8090/ws");
                this.WS.onmessage = function(event) {
                 var data = event.data;
                 console.log("收到数据:" + data);
                 //显示其他人的聊天信息
                 console.log(CHAT.me);
                 console.log(data.split(":")[0]);
                 if(CHAT.me != data.split(":")[0]) {
                   appendOtherchat(data);
                 }

               },

               this.WS.onclose = function(event) {
                  console.log("连接关闭");
               },

               this.WS.onopen = function(evt) {
                     console.log("Connection open ...");
               },

              this.WS.onerror = function(event) {
                  console.log("连接失败....");
               }
              } else {
                alert("您的浏览器不支持聊天,请更换浏览器");
              }

            },
            chat:function (msg) {
              this.WS.send(msg);
            }
        }

        CHAT.init();

        function Trim(str) {
          return str.replace(/(^\s*)|(\s*$)/g, "");
        }

        function appendMy (msg) {  //拼接自己的聊天内容
          document.getElementById('chatlist').innerHTML+="<div class='comment'><a class='avatar pull-right'><i class='icon-user icon-2x'></i></a><div class='content pull-right'><div><strong>我</strong></div><div class='text'>"+msg+"</div></div></div>";

        }

        function appendOtherchat(msg) {  //拼接别人的聊天信息到聊天室
          var  msgs = msg.split(":");
          document.getElementById('chatlist').innerHTML+="<div class='comment'><a class='avatar'><i class='icon-user icon-2x'></i></a><div class='content'><div><strong>"+msgs[0]+"</strong></div><div class='text'>"+msgs[1]+"</div></div></div>";
        }


        document.getElementById('inputMsg').addEventListener('keyup', function(event) {
        if (event.keyCode == "13") {
         //回车执行查询
        var  inputMsg = document.getElementById('inputMsg').value;
        if (inputMsg == null || Trim(inputMsg) == "" ) {
             alert("请输入聊天消息");
        } else {
            var  userName = document.getElementById('userName').value;
            if (userName == null || userName == '') {
              alert("请输入聊天昵称");
            } else {
              //发送消息 定义消息格式   用户名:[消息]
              CHAT.chat(userName+":"+inputMsg);
              //记录我的昵称
              CHAT.me = userName;
              appendMy(inputMsg);
              //发送完清空输入
               document.getElementById('inputMsg').focus();
               document.getElementById('inputMsg').value="";
            }
        }
     }
 });
    </script>

都有注释就不解释了自己看

后端服务改造

  • ChatHandler改造,判断websocket响应
    /**
     * 读取客户端发送的消息,并将信息转发给其他客户端的 Channel。
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object  request) throws Exception {
           if (request instanceof FullHttpRequest) { //是http请求
               FullHttpResponse response = new DefaultFullHttpResponse(
                        HttpVersion.HTTP_1_1,HttpResponseStatus.OK , Unpooled.wrappedBuffer("Hello netty"
                                .getBytes()));
                response.headers().set("Content-Type", "text/plain");
                response.headers().set("Content-Length", response.content().readableBytes());
                response.headers().set("connection", HttpHeaderValues.KEEP_ALIVE);
                ctx.channel().writeAndFlush(response);
           } else if (request instanceof TextWebSocketFrame) { // websocket请求
               String userId = ctx.channel().id().asLongText();
               System.out.println("收到客户端"+userId+":"+((TextWebSocketFrame)request).text());
               //发送消息给所有客户端
               channels.writeAndFlush(new TextWebSocketFrame(((TextWebSocketFrame)request).text()));
               //发送给单个客户端
               //ctx.channel().writeAndFlush(new TextWebSocketFrame(((TextWebSocketFrame)request).text()));
           }
    }

* ChatServerInitializer改造,加入WebSocket

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pipeline = ch.pipeline();
          //websocket协议本身是基于http协议的,所以这边也要使用http解编码器
            pipeline.addLast(new HttpServerCodec());
            //以块的方式来写的处理器
            pipeline.addLast(new ChunkedWriteHandler());
            //netty是基于分段请求的,HttpObjectAggregator的作用是将请求分段再聚合,参数是聚合字节的最大长度
            pipeline.addLast(new HttpObjectAggregator(1024*1024*1024));

            //ws://server:port/context_path
            //ws://localhost:9999/ws
            //参数指的是contex_path
            pipeline.addLast(new WebSocketServerProtocolHandler("/ws",null,true,65535));

            //自定义handler
            pipeline.addLast(new ChatHandler());

            System.out.println("ChatClient:"+ch.remoteAddress() +"连接上");
        
    }

改造完成

启动后端服务,访问你的前端静态页面就可以和小伙伴聊天了。其实后端群聊很简单,就是把一个用户的输入消息,返回给所有在线客户端,前端去负责筛选显示。自己动手照着搞10分钟就能完成。

实现功能

  • 输入聊天昵称开始聊天
  • 聊天消息不为空才能发送
  • 发送完自动清空输入,且聚焦输入框
  • 自己的消息显示在左侧,其他人的消息在右侧

别忘了关注我 mike啥都想搞
mike啥都想搞

求关注啊。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值