netty set up web chat room group chat

In the last lesson, I completed the back-end construction of netty and completed the simple http request response. Today, I will complete the group chat function with the front-end websocket. If you don't want to talk much, let's start with the picture above:

Front-end construction

  • Do not use complex build tools to start static pages directly

zui style library used http://zui.sexy/?#/ , very good, there are many templates. I used the chat Template Transformation

    <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">
  • Main part
<div class="container">
    <h1>mike Multi person chat room, waiting for you to chat</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>Someone else</strong></div>
        <div class="text">Other people's chat content</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>I</strong></div>
        <div class="text">What I'm talking about</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">Nickname?:</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="Start chatting...  input enter send message"></textarea>
        </div>
      </form>
    </div>
  </footer>
</div>
</div>
  • Introduce dependency js
    <!-- ZUI Javascript rely on jQuery -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/zui/1.8.1/lib/jquery/jquery.js"></script>
    <!-- ZUI Standard Version compressed JavaScript file -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/zui/1.8.1/js/zui.min.js"></script>
  • js code and business code of websocket
  <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 received:" + data);
                 //Show other people's chat messages
                 console.log(CHAT.me);
                 console.log(data.split(":")[0]);
                 if(CHAT.me != data.split(":")[0]) {
                   appendOtherchat(data);
                 }

               },

               this.WS.onclose = function(event) {
                  console.log("Connection closure");
               },

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

              this.WS.onerror = function(event) {
                  console.log("connection failed....");
               }
              } else {
                alert("Chat is not supported in your browser. Please change your browser");
              }

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

        CHAT.init();

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

        function appendMy (msg) {  //Splicing your own chat content
          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>I</strong></div><div class='text'>"+msg+"</div></div></div>";

        }

        function appendOtherchat(msg) {  //Splicing other people's chat information to chat room
          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") {
         //Enter to query
        var  inputMsg = document.getElementById('inputMsg').value;
        if (inputMsg == null || Trim(inputMsg) == "" ) {
             alert("Please enter a chat message");
        } else {
            var  userName = document.getElementById('userName').value;
            if (userName == null || userName == '') {
              alert("Please enter a chat nickname");
            } else {
              //Send message definition message format user name: [message]
              CHAT.chat(userName+":"+inputMsg);
              //Record my nickname
              CHAT.me = userName;
              appendMy(inputMsg);
              //Clear input after sending
               document.getElementById('inputMsg').focus();
               document.getElementById('inputMsg').value="";
            }
        }
     }
 });
    </script>

If you have comments, you can't explain them

Back end service transformation

  • ChatHandler transformation, judge websocket response
    /**
     * Read the message sent by the client and forward it to the Channel of other clients.
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object  request) throws Exception {
           if (request instanceof FullHttpRequest) { //It's an http request
               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 request
               String userId = ctx.channel().id().asLongText();
               System.out.println("Client received"+userId+":"+((TextWebSocketFrame)request).text());
               //Send message to all clients
               channels.writeAndFlush(new TextWebSocketFrame(((TextWebSocketFrame)request).text()));
               //Send to a single client
               //ctx.channel().writeAndFlush(new TextWebSocketFrame(((TextWebSocketFrame)request).text()));
           }
    }

*ChatServerInitializer transformation, adding WebSocket

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pipeline = ch.pipeline();
          //websocket protocol itself is based on http protocol, so we also need to use http to decode the encoder
            pipeline.addLast(new HttpServerCodec());
            //A processor written in blocks
            pipeline.addLast(new ChunkedWriteHandler());
            //netty is based on segmented request. HttpObjectAggregator is used to segment and re aggregate the request. The parameter is the maximum length of aggregate bytes
            pipeline.addLast(new HttpObjectAggregator(1024*1024*1024));

            //ws://server:port/context_path
            //ws://localhost:9999/ws
            //Parameter refers to content [u path
            pipeline.addLast(new WebSocketServerProtocolHandler("/ws",null,true,65535));

            //Custom handler
            pipeline.addLast(new ChatHandler());

            System.out.println("ChatClient:"+ch.remoteAddress() +"Connection");
        
    }

Transformation completed

Start the back-end service, visit your front-end static page and chat with your friends. In fact, the back-end group chat is very simple, that is, the input message of a user is returned to all online clients, and the front-end is responsible for filtering and displaying. Do it yourself and do it for 10 minutes.

Realization function

  • Enter a chat nickname to start a chat
  • Chat message can only be sent if it is not empty
  • Automatically clear the input after sending, and focus the input box
  • Own messages are displayed on the left, others on the right

Don't forget to pay attention to me mike wants to do everything

Please pay attention.

Keywords: Java Netty Javascript JQuery

Added by gojakie on Wed, 04 Dec 2019 11:03:04 +0200