springboot整合websocket实现简单的多人在线聊天

一开始是看着这篇博客写的《使用websocket简单实现多人聊天》,不过有bug(用户名使用的是在线人数作为用户名,当用户退出后,用户名是人数就会出现bug了,可以自己试试,最好是用动态参数)。

而且由于这是springboot启动的,需要额外写个配置类,具体原因可以看这篇文章https://blog.csdn.net/Xyouzi/article/details/113914558,如果使用独立的servlet容器则不需要

  1. 目录结构
    在这里插入图片描述

  2. 引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
  1. 前端页面(index.html用于用户使用,admin.html用于发布广播)

index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>多人在线聊天</title>
</head>
<body>
<input id="text" type="text">
<button onclick="send()">发送消息</button>
<button onclick="closeWebSocket()">退出多人聊天</button>
<hr>
<div id="message"></div>
================================================================
<script type="text/javascript">
    var websocket=null;
    let name = "";
    if('WebSocket' in window){
    
    
        name = location.href.split('?')[1].split("=")[1];
        websocket=new WebSocket("ws://localhost:8088/websocket/server/"+name);
    }
    else{
    
    
        alert('当前浏览器不支持websocket')
    }

    //连接失败事件
    websocket.onerror=function(){
    
    
        setMessageInnerHTML("连接失败!");
    }

    //连接成功事件
    websocket.onopen=function(){
    
    
        setMessageInnerHTML("成功加入聊天室");
    }


    //有消息从服务器端发送过来
    websocket.onmessage=function (event){
    
    
        setMessageInnerHTML(event.data);
    }

    //关闭事件
    websocket.onclose=function(){
    
    
        setMessageInnerHTML('退出聊天室!')
    }


    window.onbeforeunload=function(){
    
    //关闭窗口时,关闭连接
        websocket.close();
    }


    function setMessageInnerHTML(innerHTML){
    
    
        document.getElementById("message").innerHTML+=innerHTML+'<br/>'
    }

    function closeWebSocket(){
    
    
        websocket.close();
    }

    function send(){
    
    
        var message=document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</body>
</html>

admin.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>多人在线聊天</title>
</head>
<body>
<input id="text" type="text">
<button onclick="send()">发送公告</button>
<hr>
<div id="message"></div>
================================================================
<script type="text/javascript">
    var websocket=null;
    let name = "";
    if('WebSocket' in window){
    
    
        name = location.href.split('?')[1].split("=")[1];
        websocket=new WebSocket("ws://localhost:8088/websocket/server/"+name);
    }
    else{
    
    
        alert('当前浏览器不支持websocket')
    }

    //连接失败事件
    websocket.onerror=function(){
    
    
        setMessageInnerHTML("连接失败!");
    }

    //连接成功事件
    websocket.onopen=function(){
    
    
        setMessageInnerHTML("可发布广播");
    }


    //有消息从服务器端发送过来
    websocket.onmessage=function (event){
    
    
        setMessageInnerHTML('已发送广播');
    }

    //关闭事件
    websocket.onclose=function(){
    
    
        setMessageInnerHTML('退出控制台!')
    }


    window.onbeforeunload=function(){
    
    //关闭窗口时,关闭连接
        websocket.close();
    }


    function setMessageInnerHTML(innerHTML){
    
    
        document.getElementById("message").innerHTML+= innerHTML + '<br/>'
    }

    function closeWebSocket(){
    
    
        websocket.close();
    }

    function send(){
    
    
        var message=document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</body>
</html>

4.后端代码

@Component
@ServerEndpoint("/websocket/server/{username}")
public class MySocket {
    
    

    // 记录当前在线记录数
    private static AtomicInteger onlineCount = new AtomicInteger();

    // 存储每个客户端
    private static CopyOnWriteArraySet<MySocket> socketSet = new CopyOnWriteArraySet<MySocket>();

    private Session session;

    private String name;

    @OnOpen//连接成功
    public void onOpen(Session session, @PathParam(value = "username") String userName) {
    
    
        this.session = session;
        socketSet.add(this);
        addOnlineCount();
        this.name = "用户" + userName;//简易用户名
        try {
    
    
            if ("用户all".equals(this.name)){
    
    
                return;
            } else {
    
    
                this.sendMessage("系统:欢迎您!你是" + this.name + ",开始聊天吧!");
            }
        } catch (IOException e) {
    
    
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("有新连接加入!当前在线人数为" + onlineCount);

    }

    @OnClose//关闭
    public void onClose() {
    
    
        subOnlineCount();
        socketSet.remove(this);
        System.out.println("一个用户离开了!当前在线人数" + onlineCount);
    }

    @OnError//连接出错
    public void onError(Session session, Throwable error) {
    
    
        System.out.println("连接发生错误");
        error.printStackTrace();
    }

    @OnMessage//当客户端有消息传来时
    public void onMessage(String message, Session session) {
    
    
        System.out.println("来自客户端的消息,由" + this.name + "发出:" + message);
        String mstemp;
        for (MySocket mySocket : socketSet) {
    
    
            System.out.println(this.name);
            if ("用户all".equals(this.name)) {
    
    
                System.out.println("--"+this.name+"--");
                mstemp = "广播:" + message;
            }
            else if (this.name.equals(mySocket.name)) {
    
     //处理客户端消息
                mstemp = "我" + ":" + message;
            }
            else {
    
    
                mstemp = this.name + ":" + message;
            }
            try {
    
    
                mySocket.sendMessage(mstemp);
            } catch (IOException e) {
    
    
                e.printStackTrace();
                continue;
            }
        }
    }


    public void sendMessage(String message) throws IOException {
    
    
        this.session.getBasicRemote().sendText(message);
    }

    public static synchronized void addOnlineCount() {
    
    
        onlineCount.incrementAndGet();
    }

    public static synchronized void subOnlineCount() {
    
    
        onlineCount.decrementAndGet();
    }

}

还有记得在配置里改端口

猜你喜欢

转载自blog.csdn.net/Xyouzi/article/details/113933410