websocket-chat:一个网页聊天小程序

页面:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes" />
<title>不忘初心</title>
<link rel="shortcut icon" href="skin/img/favicon48.ico">
<script src="skin/js/jquery-3.2.1.min.js"></script>
<link rel="stylesheet" href="skin/css/chat.css" type="text/css" />
<link href="skin/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
<!--[if lt IE 9]>
      <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
<script src="skin/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    
<script type="text/javascript">
    $(function() {
        var url = "ws://113.128.104.115:1314/chat/ChatServer";
        var ws = null;
        var nickname = "";
        
        $('#myModal').modal('show');
        $('#myModal').on('shown.bs.modal', function () {
            $("#nickname").val("小新");
            $("#nickname").focus();
            $("#nickname_btn").click();
        })
        $("form#nickname_form").submit(function(){ //发送昵称,连接聊天室
            nickname = $("#nickname").val().trim();
            if (nickname === "") {
                alert("请输入昵称!");
            } else {
                ws_connect();
                $('#myModal').modal('hide');
            }
            return false;
        });
        $("#nickname_btn").click(function(){ //输入昵称点击进入触发,进入聊天
            $("form#nickname_form").submit();
        });
            
        function ws_connect() { //连接ws,建立通讯
            nickname = window.btoa(unescape(encodeURIComponent(nickname)));
            if (ws == null) {
                ws = new WebSocket(url + "?" + nickname);
                ws.onopen = function() {
                    console.log("连接成功——ws.onopen");
                };
                ws.onmessage = function(evt) {
                    var data = evt.data;
                    if(data.trim() === ""){
                        return;
                    }
                    var msg ="";
                    if(data.indexOf("{") == 0){
                        var obj = JSON.parse(data);
                        if(obj["me"] == 1){
                            nickname = obj["nickname"];
                            msg = '<div class="mine_user hidden"><div class="triangle"></div><div class="say">' + obj["msg"] + '</div></div>'

                        }else{
                            msg = '<div class="other_user hidden"><div class="triangle"></div><div class="say">' + obj["msg"] + '</div></div>'

                        }
                        obj["time"]
                    }else{
                        msg = data;
                    }
                    $("#content").append(msg);
                    toBottom();
                };
                ws.onclose = function(evt) {
                    console.log("连接关闭——ws.onclose");
                };
                ws.onerror = function(evt) {
                    console.log("连接出错——ws.onerror");
                };
            }
        }
        
        function setContentHeight(){  //调整显示区域正好填满整个页面
            var h = $(window).height();
            var body_pading_top = parseInt($("body.container").css("padding-top").replace("px", ""));
            var body_pading_bottom = parseInt($("body.container").css("padding-bottom").replace("px", ""));
            var body_margin_top = parseInt($("body.container").css("margin-top").replace("px", ""));
            var body_margin_bottom = parseInt($("body.container").css("margin-top").replace("px", ""));
            var content_margin_h = $("div#content").outerHeight(true) - $("div#content").outerHeight();
            var inputGroup_h = $("div.input-group").height();
            var content_h = h - content_margin_h - inputGroup_h - body_pading_top - body_pading_bottom - body_margin_top - body_margin_bottom;
            $("div#content").css({"height":content_h + "px"});
        }
        
        setContentHeight();
        $(window).resize(function() { //窗口大小变化触发
            setContentHeight();
        });
        
        function toBottom(){ //将聊天内容区域滚动条滚到最下面
            $("div.hidden").each(function(){  //将太宽的显示缩窄
                $(this).removeClass("hidden");
                var i = $(this).find(".say:last").width();
                if(i+5 > $(this).width()*0.85){
                    $(this).find(".say").css("width", "85%");
                }
            });
            var sh = $("div#content").prop("scrollHeight");
            $("div#content").animate({"scrollTop": sh}, 200);
        }
        
        
//      $("input#sendcontent").focus(function(){
//          setTimeout(function() {
//              $(window).scrollTop(10000);
//          }, 200);
//      }); 
        
//      $("input#sendcontent").blur(function(){
//          var h = $(window).height();
//          h = $(window)[0].scrollHeight;
//          $("div#content").append("<br> blur: " + h);
//      }); 
        
        $("span#sendspan").click(function(){ //点击发送按钮发送消息
            $("form#chat").submit();
        });
        
        $("form#chat").submit(function(){ //聊天内容发送,在输入框按下回车或者点击发送按钮触发
            if (ws == null) {
                alert("连接断开,重新刷新页面");
            } else {
                var msg = $("#sendcontent").val();
                if(msg.trim() === ""){
                    return false;
                }
                ws.send(msg);
                $("#sendcontent").val("");
                
            }
            return false;
        });
        
        function HTMLencode(content){ //将'<'、'>'等特殊符号转为html字符实体
            var temp = document.createElement("div");
            $(temp).css("display", "none");
            $(temp).text(content);
            var res = temp.innerHTML
            $(temp).remove();
            return res;
        }
        
        
        $("textarea#sendcontent").keydown(function(event){ //textarea框回车提交,阻止换行
            if(event.keyCode == 13 && event.ctrlKey){
                $("textarea#sendcontent")[0].value += "\n";
            }else if(event.keyCode == 13){
                event.preventDefault();
                $("form#chat").submit();
            }
        });
        
    })
</script>
</head>

<body class="container" style="margin-top: 20px; margin-bottom: 20px;">
    <form id="chat" class="form-horizontal">
        <div id="content" class="well" style="height: 500px;">
            <div class="other_user">
<!--                <div class="name_time"> -->
<!--                    小新(11-30 20:54) -->
<!--                </div> -->
                <div class="triangle"></div>
                <div class="say">
                    你好吗?
                </div>
            </div>
        </div>
        <div class="input-group">
            <textarea id="sendcontent" class="form-control" rows="1"></textarea>
<!--            <input type="text" id="sendcontent" class="form-control"/>  -->
            <span id="sendspan" class="input-group-addon">&crarr;</span>
        </div>
    </form>
    
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
      <div class="modal-dialog modal-sm" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h4 class="modal-title" id="myModalLabel">输入昵称加入聊天</h4>
          </div>
          <div class="modal-body">
            <form id="nickname_form" class="form-horizontal">
                <div class="input-group">
                    <input type="text" id="nickname" class="form-control" placeholder="昵称"/> 
                    <span id="nickname_btn" class="input-group-addon">进入</span>
                </div>
            </form>
          </div>
        </div>
      </div>
    </div>

</body>
</html>

后台:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.org.apache.xml.internal.security.utils.Base64;

@ServerEndpoint("/ChatServer")
public class ChatServer {
    private static Map<Session, String> users = new HashMap<Session, String>();
    private static BufferedWriter record_w = null;
    @OnOpen
    public void onOpen(Session session) throws Exception {
        String nickname = session.getQueryString();
        nickname = new String(Base64.decode(nickname), "utf8");
        synchronized (users) {
            while(users.containsValue(nickname)){
                String tail = Utils.randomString(4, 10);
                nickname += tail;
            }
            users.put(session, nickname);
        }
        String msg = "<div class='text-center text-primary sysinfo'>系统提示: " + Utils.getTime("", "") + " " + nickname + " 加入聊天</div>";
        for(Session user : users.keySet()){
            user.getBasicRemote().sendText(msg);
        }
        System.out.println("open.. " + users);
    }
    
    @OnMessage
    public String onMessage(Session session, String message) throws IOException {
        String nickname = users.get(session);
        Map<String, String> res = new HashMap<String, String>();
        res.put("nickname", nickname);
        res.put("time", Utils.getTime("", ""));
//      res.put("msg", message);
        res.put("msg", message.replace("\n", "<br>").replace(" ", "&nbsp;"));
        ObjectMapper objMapper = new ObjectMapper();
        String rtn = objMapper.writeValueAsString(res);
//      String record = nickname + ": " + Utils.getTime("", "") + " " + message;
        synchronized (users) {
            //write record file
            if(record_w == null){
                record_w = new BufferedWriter(new FileWriter("e:/mnt/record", true));
            }
            record_w.write(rtn + "\n");
            record_w.flush();
            
            for(Session user : users.keySet()){
                if(!user.equals(session)){
                    user.getBasicRemote().sendText(rtn);
                }
            }
        }
//      {"time":"(11-30 23:1:42)","nickname":"小新4651","msg":"聊天内容。。。"}
        rtn = rtn.substring(0, rtn.length()-1) + ",\"me\":\"1\"}";
        return rtn;
    }
    
    @OnClose
    public void onClose(Session session, CloseReason reason) throws IOException {
        String nickname = users.get(session);
        users.remove(session);
        String msg = "<div class='text-center text-muted sysinfo'>系统提示: " + Utils.getTime("", "") + " " + nickname + " 离开聊天</div>";
        for(Session user : users.keySet()){
            user.getBasicRemote().sendText(msg);
        }
        System.out.println("close.. " + users);
    }
}

猜你喜欢

转载自blog.csdn.net/xuejianbest/article/details/84821801