WebSocket 快速入门 与 应用

        WebSocket 是一种在 Web 应用程序中实现实时、双向通信的技术。它允许客户端和服务器之间建立持久性的连接,以便可以在两者之间双向传输数据

以下是 WebSocket 的一些关键特点和工作原理:

0.特点:

  1. 双向通信:WebSocket 允许服务器和客户端之间进行双向通信,无需客户端发起请求。

  2. 实时性:WebSocket 提供了实时性通信的能力,使得服务器可以立即将数据推送给客户端,而无需等待客户端发起请求。

  3. 持久性连接:与传统的 HTTP 请求-响应模式不同,WebSocket 的连接是持久性的,一旦建立连接,它将保持打开状态,直到其中一方主动关闭连接。

  4. 低延迟:由于 WebSocket 使用单一的 TCP 连接,相较于传统的轮询或长轮询方式,它能够减少通信的延迟。

  5. 节省带宽:WebSocket 的头部较小,且在通信过程中不需要重复的 HTTP 头部,因此可以节省带宽。

1.工作原理:

  1. 握手阶段:客户端发起 WebSocket 握手请求,请求头部包含一些特定的字段,如 Upgrade 和 Connection 等。服务器收到请求后,如果支持 WebSocket 协议,会返回 101 状态码,表示协议切换成功,然后连接升级为 WebSocket 连接。

  2. 建立连接:建立连接后,服务器和客户端可以通过发送消息进行通信。每个消息都被分割成一个或多个帧进行传输。

  3. 数据传输:WebSocket 数据以帧的形式传输。帧可以是文本、二进制数据或控制帧。文本帧用于传输文本数据,而二进制帧用于传输二进制数据。控制帧用于控制连接,例如关闭连接或心跳检测。

  4. 保持活动状态:WebSocket 连接可以保持活动状态,无需在每次通信后重新建立连接。服务器和客户端可以周期性地发送心跳消息来保持连接的活跃状态。

  5. 关闭连接:任何一方都可以通过发送关闭帧来关闭连接。关闭帧包含一个状态码和一个可选的关闭消息。收到关闭帧后,双方都应该关闭连接。

        WebSocket 在现代 Web 应用程序中被广泛应用于实时通信、在线游戏、实时协作等场景,它提供了一种高效且可靠的双向通信方式,为开发者提供了更多创新的可能性。

2. 基于 Java 实现 WebSocket

  • 服务端的类
    • 监听连接——@ServerEndpoint
    • 连接成功——@OnOpen
    • 连接关闭——@OnClose
    • 收到消息状态——@OnMessage
(一)方式一:通过注解实现

        实现了一个基于WebSocket的双向通信系统

        其中服务器端配置了 WebSocket 并实现了消息处理和定时推送

        客户端页面则使用 JavaScript 创建WebSocket连接 并实现消息发送和接收。

1.项目依赖

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
2.WsServerEndpoint
/*** 监听webSocket地址  /myWs* 即:监听谁连接了 客户端*//*** 定义了一个 WebSocket 服务器端点的类。它使用了 @ServerEndpoint 来指定 WebSocket 的端点路径为 "/myWs"。** 这个类也使用了 @Component 注解,将这个类标记为 Spring 的组件,以便 Spring 自动扫描并注册它。** 另外,使用了 @EnableScheduling 注解用于开启定时任务功能。*/@ServerEndpoint("/myWs")               //   监听连接
@Component
@Slf4j
@EnableScheduling
public class WsServerEndpoint {static Map<String, Session> sessionMap = new ConcurrentHashMap<>();//连接建立时 进行的操作//@OnOpen: 用于标记连接成功时执行的方法,将建立的 Session 对象存储在 sessionMap 中,并记录日志表示 WebSocket 已连接。@OnOpen             //    连接成功public void onOpen(Session session){sessionMap.put(session.getId(), session);log.info("websocket is open");}// 收到客户端消息时 进行的操作//@OnMessage: 用于标记接收到消息时执行的方法,打印收到的消息并返回一条确认消息。@OnMessage          //    收到消息状态public String OnMessage(String text){log.info("收到了一条消息:"+text);return "已收到你的消息";}// 连接关闭的时候 执行的操作//@OnClose: 用于标记连接关闭时执行的方法,从 sessionMap 中移除对应的 Session 对象,并记录日志表示 WebSocket 已关闭。@OnClosepublic void onClose(Session session){sessionMap.remove(session.getId());log.info("websocket is close");}// 服务端想给 客户端发送数据的话// ===》 定时任务实现     (每隔多少秒执行一次)//@Scheduled: 使用定时任务(通过 @Scheduled 注解)每隔两秒向所有的客户端发送一条消息。@Scheduled(fixedRate = 2000)public void sendMsg() throws IOException {for (String key:sessionMap.keySet()){sessionMap.get(key).getBasicRemote().sendText("心跳");}}
}

3.WebSocketConfig

/*** 定义了一个 Spring @Configuration 类,并且使用了 @Bean 注解向 Spring 容器注册了一个 ServerEndpointExporter 的实例** 这个 ServerEndpointExporter 实例是用于在 Spring Boot 中配置和注册 WebSocket 服务器端点的组件。*/
@Configuration
public class WebSocketConfig {// 将依赖包中的一些  依赖  注入为Bean@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

4.ws.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>ws client</title>
</head>
<body>
</body>
<!--通过 JavaScript 创建了一个 WebSocket 客户端连接到指定路径 "/myWs"(与服务器端点匹配)。当连接成功建立时,会发送一条消息 "hello,phdvb";同时当接收到消息时,将消息数据打印到控制台。-->
<script>let ws = new WebSocket("ws://localhost:8080/myWs")//当连接打开的时候   想服务端发送消息ws.onopen = function() {ws.send("hello,phdvb")}ws.onmessage = function(message) {console.log(message.data)}
</script>
</html>

实现效果

(二)方式二:通过Spring类+接口实现

3.基于websocket实现多人聊天室

  • 实现的功能
    • 进入聊天室
    • 群聊功能,任何人说话,所有人都能接收到提醒
    • 退出群聊

4.websocket的应用场景


解决怎样的经典问题?

Q: 由于Http协议,只能由浏览器向服务器发送请求,服务器无法直接向浏览器发送请求

        常见的提点方案:浏览器以轮询的方式向服务器发送请求

        轮询的缺陷:浪费带宽,实时性差,导致服务器压力较大


PC端二维码支付:

https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay
/chapter2_7_2.shtml

       

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是端口转发?路由器如何正确的设置端口转发和范围转发?(外网访问必备设置)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 端口转发 📒🚀 端口转发的应用场景💡 路由器如何设置端口转发(示例)💡 端口范围转发(示例)🎯 范围转发的应用场景🛠️ 设置范围转发📝 范围转发实操示例🎈 注意事项 🎈⚓️ 相关链接 ⚓️📖 介绍 📖 …

遗传算法求解车间调度问题(附python代码)

背景介绍 车间调度问题&#xff08;Job Shop Scheduling Problem, JSSP&#xff09;是一类经典的组合优化问题&#xff0c;它在制造业和生产管理中有着广泛的应用。JSSP 的目标是对车间中的一系列作业进行排程&#xff0c;以使得作业在不同机器上的加工顺序是最优的&#xff0…

什么是场外期权?场外期权有几种做法?

今天带你了解什么是场外期权&#xff1f;场外期权有几种做法&#xff1f;期权分为场内期权&#xff0c;场外期权。场内期权我们都知道&#xff0c;是在期货盘里购买的期权&#xff0c;但场外期权呢&#xff1f; 什么是场外期权&#xff1f; 场外期权是一种在交易所之外进行交易…

WinForm之TCP服务端

目录 一 原型 二 源码 一 原型 二 源码 using System.Net; using System.Net.Sockets; using System.Text;namespace TCP网络服务端通讯 {public partial class Form1 : Form{public Form1(){InitializeComponent();}TcpListener listener null;TcpClient handler null;Ne…

【Linux】从零开始配置新的服务器的机器学习环境

终端远程登录 ssh -p [端口号] [服务器用户名][服务器IP]或者 ssh [用户名][主机地址]第二种的前提是在.ssh\config中配置了host 安装文本编辑器vim 主要用于后续的文本编辑&#xff0c;个人比较习惯用vim&#xff0c;根据自己喜好选择 更新apt sudo apt update安装文本编辑…

陪诊小程序开发,陪诊师在线接单

近几年&#xff0c;陪诊师成为了一个新兴行业&#xff0c;在科技时代中&#xff0c;陪诊小程序作为互联网下的产物&#xff0c;为陪诊市场带来了更多的便利。 当下生活压力大&#xff0c;老龄化逐渐严重&#xff0c;年轻人很难做到陪同家属看病。此外&#xff0c;就诊中出现了…

【npm】安装报错(大多是版本冲突)

1.eslint版本太高&#xff0c;Vuex报错 我使用的是vue2.x&#xff0c;npm 安装Vuex3版本&#xff0c;控制台报错说eslint版本太高 解决办法&#xff1a;Vue2项目安装 vuex3 出现版本报错解决方法_安装 vuex3版本 eslint 报错-CSDN博客

在Lua解释器中注册自定义函数库

本文目录 1、引言2、注册原理3、实例4、程序验证 文章对应视频教程&#xff1a; 暂无&#xff0c;可以关注我的B站账号等待更新。 点击图片或链接访问我的B站主页~~~ 1、引言 在现代软件开发中&#xff0c;Lua因其轻量级、高效和可嵌入性而被广泛使用。作为一种灵活的脚本语言…

MyBatis使用 PageHelper 分页查询插件的详细配置

1. MyBatis使用 PageHelper 分页查询插件的详细配置 文章目录 1. MyBatis使用 PageHelper 分页查询插件的详细配置2. 准备工作3. 使用传统的 limit 关键字进行分页4. PageHelper 插件&#xff08;配置步骤&#xff09;4.1 第一步&#xff1a;引入依赖4.2 第二步&#xff1a;在m…

【SpringBoot整合系列】SpringBoot整合kinfe4j

目录 kinfe4j与Swagger的区别 SpringBoot2.x整合kinfe4j1.添加依赖2.启动类注解3.创建Knife4J配置类4.实体类5.接口admin访问 api访问 常用注解汇总SpringBoot3.x整合Kinfe4j启动报错解决1.更换依赖2.启动类3.配置4.配置类5.参数实体类6.接口admin访问 api访问 各版本注解参照 …

视频美颜工具技术探秘:直播美颜SDK的应用与发展

今天&#xff0c;笔者将深入探讨直播美颜SDK的应用场景和发展趋势&#xff0c;揭示其背后的技术奥秘和潜力。 一、直播美颜SDK的基本原理 直播美颜SDK其基本原理包括以下几个方面&#xff1a; 人脸检测与特征定位 肤色分析与调整 瑕疵修复与细节增强 滤镜和特效应用 二、…

【算法】Graham 凸包扫描算法 ( 凸包概念 | 常用的凸包算法 | 角排序 | 叉积 | Python 代码示例 )

文章目录 一、Graham 凸包扫描算法1、凸包概念2、常用的凸包算法3、Graham 凸包扫描算法 二、Graham 算法前置知识点1、角排序2、叉积3、算法过程分析 三、代码示例1、完整代码示例2、执行结果 使用 Graham 算法绘制的凸包效果 : 博客代码下载 : https://download.csdn.net/d…

算法刷题【二分法】

题目&#xff1a; 注意题目中说明了数据时非递减的&#xff0c;那么这样就存在二分性&#xff0c;能够实现logn的复杂度。二分法每次只能取寻找特定的某一个值&#xff0c;所以我们要分别求左端点和有端点。 分析第一组用例得到结果如下: 成功找到左端点8 由此可知&#xff0…

Spring Boot集成 Spring Retry 实现容错重试机制并附源码

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

verilog阻塞和非阻塞语法

阻塞和非阻塞是FPGA硬件编程中需要了解的一个概念,绝大部分时候,因为非阻塞的方式更加符合时序逻辑设计的思想,有利于时钟和信号的同步,更加有利于时序收敛,所以除非特殊情况,尽量采用非阻塞方式。 1,非阻塞代码 非阻塞赋值,A和B是同时被赋值的,具体是说在时钟的上升…

论文阅读:H-ViT,一种用于医学图像配准的层级化ViT

来自CVPR的一篇文章&#xff0c;https://openaccess.thecvf.com/content/CVPR2024/papers/Ghahremani_H-ViT_A_Hierarchical_Vision_Transformer_for_Deformable_Image_Registration_CVPR_2024_paper.pdf 用CNNTransformer混合模型做图像配准。可变形图像配准是一种在相同视场…

基于单片机的机械手臂控制系统设计

摘 要&#xff1a; 应用单片机 、 Arduino 及机械臂的有关知识&#xff0c;设计一款基于单片机的六自由度机械手臂&#xff0c;并详述其控制系统的软、 硬件设计 。 该机械手臂能够模仿人的上肢完成简单的动作&#xff0c;因此在实验教学演示平台 、 生产或生活中都极具应用价…

Dubbo 3.x源码(20)—Dubbo服务引用源码(3)

基于Dubbo 3.1&#xff0c;详细介绍了Dubbo服务的发布与引用的源码。 此前我们学习了调用createProxy方法&#xff0c;根据服务引用参数map创建服务接口代理引用对象的整体流程&#xff0c;我们知道会调用createInvokerForRemote方法创建远程引用Invoker&#xff0c;这是Dubbo …

Linux文件系统

目录 1.磁盘的结构 1.1磁盘的物理结构 1.2 磁盘的存储结构 1.3 磁盘的逻辑结构 2.文件系统 在上一篇文章基础IO中&#xff0c;我们主要是讲了被打开的文件与进程的关系&#xff0c;以及操作系统是如何管理这些被打开的文件的&#xff0c;但是磁盘有这么多文件&#xff0c;被打…

QT--DAY1

不使用图形化界面实现一个登陆界面 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {//设置窗口标题this->setWindowTitle("登录界面");//设置窗口大小this->resize(535,410);//固定窗口大小this->setFixedSize(535,410)…