SpringBoot-实现WebSocket群聊私聊

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

1.添加依赖

	 <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-websocketartifactId>
        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 testtitle>
    <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 + "
"
; }; 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群聊私聊_第1张图片

聊天结果为:
SpringBoot-实现WebSocket群聊私聊_第2张图片
SpringBoot-实现WebSocket群聊私聊_第3张图片

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 testtitle>
    <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 + "
"
; }; 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群聊私聊_第4张图片

对于运行:

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

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

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

你可能感兴趣的:(Spring,websocket)