SpringBoot整合WebSocket实现聊天室

1.简单的实现了聊天室功能,注意页面刷新后聊天记录不会保存,后端没有做消息的持久化

2.后端用户的识别只简单使用Session用户的身份

0.依赖

XML 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

1.配置WebSocketConfigurer配置类

java 复制代码
package com.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.server.HandshakeInterceptor;

import javax.servlet.http.HttpSession;
import java.util.Map;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfigurer implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").withSockJS()
                .setInterceptors(new HttpHandshakeInterceptor());
    }

    public class HttpHandshakeInterceptor implements HandshakeInterceptor {
        @Override
        public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                       WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
            if (request instanceof ServletServerHttpRequest) {
                ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
                HttpSession session = servletRequest.getServletRequest().getSession(false);
                if (session != null) {
                    //使用session中的user
                    String user = (String) session.getAttribute("user");
                    if(user!=null){
                        attributes.put("user", user);
                    }
                }
            }
            return true;
        }

        @Override
        public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                   WebSocketHandler wsHandler, Exception exception) { }
    }

}

2.MessageHandler用于处理接收消息

java 复制代码
package com.example.webController;

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import javax.servlet.http.HttpSession;

@Controller
public class MessageHandler {


    @MessageMapping("/chat")
    @SendTo("/topic/messages")
    public String chat(@PathVariable("messages") String message, SimpMessageHeaderAccessor headerAccessor) {
        // 获取用户数据
        Object user = headerAccessor.getSessionAttributes().get("user");
        System.out.println("User: " + user);

        return user.toString()+":" + message;
    }

    //登录
    @GetMapping("login/{userName}")
    public void login(@PathVariable String userName, HttpSession session) {
        System.out.println("User " + userName);
        session.setAttribute("user", userName);
    }
}

3.前端页面

先登录后发送消息

4.前端代码

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/sockjs-client/dist/sockjs.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/stompjs/lib/stomp.min.js"></script>
    <style>
        #chatBox {
            width: 60%;
            margin: auto;
            height: 500px;
            border: 1px solid black;
            padding: 10px;
            border-radius: 7px;
        }
        .chat-message {
            height: 85%;
            overflow: auto;
        }
        .flex-row, .flex-row-reverse {
            display: flex;
            justify-content: space-between;
            padding: 10px 0;
        }
        .message {
            max-width: 60%;
            padding: 10px;
            border-radius: 10px;
        }
        .user {
            background-color: #7986cb;
            color: white;
        }
        .assistant {
            background-color: #ffe082;
        }
        #inputMessage {
            width: 80%;
            padding: 10px;
            border-radius: 10px;
            border: 1px solid black;
            margin-top: 10px;
        }
        #sendButton {
            width: 15%;
            margin-left: 5%;
            padding: 11px;
            background-color: #ff7043;
            color: white;
            border: none;
            border-radius: 10px;
            cursor: pointer;
        }
    </style>
</head>
<body>
<div id="chat">
    <div id="chatBox">
        <div class="chat-message">
            <div class="flex-row">
                <div class="message user">
                    <p>Hello</p>
                </div>
            </div>
            <div class="flex-row-reverse">
                <div class="message assistant">
                    <p>Hi, How can I help you?</p>
                </div>
            </div>
        </div>
        <input type="text" id="inputMessage" placeholder="Type message.." />
        <button id="sendButton"  onclick="send()">Send</button>
    </div>
    <input type="text" id="login" placeholder="输入用户名。。。" />
    <button  onclick="login()">Login</button>

</div>
<script>
    var socket = new SockJS('/ws');
    var stompClient = Stomp.over(socket);

    stompClient.connect({}, function(frame) {
        stompClient.subscribe('/topic/messages', function(message) {
            var div = document.createElement('div');
            div.className = "flex-row-reverse";
            var messageDiv = document.createElement('div');
            messageDiv.className = "message assistant";
            var p = document.createElement('p');
            p.textContent = message.body;
            messageDiv.appendChild(p);
            div.appendChild(messageDiv);
            document.querySelector('.chat-message').appendChild(div);
        });
    });
    function login() {
        var value = document.getElementById('login').value;
        //发送get请求
        fetch('/login/' + value)
        //刷新页面
        window.location.reload();
    }
    function send() {
        var inputValue = document.getElementById('inputMessage').value;
        var div = document.createElement('div');
        div.className = "flex-row";
        // var messageDiv = document.createElement('div');
        // messageDiv.className = "message user";
        // var p = document.createElement('p');
        // p.textContent = inputValue;
        // messageDiv.appendChild(p);
        // div.appendChild(messageDiv);
        document.querySelector('.chat-message').appendChild(div);
        stompClient.send("/app/chat", {}, inputValue);
        document.getElementById('inputMessage').value = '';
    }
</script>
</body>
</html>
相关推荐
天之涯上上1 分钟前
JAVA开发 在 Spring Boot 中集成 Swagger
java·开发语言·spring boot
白宇横流学长3 分钟前
基于SpringBoot的停车场管理系统设计与实现【源码+文档+部署讲解】
java·spring boot·后端
kirito学长-Java8 分钟前
springboot/ssm太原学院商铺管理系统Java代码编写web在线购物商城
java·spring boot·后端
中草药z25 分钟前
【Spring】深入解析 Spring 原理:Bean 的多方面剖析(源码阅读)
java·数据库·spring boot·spring·bean·源码阅读
程序猿-瑞瑞41 分钟前
24 go语言(golang) - gorm框架安装及使用案例详解
开发语言·后端·golang·gorm
m0_7482567843 分钟前
SpringBoot 依赖之Spring Web
前端·spring boot·spring
组合缺一44 分钟前
Solon v3.0.5 发布!(Spring 可以退休了吗?)
java·后端·spring·solon
猿来入此小猿1 小时前
基于SpringBoot在线音乐系统平台功能实现十二
java·spring boot·后端·毕业设计·音乐系统·音乐平台·毕业源码
愤怒的代码1 小时前
Spring Boot对访问密钥加解密——HMAC-SHA256
java·spring boot·后端
栗豆包1 小时前
w118共享汽车管理系统
java·spring boot·后端·spring·tomcat·maven