美文网首页javaWeb
websocket聊天+Java后台完整代码

websocket聊天+Java后台完整代码

作者: 咩咩籽 | 来源:发表于2019-07-09 09:28 被阅读0次

效果图----请各位看官轻些喷

image image

前端+css+js

<%@page contentType="text/html;charset=UTF-8"language="java" %>

<html !DOCTYPE html>

<head>

    <meta charset="utf-8">

    <title>websocket</title>

    <meta name="renderer" content="webkit">

    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    //以下内容换成自己的路径

    <link rel="stylesheet" href="${pageContext.request.contextPath }/static/layui/css/layui.css"/>

    <script type="text/javascript" src="${pageContext.request.contextPath }/static/js/jquery-3.4.0.min.js"></script>

    <script type="text/javascript" src="${pageContext.request.contextPath }/static/layui/layui.js"></script>

    <style>

        .fatherDiv {

            height:80%;

            width:70%;

            position:relative;

            top:20px;

            left:100px;

            border:1px black solid;

        }

        .otherSay {

            text-align:left;

        }

        .mine {

            text-align:right;

        }

        .users {

            height:40px;

            line-height:40px;

            background-color:#EAEAEA;

        }

        .users::before {

            content:" ";

            background-image:url('<%=request.getContextPath()%>/static/images/face.jpg');

            background-size:30px 30px;

            display:inline-block;

            height:30px;

            width:30px;

            vertical-align:middle;

            margin:0 10px;

        }

        .otherSay::before {

            content:" ";

            background-image:url('<%=request.getContextPath()%>/static/images/face.jpg');

            background-size:30px 30px;

            display:inline-block;

            height:30px;

            width:30px;

            vertical-align:middle;

            margin:0 10px;

        }

        .mine::after {

            content:" ";

            background-image:url('<%=request.getContextPath()%>/static/images/girl.jpeg');

            background-size:30px 30px;

            display:inline-block;

            height:30px;

            width:30px;

            vertical-align:middle;

            margin:0 10px;

        }

        .addTimer {

            text-align:center;

        }

        .peopleSay {

            padding-top:10px;

        }

        .active {

            background-color:#C1C1C1;

        }

        .info_text {

            position:relative;

            top:-38px;

            left:35px;

        }

    </style>

</head>

<body>

<div class="fatherDiv">

    <%--移动:4/12 | 平板:5/12 | 桌面:4/12--%>

<%--显示在线人数--%>

    <div class="layui-col-xs4 layui-col-sm5 layui-col-md4">

        <p class="grid-demo layui-bg-green" style="text-align:center">会话</p>

        <div id="onLineUser"></div>

    </div>

    <%--移动:4/12 | 平板:7/12 | 桌面:8/12--%>

<%--显示聊天记录--%>

    <div class="layui-col-xs4 layui-col-sm7 layui-col-md8">

        <p class="grid-demo layui-bg-gray" style="text-align:center">${username},你好</p>

        <div id="message" style="height:475px;background-color:#EDEDED;overflow-y:auto"></div>

        <div id="msgSay" style="margin-top:10px;text-align:right;border:1px dimgrey solid;border-radius:5px">

            <textarea type="text" id="whatISaid" style="display:block;width:100%;height:10%;border:none"></textarea>

            <button onclick="send()" class="layui-btn layui-btn-normal"

                    style="height:30px;margin-right:10px;margin-bottom:5px;">发送

</button>

        </div>

    </div>

</div>

</body>

<script type="text/javascript">

    var username = '${username}';

    $(document).ready(function () {

        var time = localStorage.getItem("createTimeOfWebSocket");

        if (time == "" || time == null || time == undefined) {

            localStorage.setItem("createTimeOfWebSocket", new Date().getTime());

        } else if (new Date().getTime() - time > 604800000) {//7天清空一次

            localStorage.clear();

        }

    });

    var webSocket;

    var toWho = "ALL";

    if ("WebSocket" in window) {

//        打到正式服务器上为wss:,本地时为:ws://

        webSocket = new WebSocket("ws://" + 主机地址+ "/websocket/${username}");

        //连通之后的回调事件

        webSocket.onopen= function () {

            console.log("已经连通了websocket");

        };

        //接收后台服务端的消息

        webSocket.onmessage= function (evt) {

            var received_msg = evt.data;

            console.log("数据已接收:" + received_msg);

            var obj = JSON.parse(received_msg);

            console.log("可以解析成json:" + obj.messageType);

            //1代表上线 2代表下线 3代表在线名单 4代表普通消息

            if (obj.messageType== 1) {

                //把名称放入到list中

                var onlineName = obj.username;

                var text = "<p class='users' id=" + onlineName + " onclick='sendMe(this)'>" + onlineName + "<span class='layui-badge-dot info_text' style='display: none;'></span></p>";

                $("#onLineUser").append(text);

            }

            else if (obj.messageType== 2) {

                //下线就移除它

                var offlineName = obj.username;

                $("#" + offlineName).remove();

                //需要把之前的聊天记录保存在本地,然后打开新的聊天

                var msg = $("#message")[0].innerHTML;

                //这是把现在聊的人的聊天记录存进历史记录中

                localStorage.setItem(offlineName + username, msg);

                //如果只剩自己了就等到别人上线

                if(obj.onlineUsers.length==1&&obj.onlineUsers[0]=='${username}'){

                    return false;

                }else{

                    //给第一个用户抹黑

                    $("#onLineUser").find("p").eq(0).addClass('active');

                    toWho = $("#onLineUser").find("p")[0].innerText;

                    //把记录加在messageDIV中

                    var div = document.getElementById('message');

                    div.innerHTML= localStorage.getItem(toWho + username);

                    div.scrollTop= div.scrollHeight;

                }

}

            else if (obj.messageType== 3) {

                var onlineName = obj.onlineUsers;

                //如果只剩自己了就等到别人上线

                if(onlineName.length==1&&onlineName[0]==${username}){

                    return false;

                }else{

                    for (var i = 0; i < onlineName.length; i++) {

                        if (onlineName[i] != '${username}') {

                            $("#onLineUser").append("<p class='users' id=" + onlineName[i] + " onclick='sendMe(this)'>" + onlineName[i] + "<span class='layui-badge-dot info_text' style='display: none;'></span></p>");

                        }

}

                    //给第一个用户抹黑

                    $("#onLineUser").find("p").eq(0).addClass('active');

                    toWho = $("#onLineUser").find("p")[0].innerText;

                }

            } else {

                console.log('有消息')

                if (toWho != obj.fromusername) {

                    //设置样式

                    $('#' + obj.fromusername).find('span').eq(0).css({

                        'display': 'flex',

                        'top': '-38px',

                        'left': '38px'

                    });

                    var remsg=localStorage.getItem(obj.fromusername+ username);

                    //如果不是当前选中用户发来的消息,直接写到历史记录中,不展示出来

                    var msg = remsg==null?'': remsg +

                        '<div class="peopleSay"><p class="otherSay">' +

                            obj.textMessage+ '</p></div>';

                    localStorage.setItem(obj.fromusername+ username, msg);

                } else {

                    setMessageInnerHTMLOtherSay(obj.textMessage);

                }

}

        };

        //连接关闭的回调事件

        webSocket.onclose= function () {

            setMessageInnerHTMLOtherSay("连接已经关闭....");

        };

    } else {

        // 浏览器不支持 WebSocket

        alert("您的浏览器不支持 WebSocket!");

    }

    //将别人说的消息显示在网页上

    function setMessageInnerHTMLOtherSay(innerHTML) {

        $("#message").append('<div class="peopleSay"><p class="otherSay">' + innerHTML+ '</p></div>')

        var div = document.getElementById('message');

        div.scrollTop= div.scrollHeight;

    }

    //将自己说的消息显示在网页上

    function setMessageInnerHTMLMine(innerHTML) {

        $("#message").append('<div class="peopleSay"><p class="mine">' + innerHTML+ '</p></div>')

        var div = document.getElementById('message');

        div.scrollTop= div.scrollHeight;

    }

    function closeWebSocket() {

        //直接关闭websocket的连接

        webSocket.close();

    }

    function send() {

        var message = {

            "message": $("#whatISaid").val().trim(),

            "username": '${username}',

            "to": toWho

        };

        setMessageInnerHTMLMine($("#whatISaid").val());

        webSocket.send(JSON.stringify(message));

        //追加时间

        var time = timestampToTime();

        $("#message").append('<div class="addTimer">' + time + '</div>');

        $("#whatISaid").val('');

    }

    $('#whatISaid').on('keyup',function(event){

        if(event.keyCode== 13) {

            send();

        }

    });

    //点击某一个人的头像后,对他进行通话,获取聊天记录,如果是第一个就不用获取聊天记录了

    function sendMe(data) {

        console.log(1)

        //需要把之前的聊天记录保存在本地,然后打开新的聊天

        var msg = $("#message")[0].innerHTML;

        var key=toWho + username;

        //这是把现在聊的人存进历史记录中

        localStorage.setItem(key, msg);

        //清空所有的人的active类

        $("#onLineUser p").removeClass('active');

        //对点击的添加新类

//把对象改为刚刚点击的人

        toWho = data.textContent;

        $(data)[0].classList.add('active');

        $("#message").empty();

        var key1=toWho + username;

        //把记录加在messageDIV中

        var div = document.getElementById('message');

        div.innerHTML= localStorage.getItem(key1);

        console.log(key1,localStorage.getItem(key1));

        div.scrollTop= div.scrollHeight;

        //设置样式

        $('#' + toWho).find('span').eq(0).css('display', 'none');

    }

    function timestampToTime() {

        var date = new Date();//时间戳为10位需*1000,时间戳为13位的话不需乘1000

        var Y = date.getFullYear() + '-';

        var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';

        var D = date.getDate() < 10 ? '0' + date.getDate() + ' ' : date.getDate() + ' ';

        var h = date.getHours() < 10 ? '0' + date.getHours() + ':' : date.getHours() + ':';

        var m = date.getMinutes() < 10 ? '0' + date.getMinutes() + ':' : date.getMinutes() + ':';

        var s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();

        return Y + M + D + h + m + s;

    }

</script>

</html>

后台

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONObject;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

import javax.websocket.*;

import javax.websocket.server.PathParam;

import javax.websocket.server.ServerEndpoint;

import java.io.IOException;

import java.io.UnsupportedEncodingException;

import java.util.HashMap;

import java.util.Map;

import java.util.Set;

import java.util.concurrent.ConcurrentHashMap;

/**

* @author hjy18

*/

@Component

@ServerEndpoint("/websocket/{username}")

public class WebSocket {

    /**

* 定义一个全局的记录器,通过LoggerFactory获取

*/

    private final static Logger logger = LoggerFactory.getLogger(WebSocket.class);

    /**

* 在线人数

*/

    protected static int onlineNumber=0;

    /**

* 以用户的姓名为key,websocke为对象保存起来

*/

    private static Map<String,WebSocket> clients=new ConcurrentHashMap<>(16);

    /**

* 会话

*/

    private Session session;

    /**

* 用户昵称

*/

    private String username;

    /**

* 建立连接

*

    * @param session

    */

    @OnOpen

    public void onOpen(@PathParam("username") String username, Session session){

        String name="";

        try {

            name = new String(username.getBytes("ISO-8859-1"),"utf-8");

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();

        }

        synchronized (this){

            onlineNumber++;

        }

        System.out.println("现在来连接的客户id:"+session.getId()+"用户名:"+name);

        this.username= name;

        this.session= session;

        System.out.println("有新连接加入! 当前在线人数" + onlineNumber);

        try {

            //messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息

//先给所有人发送通知,说我上线了

            Map<String,Object> map1 = new HashMap<>(16);

            map1.put("messageType",1);

            map1.put("username",name);

            sendMessageAll(JSON.toJSONString(map1),name);

            //把自己的信息加入到map当中去

            clients.put(name, this);

            //给自己发一条消息:告诉自己现在都有谁在线

            Map<String,Object> map2 = new HashMap<>(16);

            map2.put("messageType",3);

            //移除掉自己

            Set<String> set = clients.keySet();

            map2.put("onlineUsers",set);

            sendMessageTo(JSON.toJSONString(map2),name);

        }

        catch (IOException e){

            logger.error(name+"上线的时候通知所有人发生了错误");

        }

}

    @OnError

    public void onError(Session session, Throwable error) {

        logger.error("服务端发生了错误"+error.getMessage());

        //error.printStackTrace();

    }

    /**

* 连接关闭

*/

    @OnClose

    public void onClose(){

        synchronized (this){

            onlineNumber--;

        }

        clients.remove(username);

        try {

            //messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息

            Map<String,Object> map1 = new HashMap<>(16);

            map1.put("messageType",2);

            map1.put("onlineUsers",clients.keySet());

            map1.put("username",username);

            sendMessageAll(JSON.toJSONString(map1),username);

        }

        catch (IOException e){

            System.out.println(username+"下线的时候通知所有人发生了错误");

        }

        System.out.println("有连接关闭! 当前在线人数" + onlineNumber);

    }

    /**

* 收到客户端的消息

*

    * @param message 消息

    * @param session 会话

*/

    @OnMessage

    public void onMessage(String message, Session session)

{

        try {

            System.out.println("来自客户端消息:" + message+"客户端的id是:"+session.getId());

            JSONObject jsonObject = JSON.parseObject(message);

            String textMessage = jsonObject.getString("message");

            String fromusername = jsonObject.getString("username");

            String tousername = jsonObject.getString("to");

            //如果不是发给所有,那么就发给某一个人

//messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息

            Map<String,Object> map1 = new HashMap<>(16);

            map1.put("messageType",4);

            map1.put("textMessage",textMessage);

            map1.put("fromusername",fromusername);

            if(tousername.equals("All")){

                map1.put("tousername","所有人");

                sendMessageAll(JSON.toJSONString(map1),fromusername);

            }

            else{

                map1.put("tousername",tousername);

                sendMessageTo(JSON.toJSONString(map1),tousername);

            }

}

        catch (Exception e){

            System.out.println("发生了错误了");

            e.printStackTrace();

        }

}

    public void sendMessageTo(String message, String ToUserName) throws IOException {

        for (WebSocket item : clients.values()) {

            if (item.username.equals(ToUserName) ) {

                item.session.getAsyncRemote().sendText(message);

                break;

            }

}

}

    public void sendMessageAll(String message, String FromUserName) throws IOException {

        for (WebSocket item : clients.values()) {

            item.session.getAsyncRemote().sendText(message);

        }

}

    public static synchronized int getOnlineCount() {

        return onlineNumber;

    }

}

相关文章

网友评论

    本文标题:websocket聊天+Java后台完整代码

    本文链接:https://www.haomeiwen.com/subject/kvstkctx.html