Websocket (帧格式, 握手过程, Spring 中使用 WebScoket 协议)

简介: Websocket (帧格式, 握手过程, Spring 中使用 WebScoket 协议)

什么是 WebSocket

客户端 A 和客户端 B 的消息传播需要借助服务器的中转 (原因是内网不能给另一个局域网的内网直接联通, 需要借助服务器的外网做 “中介”) (NAT 地址转换)

Http 协议 不支持实时通讯 (或者说不支持服务器主动推送数据给客户端)

TCP 本身是具有服务器推送数据这样的功能的, 但是 Http 把它搞丢了 (发明 Http 的大佬们当年所处的时候, 网页就是用来看看新闻, 也没想到后辈能把网页玩出花来)

于是有了 WebSocket 协议.(基于传输层的 TCP 实现) (和 Http 一样, 都是 应用层协议 )

Tomcat 和 Spring 都提供了 WebSocket API, 方便我们通过 WebSocket 协议实现服务器消息推送


Socket 和 WebSocket

Socket 是 OS (或者说传输层) 提供的一组用于网络编程的 API

WebSocket 是一个应用层协议

二者牛马不相及 (没关系)

硬要说有关系, 那就是 WebSocket 的内部实现用到了 Socket

帧格式 (Base Framing Protocol)

FIN : 表示本帧是否是消息的最后一帧, 是1否0

opcode : 解释 payload data 的类型

MASK : 表示 Payload data 是否经过掩码处理

Payload len: 有效载荷长度 ( [0, 125] – 只使用 Payload len空间, [126] – 表示使用 Payload len 和 Extension Payload len 空间, >[127, …] – 使用 Payload len 和 Extension Payload len 和 Extension payLoad len continue 空间) (即不同数值用不同空间来表示载荷的长度)

masking-key : 掩码内容, 当 MASK = 1 时被启用

payload data : 载荷的具体内容

WebSocket 握手过程

握手之前, 客户端和浏览器同为 Http 协议

握手开始, 客户端向服务器发起 Http 请求, 根据请求头里包含的信息, 请求服务器进行协议切换

( Connection: upgrade – 能不能换个协议啊)

( Upgrade: WebSocket – 换成 WebSocket 协议行不行啊)

服务器收到浏览器的请求, 并返回响应, 并切换协议格式

( Connection: upgrade – 能换协议啊)

( Upgrade: WebSocket – 换成 WebSocket 协议 ok 啊)

返回的协议内, 状态码为 101, 明确告诉客户端, 我已经切换协议了, 我们之后用 WebSocket 协议进行通信

WebSocket 和 Http 协议是什么关系?

没关系

Http 就是 工具人

客户端和服务器之间通过 Http 协议建立连接, 连接建立完成之后, 就再也用不到 Http 协议了

WebSocket 在 Spring 中的使用

前端

// 创建 websocket 实例, 或者说进行与服务器建立 WebSocket 连接
// let websocket = new WebSocket("ws://127.0.0.1:8080/WebSocketMessage"); // 操作本地
// let websocket = new WebSocket("ws://152.136.56.110:9090/WebSocketMessage"); //操作远程服务器
let websocket = new WebSocket("ws://" + location.host + "/WebSocketMessage"); //统一格式

websocket.onopen = function() {
  // 该方法在连接建立完成后, 被自动调用
    console.log("websocket 连接成功!");
}

websocket.onmessage = function(e) {
  // 该方法在收到消息时, 被自动调用
    console.log("websocket 收到消息! " + e.data);
    // 处理消息响应
    handleMessage(e.data);  
}

websocket.onclose = function() {
  // 该方法在连接关闭后, 被自动调用
    console.log("websocket 连接关闭!");
}

websocket.onerror = function() {
  // 该方法在连接异常时, 被自动调用
    console.log("websocket 连接异常!");
}

后端

导入依赖

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

首先是 创建 Handler 对象, 让其 继承 TextWebSocketHandler

然后将 Handler 注册到 实现 WebSocketConfigurer 接口 的 注册类中

对于 Handler 对象, 有四个常用的方法

afterConnectionEstablished : 该方法在 WebSocket 连接建立 之后, 被自动调用

handlerTextMessage : 该方法在 WebSocket 收到消息 的时候, 被自动调用

handlerTransportError : 该方法在连接 出现异常 的时候, 被自动调用

afterConnectionClosed : 该方法在连接 正常关闭 后, 被自动调用

@Component
public class TestWebSocketAPI extends TextWebSocketHandler {
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 该方法会在 websocket 连接建立之后, 被自动调用
        System.out.println("Test 连接成功!");
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 该方法会在 websocket 收到消息的时候, 被自动调用
        System.out.println("Test 收到消息!" + message.toString());
    
    // 这里可以直接用, 是因为在注册器中, 已经把 HttpSession 中的内容给放到 WebSocketSession 中了
    User user = session.getAttribute().get("user");

        // session 是个会话, 里面记录通信双方的信息 (session 中持有 websocket 的通信连接)
        session.sendMessage(message);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        // 这个方法实在 连接出现异常的时候, 被自动调用
        System.out.println("Test 连接异常!");
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        // 这个方法是在连接正常关闭后, 会被自动调用
        System.out.println("Test 连接关闭!");
    }
}

对于注册器, 通过 registerWebSocketHandlers 方法的来注册 Handler (记得给注册器添加注解: @EnableWebSocket)

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Autowired
    private TestWebSocketAPI testWebSocketAPI;

    @Autowired
    private WebSocketAPI webSocketAPI;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        // 通过本方法, 将创建好的 Handler 类给注册到具体路径上.
        // 此时浏览器可通过 请求路径, 调用到绑定的 Handler 类.
        registry.addHandler(testWebSocketAPI, "/test")
                // 通过注册这个特定的 HttpSession 拦截器, 可以把用户在
                // HttpSession 中添加的 Attribute 键值对
                // 往 WebSocketSession 中添加一份
                .addInterceptors(new HttpSessionHandshakeInterceptor());
    }
}

目录
相关文章
|
1月前
|
监控 负载均衡 安全
WebSocket网络编程深度实践:从协议原理到生产级应用
蒋星熠Jaxonic,技术宇宙中的星际旅人,以代码为舟、算法为帆,探索实时通信的无限可能。本文深入解析WebSocket协议原理、工程实践与架构设计,涵盖握手机制、心跳保活、集群部署、安全防护等核心内容,结合代码示例与架构图,助你构建稳定高效的实时应用,在二进制星河中谱写极客诗篇。
WebSocket网络编程深度实践:从协议原理到生产级应用
|
前端开发 网络协议 JavaScript
在Spring Boot中实现基于WebSocket的实时通信
在Spring Boot中实现基于WebSocket的实时通信
|
5月前
|
弹性计算 JavaScript Ubuntu
WebSocket协议相关的测试命令工具使用简介
本文介绍了针对WebSocket的测试工具wscat和websocat的基本使用方法,以及通过curl命令测试HTTP/HTTPS协议的方式。对于WebSocket,直接使用curl测试较为复杂,推荐使用wscat或websocat。文中详细说明了这两种工具的安装步骤、常用参数及连接示例,例如在ECS上开启8080端口监听并进行消息收发测试。此外,还提供了curl命令的手动设置头部信息以模拟WebSocket握手的示例,但指出curl仅能作为客户端测试工具,无法模拟服务器。
1067 4
|
开发框架 前端开发 网络协议
Spring Boot结合Netty和WebSocket,实现后台向前端实时推送信息
【10月更文挑战第18天】 在现代互联网应用中,实时通信变得越来越重要。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为客户端和服务器之间的实时数据传输提供了一种高效的解决方案。Netty作为一个高性能、事件驱动的NIO框架,它基于Java NIO实现了异步和事件驱动的网络应用程序。Spring Boot是一个基于Spring框架的微服务开发框架,它提供了许多开箱即用的功能和简化配置的机制。本文将详细介绍如何使用Spring Boot集成Netty和WebSocket,实现后台向前端推送信息的功能。
2920 1
|
7月前
|
网络协议 Java 开发工具
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
387 1
|
10月前
|
弹性计算 JSON 自然语言处理
语音交互产品通过WebSocket协议对外提供实时语音流语音转写功能
阿里云智能语音交互产品通过WebSocket协议提供实时语音转写功能,支持长语音。音频流以Binary Frame上传,指令和事件为Text Frame。支持单声道、16 bit采样位数的PCM、WAV等格式,采样率8000Hz/16000Hz。可设置返回中间结果、添加标点、中文数字转阿拉伯数字,并支持多语言识别。服务端通过临时Token鉴权,提供外网和上海ECS内网访问URL。交互流程包括StartTranscription、StopTranscription指令及多种事件反馈。
|
JavaScript 前端开发 网络协议
WebSocket在Java Spring Boot+Vue框架中实现消息推送功能
在现代Web应用中,实时消息提醒是一项非常重要的功能,能够极大地提升用户体验。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为实现实时消息提醒提供了高效且低延迟的解决方案。本文将详细介绍如何在Java Spring Boot后端和Vue前端框架中利用WebSocket实现消息提醒功能。
1442 127
|
移动开发 JSON Java
Jmeter实现WebSocket协议的接口测试方法
WebSocket协议是HTML5的一种新协议,实现了浏览器与服务器之间的全双工通信。通过简单的握手动作,双方可直接传输数据。其优势包括极小的头部开销和服务器推送功能。使用JMeter进行WebSocket接口和性能测试时,需安装特定插件并配置相关参数,如服务器地址、端口号等,还可通过CSV文件实现参数化,以满足不同测试需求。
771 7
Jmeter实现WebSocket协议的接口测试方法
|
前端开发 Java C++
RSocket vs WebSocket:Spring Boot 3.3 中的两大实时通信利器
本文介绍了在 Spring Boot 3.3 中使用 RSocket 和 WebSocket 实现实时通信的方法。RSocket 是一种高效的网络通信协议,支持多种通信模式,适用于微服务和流式数据传输。WebSocket 则是一种标准协议,支持全双工通信,适合实时数据更新场景。文章通过一个完整的示例,展示了如何配置项目、实现前后端交互和消息传递,并提供了详细的代码示例。通过这些技术,可以大幅提升系统的响应速度和处理效率。
|
机器学习/深度学习 自然语言处理 网络协议
为什么ChatGPT采用SSE协议而不是WebSocket?
在探讨大型语言模型ChatGPT的技术实现时,一个引人注目的细节是其选择使用SSE(Server-Sent Events)协议而非WebSocket来实现数据的实时推送。这一选择背后,蕴含着对技术特性、应用场景及资源效率的深思熟虑。本文将深入探讨ChatGPT为何偏爱SSE,以及这一决策背后的技术逻辑。
983 3

热门文章

最新文章