Webscoket简单demo介绍

news2024/11/14 1:52:08

前言

WebSocket 是从 HTML5 开始⽀持的⼀种⽹⻚端和服务端保持⻓连接的 消息推送机制.
理解消息推送:
传统的 web 程序, 都是属于 “⼀问⼀答” 的形式. 客⼾端给服务器发送了⼀个 HTTP 请求, 服务器给客
⼾端返回⼀个 HTTP 响应.这种情况下, 服务器是属于被动的⼀⽅. 如果客⼾端不主动发起请求, 服务器就⽆法主动给客⼾端响应.
像聊天这样的程序, 是⾮常依赖 “消息推送” 的. 如果只是使⽤原⽣的 HTTP 协议, 要想实现消息推送⼀般需要通过 “轮询” 的⽅式.轮询的成本⽐较⾼, ⽽且也不能及时的获取到消息的响应.⽽ WebSocket 则是更接近于 TCP 这种级别的通信⽅式. ⼀旦连接建⽴完成, 客⼾端或者服务器都可以
主动的向对⽅发送数据.

一.WebScoket是什么?

1.1 webscoket的概念

WebSocket 是基于 TCP 的一种新的应用层网络协议。它实现了浏览器与服务器全双工通信,即允许服务器主动发送信息给客户端。因此,在 WebSocket 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输,客户端和服务器之间的数据交换变得更加简单。

1.2 webscoket 特点

  • 建立在 TCP 协议之上;
  • 与 HTTP 协议有着良好的兼容性:默认端口也是 80(ws) 和 443(wss,运行在 TLS 之上),并且握手阶段采用 HTTP 协议;
  • 较少的控制开销:连接创建后,ws 客户端、服务端进行数据交换时,协议控制的数据包头部较小,而 HTTP 协议每次通信都需要携带完整的头部;
  • 可以发送文本,也可以发送二进制数据;
  • 没有同源限制,客户端可以与任意服务器通信;
  • 协议标识符是 ws(如果加密,则为 wss),服务器网址就是 URL;
  • 支持扩展:ws 协议定义了扩展,用户可以扩展协议,或者实现自定义的子协议(比如支持自定义压缩算法等);

1.3 Webscoket 协议帧

在这里插入图片描述

  • FIN, 长度为 1 比特, 该标志位用于指示当前的 frame 是消息的最后一个分段, 因为 WebSocket 支持将长消息切分为若干个 frame 发送, 切分以后, 除了最后一个 frame, 前面的 frame 的 FIN 字段都为 0, 最后一个 frame 的 FIN 字段为 1, 当然, 若消息没有分段, 那么一个 frame 便包含了完成的消息, 此时其 FIN 字段值为 1

  • RSV 1 ~ 3, 这三个字段为保留字段, 只有在 WebSocket 扩展时用, 若不启用扩展, 则该三个字段应置为 1, 若接收方收到 RSV 1 ~ 3 不全为 0 的 frame, 并且双方没有协商使用 WebSocket 协议扩展, 则接收方应立即终止 WebSocket 连接

  • Opcode, 长度为 4 比特, 该字段将指示 frame 的类型, RFC 6455 定义的 Opcode 共有如下几种:

0x0, 代表当前是一个 continuation frame

0x1, 代表当前是一个 text frame

0x2, 代表当前是一个 binary frame

0x3 ~ 7, 目前保留, 以后将用作更多的非控制类 frame

0x8, 代表当前是一个 connection close, 用于关闭 WebSocket 连接

0x9, 代表当前是一个 ping frame (将在下面讨论)

0xA, 代表当前是一个 pong frame (将在下面讨论)

0xB ~ F, 目前保留, 以后将用作更多的控制类 frame

  • Mask, 长度为 1 比特, 该字段是一个标志位, 用于指示 frame 的数据 (Payload) 是否使用掩码掩盖, RFC 6455 规定当且仅当由客户端向服务端发送的 frame, 需要使用掩码覆盖, 掩码覆盖主要为了解决代理缓存污染攻击 (更多细节见 RFC 6455 Section 10.3)

  • Payload Len, 以字节为单位指示 frame Payload 的长度, 该字段的长度可变, 可能为 7 比特, 也可能为 7 + 16 比特, 也可能为 7 + 64 比特. 具体来说, 当 Payload 的实际长度在 [0, 125] 时, 则 Payload Len 字段的长度为 7 比特, 它的值直接代表了 Payload 的实际长度; 当 Payload 的实际长度为 126 时, 则 Payload Len 后跟随的 16 位将被解释为 16-bit 的无符号整数, 该整数的值指示 Payload 的实际长度; 当 Payload 的实际长度为 127 时, 其后的 64 比特将被解释为 64-bit 的无符号整数, 该整数的值指示 Payload 的实际长度

  • Masking-key, 该字段为可选字段, 当 Mask 标志位为 1 时, 代表这是一个掩码覆盖的 frame, 此时 Masking-key 字段存在, 其长度为 32 位, RFC 6455 规定所有由客户端发往服务端的 frame 都必须使用掩码覆盖, 即对于所有由客户端发往服务端的 frame, 该字段都必须存在, 该字段的值是由客户端使用熵值足够大的随机数发生器生成, 关于掩码覆盖, 将下面讨论, 若 Mask 标识位 0, 则 frame 中将设置该字段 (注意是不设置该字段, 而不仅仅是不给该字段赋值)

  • Payload, 该字段的长度是任意的, 该字段即为 frame 的数据部分, 若通信双方协商使用了 WebSocket 扩展, 则该扩展数据 (Extension data) 也将存放在此处, 扩展数据 + 应用数据, 它们的长度和便为 Payload Len 字段指示的值

1.5 WebSocket 与 HTTP、TCP

WebSocket、HTTP 和 TCP 都是用于网络通信的技术,但它们之间存在一些关键的区别:

  • 层级:

TCP: 属于传输层协议,是面向连接的、可靠的、点对点的传输协议。
HTTP: 属于应用层协议,是无状态的、非可靠的、面向请求-响应的协议。
WebSocket: 属于应用层协议,构建在 TCP 协议之上,是一种全双工、低延迟、低开销的协议。

  • 连接类型:

TCP: 通常是短连接,即连接建立后,数据传输完成后立即断开连接。
HTTP: 通常是短连接,但也可以使用持久连接。
WebSocket: 是长连接,即连接建立后,可以在连接保持期间传输多个数据包。

  • 协议:

TCP: 使用 TCP/IP 协议族进行通信。
HTTP: 使用文本格式的协议进行通信。
WebSocket: 使用 HTTP 协议进行握手建立连接,然后使用基于帧的二进制协议进行数据传输。
用途:

TCP: 广泛应用于各种网络应用,例如 Web 服务器、FTP 客户端/服务器、电子邮件等。
HTTP: 主要用于 Web 服务器和客户端之间的通信,用于传输 Web 页面、图片、视频等数据。
WebSocket: 常用于实时通信应用,例如 Web 聊天、游戏、协作编辑等。

1.6 Websocket 握手原理

在这里插入图片描述

1.7 基于WebSoket编程

java中有两种方式

  1. 使用Tomcat提供原生的WebScoket api .
  2. 使用spring体哦那个的WebScoket api.

编写服务器代码

  1. 创建一个一个类,作为WebSoketHandler
@Component
public class TestWebSocketController extends TextWebSocketHandler {
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 这个方法会在 websocket 连接建立成功后, 被自动调用.
        System.out.println("TestAPI 连接成功!");
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 这个方法是在 websocket 收到消息的时候, 被自动调用的.
        System.out.println("TestAPI 收到消息!" + message.toString());
        // session 是个会话, 里面就记录了通信双方是谁. (session 中就持有了 websocket 的通信连接)
        session.sendMessage(message);
    }

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

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

在这里插入图片描述

  1. 把上面的类注册到spring里面,配置路由。

创建一个类,实现一个webscoket配置的interface

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Autowired
    private TestWebSocketController testWebSocketAPI;
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        //通过这个方法,把创建好的Handler注册到具体的路径上
        //此时当前浏览器,websocket的请求路径是"/test的时候,就会调用TestWebSocketController的处理方法"
        registry.addHandler(testWebSocketAPI, "/test");

    }
}

编写客户端代码

实现js的编写

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试 websocket 的使用</title>
</head>
<body>
    <input type="text" id="message">
    <button id="send-button">发送</button>

    <script>
        // 编写 js 使用 websocket 的代码. 
        // 创建一个 websocket 实例
        var websocket = new WebSocket("ws://localhost:8080/test");

        // 给这个 websocket 注册上一些回调函数. 
        websocket.onopen = function() {
            // 连接建立完成后, 就会自动执行到. 
            console.log("websocket 连接成功!");
        }

        websocket.onclose = function() {
            // 连接断开后, 自动执行到. 
            console.log("websocket 连接断开!");
        }

        websocket.onerror = function() {
            // 连接异常时, 自动执行到
            console.log("websocket 连接异常!");
        }

        websocket.onmessage = function(e) {
            // 收到消息时, 自动执行到
            console.log("websocket 收到消息! " + e.data);
        }

        let messageInput = document.querySelector('#message');
        let sendButton = document.querySelector('#send-button');
        sendButton.onclick = function() {
            console.log("websocket 发送消息: " + messageInput.value);
            websocket.send(messageInput.value);
        }
    </script>
</body>
</html>

在这里插入图片描述

具体的客户端和服务端流程展示

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1596485.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分类预测 | Matlab实现OOA-BP鱼鹰算法优化BP神经网络数据分类预测

分类预测 | Matlab实现OOA-BP鱼鹰算法优化BP神经网络数据分类预测 目录 分类预测 | Matlab实现OOA-BP鱼鹰算法优化BP神经网络数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现OOA-BP鱼鹰算法优化BP神经网络多特征分类预测&#xff08;完整源码和数…

Win7开机进不了系统一直再自动修复,只能选禁用驱动签名才能进系统 其它模式都不行

环境&#xff1a; Win7专业版 问题描述&#xff1a; Win7开机进不了系统一直再修复&#xff0c;只能选禁用驱动签名才能进系统 其它模式都不行 解决方案&#xff1a; 1.开机按F8&#xff0c;选择禁用驱动签名进系统 2.查看系统日志文件定位错误原因 3.我这是DsArk64.sys导…

JS-32-jQuery01-jQuery的引入

一、初识jQuery jQuery是JavaScript世界中使用最广泛的一个库。鉴于它如此流行&#xff0c;又如此好用&#xff0c;所以每一个入门JavaScript的前端工程师都应该了解和学习它。 jQuery是一个优秀的JS函数库。 &#xff08;对BOM和DOM的封装&#xff09; jQuery这么流行&#x…

Flink设计运行原理 | 大数据技术

⭐简单说两句⭐ ✨ 正在努力的小新~ &#x1f496; 超级爱分享&#xff0c;分享各种有趣干货&#xff01; &#x1f469;‍&#x1f4bb; 提供&#xff1a;模拟面试 | 简历诊断 | 独家简历模板 &#x1f308; 感谢关注&#xff0c;关注了你就是我的超级粉丝啦&#xff01; &…

计算机毕业设计springboot小区物业报修管理系统m8x57

该物业报修管理系统实施的目的在于帮助物业管理企业升级员工管理、住户管理、报修问题管理等内部管理平台&#xff0c;整合物业管理企业物力和人力&#xff0c;全面服务于维修人员管理的内部管理需求,并重视需求驱动、管理创新、与业主交流等外部需求,通过物业管理企业各项资源…

ArrayList部分底层源码分析

JDK版本为1.8.0_271&#xff0c;以插入和删除元素为例&#xff0c;部分源码如下&#xff1a; // 部分属性 transient Object[] elementData; // 底层数组 private int size; // 记录元素个数 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA {}; // 空Obje…

异地组网怎么安装?

异地组网安装是指在不同地域的多个设备之间建立网络连接&#xff0c;以便实现数据传输和协同工作的过程。在如今的数字化时代&#xff0c;异地组网安装已经成为了许多企业和组织所必需的一项技术。 天联的使用场景 在异地组网安装中&#xff0c;天联是一种常用的工具。它具有以…

得物 Zookeeper SLA 也可以 99.99% | 得物技术

一、背景 ZooKeeper&#xff08;ZK&#xff09;是一个诞生于2007年的分布式应用程序协调服务。尽管出于一些特殊的历史原因&#xff0c;许多业务场景仍然不得不依赖它。比如&#xff0c;Kafka、任务调度等。特别是在 Flink 混合部署 ETCD 解耦 时&#xff0c;业务方曾要求绝对…

网络与系统攻防技术实验及实验报告

1.实验内容 正确使用msf编码器&#xff0c;veil-evasion&#xff0c;自己利用shellcode编程等免杀工具或技巧 正确使用msf编码器&#xff0c;使用msfvenom生成如jar之类的其他文件veil&#xff0c;加壳工具使用C shellcode编程 通过组合应用各种技术实现恶意代码免杀 如果成功…

多目标跟踪 | 基于anchor-free目标检测+ReID的实时一阶多类多目标跟踪算法实现

项目应用场景 面向多目标检测跟踪场景&#xff0c;项目采用 anchor-free 目标检测ReID 的实时一阶段多类多目标跟踪算法实现&#xff0c;效果嘎嘎好。 项目效果 项目细节 > 具体参见项目 README.md (1) 类别支持 1~10 object classes are what we need non-interest-…

智能热流体仿真软件AICFD 2024R1新版本功能介绍

AICFD是由天洑软件自主研发的一款通用的智能热流体仿真软件。软件引入AI技术&#xff0c;具备智能问答、智能加速、智能预测等特色功能&#xff0c;解决用户在传统CFD软件中遇到的“网格划分繁、求解设置难、仿真计算慢”等痛点&#xff0c;使设计师和工程师可以专注于业务本身…

AI大模型语言开源大语言模型完整列表

开源大语言模型完整列表 Large Language Model (LLM) 即大规模语言模型&#xff0c;是一种基于深度学习的自然语言处理模型&#xff0c;它能够学习到自然语言的语法和语义&#xff0c;从而可以生成人类可读的文本。 所谓"语言模型"&#xff0c;就是只用来处理语言文…

WP免费主题下载

免费wordpress模板下载 高端大气上档次的免费wordpress主题&#xff0c;首页大图全屏显示经典风格的wordpress主题。 https://www.wpniu.com/themes/289.html 免费WP主题 蓝色简洁实用的wordpress免费主题模板&#xff0c;免费主题资源分享给大家。 https://www.wpniu.com/…

如何查找overlayfs对应的POD如何根据pod找到containerd id

如何查找overlayfs对应的POD mount |grep overlayfs | grep 1738 ctr -n k8s.io c list | grep 11ac4083419be11174746b68d018a0a402d9ae43c6b52125810fe1ec7db63bc6 查找目录并统计大小 find / -name "jfsCache" -exec du -sh {} | sort -rh如何根据pod找到c…

配置IP地址并验证连通性

1.实验环境 主机 A和主机 B通过一根网线相连&#xff0c;如图6.13所示。 图6.13 实验案例一示意图 2.需求描述 为两台主机配置!P地址&#xff0c;验证P地址是否生效&#xff1b;验证同一网段的两台主机可以互通&#xff0c;不同网段的主机不能直接互通。 3.推荐步骤 为两台…

笔记软件功能多样的是哪款?做笔记的软件哪个好用

在快节奏的现代生活中&#xff0c;笔记软件已成为我们提高工作效率、记录生活点滴的重要工具。想象一下&#xff0c;在繁忙的工作中&#xff0c;你能够快速记录下关键信息&#xff0c;或在灵感迸发时及时捕捉&#xff0c;这是多么方便高效。 一款功能多样的笔记软件&#xff0…

JAVA-贪吃蛇(源代码)

游戏界面: 图片素材: 背景图片 蛇身 食物 蛇头 标题 源代码: 运行界面 package com.snake.game;public class snakeApp {public static void main(String[] args) {//添加界面new snakeJFrame();} }游戏界面类JFrame package com.snake.game;import javax.swing.*; import …

WEB前端-用户注册倒计时

<body><textarea name"" id"" cols"30" rows"10">用户注册协议欢迎注册成为京东用户&#xff01;在您注册过程中&#xff0c;您需要完成我们的注册流程并通过点击同意的形式在线签署以下协议&#xff0c;请您务必仔细阅读…

腾讯EdgeOne产品测评体验——多重攻击实战验证安全壁垒:DDoS攻击|CC压测|Web漏洞扫描|SQL注入

腾讯EdgeOne产品测评体验——实战验证安全壁垒&#xff1a;DDoS攻击|CC压测|Web漏洞扫描|SQL注入 写在最前面一、产品概述1.1 什么是边缘安全加速平台 EO&#xff1f;1.2 EdgeOne产品功能 二、准备工作2.1 选择&#xff1a;NS&#xff08;Name Server&#xff09;接入模式或 CN…

智慧用电安全管理系统

智慧用电安全管理系统 智慧用电安全管理系统是智能电网中客户侧关键的构成部分&#xff0c;是基本建设新型智慧城市的基本&#xff0c;将完成地区内各种各样用电设备的智能化系统监管&#xff0c;完成地区内日常生活与工作中安全性、舒服。 一、智慧用电安全管理系统介绍 …