欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot-实现WebSocket群聊私聊

程序员文章站 2022-10-03 20:22:10
参考博客:https://blog.csdn.net/qq_42240818/article/details/91414670还有一篇参考的,但是我不知道跑哪去了。就没贴了,如果后续找到了,就会贴的。1.添加依赖 org.springframework.boot spring-boot-starter-websocke...

参考博客:https://blog.csdn.net/qq_42240818/article/details/91414670
还有一篇参考的,但是我不知道跑哪去了。就没贴了,如果后续找到了,就会贴的。

1.添加依赖

	 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

2.编写配置文件

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;


@Configuration
public class WebSocketConfig {
    //这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

3.编写一对一聊天

import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;

//{user}、{uuid}这两个值从前端获取
@ServerEndpoint(value = "/onewebsocket/{user}/{uuid}")
@Component
public class oneWebSocket {
    // 通过类似GET请求方式传递参数的方法(服务端采用第二种方法"WebSocketHandler"实现)
//    websocket = new WebSocket("ws://127.0.0.1:18080/testWebsocket?id=23&name=Lebron");
    /**
     * 在线人数
     */
    public static AtomicInteger onlineNumber = new AtomicInteger(0);

    /**
     * 所有的对象,每次连接建立,都会将我们自己定义的MyWebSocket存放到List中,
     */
    public static List<oneWebSocket> webSockets = new CopyOnWriteArrayList<oneWebSocket>();

    /**
     * 会话,与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;

    /**
     * 每个会话的用户
     */
    private String user;

    /**
     * 建立连接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("user") String user) {
        //用户名判断是否为空
        if (user == null || "".equals(user)) {
            try {
                session.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }
        //在线人数+1
        onlineNumber.incrementAndGet();

        //遍历整个MyWebSocket里面的用户
        for (oneWebSocket myWebSocket : webSockets) {
            //判断用户是否重名
            if (user.equals(myWebSocket.user)) {
                try {
                    session.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return;
            }
        }
        //如果确定用户正确
        //将session的缓存存入这个用户
        this.session = session;
        //将user的这个用户
        this.user = user;
        //WebSocket对象+1
        webSockets.add(this);
        System.out.println("有新连接加入! 当前在线人数" + onlineNumber.get());
    }

    /**
     * 连接关闭
     */
    @OnClose
    public void onClose() {
        onlineNumber.decrementAndGet();
        //移除这个对象
        webSockets.remove(this);
        System.out.println("有连接关闭! 当前在线人数" + onlineNumber.get());
    }

    /**
     * 收到客户端的消息
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message,Session session, @PathParam("user") String user,@PathParam("uuid") String uuid) {
        //String[] uuid = message.split(":");
        System.out.println("来自" + user + "消息:" + message+"   发给谁:"+uuid);
        pushMessage(user, message, uuid);
    }

    /**
     * 发送消息
     *
     * @param message 消息
     */
    public void sendMessage(String message) {
        try {
            //缓存里面的消息发出去
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 消息推送
     *
     * @param message
     * @param uuid    uuid为空则推送全部人员
     */
    public static void pushMessage(String user, String message, String uuid) {
        //判断为空则推给所有人
        if (uuid == null || "".equals(uuid)) {
            //推给所有人
            for (oneWebSocket myWebSocket : webSockets) {
                myWebSocket.sendMessage(user + ":" + message);
            }
        } else {
            //私聊只有两个人,所以也就是所有人呗,信息发给所有人呗
            for (OneWebSocket myWebSocket : webSockets) {
                myWebSocket.sendMessage(user + ":" + message);
            }
        }

    }
}

4.一对一前端

<html>
<head>
    <meta charset="UTF-8">
    <title>Web sockets test</title>
    <script type="text/javascript">
        var ws;

        function login() {
            if (!ws) {
                var user = document.getElementById("name").value;
                var uuid = document.getElementById("onename").value;
                console.log("uuid:"+uuid);
                try {
                    //注意端口是否一致
                    ws = new WebSocket("ws://127.0.0.1:8080/onewebsocket/" + user+"/"+uuid);//连接服务器
                    ws.onopen = function (event) {
                        console.log("已经与服务器建立了连接...");
                        alert("登陆成功,可以开始聊天了")
                    };
                    ws.onmessage = function (event) {
                        console.log("接收到服务器发送的数据..." + event.data);
                        document.getElementById("info").innerHTML += event.data + "<br>";
                    };
                    ws.onclose = function (event) {
                        console.log("已经与服务器断开连接...");
                    };
                    ws.onerror = function (event) {
                        console.log("WebSocket异常!");
                    };
                } catch (ex) {
                    alert(ex.message);
                }
                document.getElementById("login").innerHTML = "退出";
            } else {
                ws.close();
                ws = null;
            }
        }
        //发送信息
        function SendData() {
            var data = document.getElementById("data").value;
            try {
                ws.send(data);
            } catch (ex) {
                alert(ex.message);
            }
        };

    </script>
</head>
<body>

<input id="name" value="" placeholder="用户名">
<button id="login" type="button" onclick="login()" value="">登陆</button>

<br/><br/>
<input id="onename" value="" placeholder="发给谁">

<br/><br/>
<input id="data">
<button type="button" onclick='SendData();'>发送消息</button>
<br/><br/>
<div id="info">

</div>
</body>
</html>

5.运行结果为

SpringBoot-实现WebSocket群聊私聊

聊天结果为:
SpringBoot-实现WebSocket群聊私聊
SpringBoot-实现WebSocket群聊私聊

6.编写群聊

与单独聊天差不多,只是少了一个参数uuid的参数

只是将oneWebSocket改为MyWebSocket

html也由前面的转成后面的

import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;


@ServerEndpoint(value = "/websocket/{user}")
@Component
public class MyWebSocket {
    // 通过类似GET请求方式传递参数的方法(服务端采用第二种方法"WebSocketHandler"实现)
//    websocket = new WebSocket("ws://127.0.0.1:18080/testWebsocket?id=23&name=Lebron");
    /**
     * 在线人数
     */
    public static AtomicInteger onlineNumber = new AtomicInteger(0);

    /**
     * 所有的对象,每次连接建立,都会将我们自己定义的MyWebSocket存放到List中,
     */
    public static List<MyWebSocket> webSockets = new CopyOnWriteArrayList<MyWebSocket>();

    /**
     * 会话,与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;

    /**
     * 每个会话的用户
     */
    private String user;

    /**
     * 建立连接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("user") String user) {
        //用户名判断是否为空
        if (user == null || "".equals(user)) {
            try {
                session.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }
        //在线人数+1
        onlineNumber.incrementAndGet();

        //遍历整个MyWebSocket里面的用户
        for (MyWebSocket myWebSocket : webSockets) {
            //判断用户是否重名
            if (user.equals(myWebSocket.user)) {
                try {
                    session.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return;
            }
        }
        //如果确定用户正确
        //将session的缓存存入这个用户
        this.session = session;
        //将user的这个用户
        this.user = user;
        //WebSocket对象+1
        webSockets.add(this);
        System.out.println("有新连接加入! 当前在线人数" + onlineNumber.get());
    }

    /**
     * 连接关闭
     */
    @OnClose
    public void onClose() {
        onlineNumber.decrementAndGet();
        //移除这个对象
        webSockets.remove(this);
        System.out.println("有连接关闭! 当前在线人数" + onlineNumber.get());
    }

    /**
     * 收到客户端的消息
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message, Session session, @PathParam("user") String user) {
        System.out.println("来自" + user + "消息:" + message);
        pushMessage(user, message, null);
    }

    /**
     * 发送消息
     *
     * @param message 消息
     */
    public void sendMessage(String message) {
        try {
            //缓存里面的消息发出去
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 消息推送
     *
     * @param message
     * @param uuid    uuid为空则推送全部人员
     */
    public static void pushMessage(String user, String message, String uuid) {
        if (uuid == null || "".equals(uuid)) {
            //推给所有人
            for (MyWebSocket myWebSocket : webSockets) {
                myWebSocket.sendMessage(user + ":" + message);
            }
        } else {
            for (MyWebSocket myWebSocket : webSockets) {
                //推给某一个人
                if (uuid.equals(myWebSocket.user)) {
                    myWebSocket.sendMessage(message);
                }
            }
        }

    }
}

7.群聊前端

<html>
<head>
    <meta charset="UTF-8">
    <title>Web sockets test</title>
    <script type="text/javascript">
        var ws;

        function login() {
            if (!ws) {
                var user = document.getElementById("name").value;
                try {
                    //注意端口是否一致
                    ws = new WebSocket("ws://127.0.0.1:8080/websocket/" + user);//连接服务器
                    //建立连接 session=event
                    ws.onopen = function (event) {
                        console.log("已经与服务器建立了连接...");
                        alert("登陆成功,可以开始聊天了")
                    };
                    //event代表的就是数据,服务器传过来的数据
                    ws.onmessage = function (event) {
                        //接收到后台发送过来的数据
                        console.log("接收到服务器发送的数据..." + event.data);
                        //界面打印
                        document.getElementById("info").innerHTML += event.data + "<br>";
                    };
                    ws.onclose = function (event) {
                        console.log("已经与服务器断开连接...");
                    };
                    ws.onerror = function (event) {
                        console.log("WebSocket异常!");
                    };
                } catch (ex) {
                    alert(ex.message);
                }
                document.getElementById("login").innerHTML = "退出";
            } else {
                ws.close();
                ws = null;
            }
        }
        //发送信息
        function SendData() {
            var data = document.getElementById("data").value;
            try {
                ws.send(data);
            } catch (ex) {
                alert(ex.message);
            }
        };

    </script>
</head>
<body>
<input id="name" value="" placeholder="用户名">
<button id="login" type="button" onclick="login()" value="">登陆</button>
<br/><br/>
<input id="data">
<button type="button" onclick='SendData();'>发送消息</button>
<br/><br/>
<!--打印数据-->
<div id="info">

</div>
</body>
</html>

附工程结构:
SpringBoot-实现WebSocket群聊私聊

对于运行:

可以直接运行后端,然后再拿浏览器运行前端代码即可。

也可以直接在同一个项目里运行,这个就跑到SpringBoot运行html了。

你们可以看看这篇文章:https://blog.csdn.net/weixin_45969142/article/details/114001188

本文地址:https://blog.csdn.net/weixin_45969142/article/details/114003103

相关标签: Spring websocket