当前位置: 首页 > article >正文

websocket学习笔记【springboot+websocket聊天室demo】

文章目录

  • WebSocket是什么?
  • 为什么需要WebSocket?
  • WebSocket和Http连接的区别
  • WebSocket的工作原理
    • 基本交互过程:
  • Java中的WebSocket支持
  • WebSocket的优势
  • springboot + websocket + themlef 一个聊天室demo
    • pom.xml
    • WebSocketConfig
    • ChatController
    • WebController
    • chat.html
    • application.yml
  • 测试效果

WebSocket是什么?

WebSocket是一种基于TCP协议的双向通信协议,它允许服务器和客户端之间建立持久的连接。与传统的HTTP请求/响应模型不同,WebSocket连接一旦建立,可以在不断开的情况下双向传输数据。这使得WebSocket在实时应用中非常有用,例如在线游戏、即时聊天、实时协作工具等。

为什么需要WebSocket?

尽管HTTP协议广泛应用于网络通信,但它存在一个关键的局限性:通信只能由客户端发起。这种方式在需要频繁的数据更新和实时交互的场景中效率低下。例如,在一个聊天应用中,使用HTTP协议,客户端需要不断地发送请求以检查新消息,这种“轮询”机制浪费了大量的资源。WebSocket应运而生,解决了这个问题,通过建立一个持久的连接,实现了更高效的数据交换。

WebSocket和Http连接的区别

  • 通信方式:
    HTTP: HTTP是一种无状态协议,每次请求都是独立的,即使是在同一个客户端和服务器之间的多次请求。客户端向服务器发送请求,服务器处理请求并返回响应,然后连接关闭。HTTP通常是一种请求/响应协议。
    WebSocket: WebSocket是一种全双工协议,允许双方建立持久性的连接,以便在连接建立后双向传输数据。WebSocket支持实时通信,允许服务器和客户端随时发送数据,而无需为每个消息建立新的连接。

  • 连接建立:
    HTTP: HTTP连接是临时的,每个请求都需要建立新的TCP连接,完成后即刻关闭。这导致了额外的延迟,尤其是在需要频繁通信的实时应用中。
    在这里插入图片描述

    WebSocket: WebSocket连接是持久的,一旦建立,它可以一直保持开放状态,不需要在每次通信之间重新建立连接。这减少了延迟,并使它适用于实时应用。
    在这里插入图片描述

  • 头部信息:
    HTTP: HTTP请求和响应通常包括大量的头部信息,用于描述请求的属性、内容类型等。这些头部信息会占用额外的带宽,尤其是在小数据传输中显得不必要。
    WebSocket: WebSocket头部信息相对较少,因为它专注于数据传输,减少了不必要的开销。

  • 用途:
    HTTP: HTTP主要用于请求和获取资源,如网页、图像、文档等。每个HTTP请求都是短暂的,没有保持连接的需求。
    WebSocket: WebSocket适用于需要实时通信、双向数据交换的应用,如在线游戏、实时聊天、实时协作工具、监控系统等。

  • 安全性:
    HTTP: HTTP本身不提供加密,因此数据可以被拦截和窥探。但HTTPS通过TLS/SSL协议提供了数据加密和安全性。
    WebSocket: WebSocket也可以通过WSS(WebSocket Secure)协议提供加密和安全性,以确保数据的机密性。

WebSocket的工作原理

基本交互过程:

1. 握手阶段: 客户端通过发送HTTP升级请求到服务器来启动WebSocket连接。服务器收到这个请求后,如果支持WebSocket,它将回复一个HTTP 101切换协议的响应,从而建立WebSocket连接。

2. 数据传输: 一旦WebSocket连接建立,客户端和服务器可以双向传输数据。无论是客户端还是服务器,都可以随时向对方发送消息。这种双向通信的实时性使WebSocket在很多应用场景中非常有用。

3. 关闭连接: 当需要关闭WebSocket连接时,任一方可以发送一个关闭帧,通知对方关闭连接。这确保了连接的正常关闭,释放资源。

Java中的WebSocket支持

Java提供了多种库和框架来支持WebSocket技术,其中最知名的是Java API for WebSocket(JSR-356),它是Java EE 7规范的一部分。Java WebSocket API允许你在Java应用程序中创建WebSocket服务器和客户端。

WebSocket的优势

减少开销: 在建立连接后,WebSocket不需要像HTTP那样为每个消息发送额外的头信息,这降低了通信的总体开销。
实时性: 全双工通信使得消息可以即时发送和接收,非常适合需要实时数据交互的应用。
节省资源: 相比于HTTP轮询,WebSocket通过维持持久连接减少了频繁建立和断开连接的资源消耗。

springboot + websocket + themlef 一个聊天室demo

在这里插入图片描述

pom.xml

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

WebSocketConfig

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/chat").withSockJS();
    }

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

ChatController

@Controller
public class ChatController {

    @MessageMapping("/sendMessage")
    @SendTo("/topic/public")
    public String sendMessage(String message) {
        return message;
    }

}

WebController

@Controller
public class WebController {
    @GetMapping("/chat")
    public String chat() {
        return "chat"; // Thymeleaf 模板文件的名称(不包含 .html 扩展名)
    }
}

chat.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Chat Room</title>
    <script src="https://cdn.jsdelivr.net/npm/sockjs-client/dist/sockjs.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/stomp-websocket/lib/stomp.min.js"></script>
    <style>
        #messageArea {
            height: 300px;
            overflow-y: auto;
            border: 1px solid #cccccc;
            padding: 10px;
            margin-bottom: 10px;
        }

        .chat-message {
            margin-bottom: 10px;
            border: 1px solid #dddddd;
            padding: 5px;
            border-radius: 5px;
        }
    </style>
</head>
<body>
<div id="chatPage">
    <div id="messageArea"></div>
    <input type="text" id="messageInput" placeholder="Type a message...">
    <button onclick="sendMessage()">Send</button>
</div>
<script th:inline="javascript">
    var stompClient = null;
    function connect() {
        var socket = new SockJS('/chat');
        stompClient = Stomp.over(socket);
        stompClient.connect({}, function (frame) {
            stompClient.subscribe('/topic/public', function (message) {
                showMessage(message.body);
            });
        });
    }

    function sendMessage() {
        var message = document.getElementById('messageInput').value;
        stompClient.send("/app/sendMessage", {}, message);
        document.getElementById('messageInput').value = '';
    }

    function showMessage(message) {
        var messageArea = document.getElementById('messageArea');
        var messageElement = document.createElement('div');
        messageElement.classList.add('chat-message');
        messageElement.innerText = message;
        messageArea.appendChild(messageElement);
    }

    connect();
</script>
</body>
</html>

application.yml

server:
  port: 8081

spring:
  thymeleaf:
    mode: HTML
    cache: true
    prefix: classpath:/templates/
    encoding: UTF-8
    suffix: .html
    check-template-location: true
    template-resolver-order: 1

测试效果

在浏览器访问http://localhost:8081/chat,打开多个界面
在这里插入图片描述
在其中一个窗口发送信息
在这里插入图片描述
其他窗口都收到了信息
在这里插入图片描述


http://www.kler.cn/a/133617.html

相关文章:

  • Java NIO 深度解析:构建高效的 I/O 操作
  • 【Excel】ToRow超级查找函数
  • 【FFmpeg】FFmpeg 函数简介 ③ ( 编解码相关函数 | FFmpeg 源码地址 | FFmpeg 解码器相关 结构体 和 函数 )
  • 如何在python中模拟重载初始化函数?
  • 【C语言】值传递和地址传递
  • Spring-Webflux + Reactor + Netty 初体验
  • PostgreSQL 数据类型
  • 基于JavaWeb+SSM+社区居家养老服务平台—颐养者端微信小程序系统的设计和实现
  • 软件质量保护与测试(第2版)学习总结第十三章 集成测试
  • 切换阿里云ES方式及故障应急处理方案
  • vue之Error: Unknown option: .devServer.
  • Panda3d 动画序列
  • 七、文件包含漏洞
  • Excel查询时用vlookup或者xlookup时,虽然用的参数选择的是精确匹配,但是发现不能区分大小写,应该如何解决?
  • 【C/PTA】数组进阶练习(三)
  • 系列七、JVM的内存结构【堆(Heap)】
  • 【Rust】6、练习:自己实现 ls
  • 【STM32】ADC(模拟/数字转换)
  • JVM:字节码文件,类的生命周期,类加载器
  • wpf devexpress 创建布局
  • 蓝桥杯第三周算法竞赛D题E题
  • Android studio访问选程https接口(.crt handshake)
  • 一文了解ChatGPT Plus如何完成论文写作和AI绘图
  • rust内存优化
  • .NET CLR介绍
  • 处理多个axios请求