【后端】websocket学习笔记

文章目录

  • 1. 消息推送常见方式
    • 1.1 轮询 VS 长轮询
    • 1.2 SSE(server-sent event)服务器发送事件
  • 2. websocket介绍
    • 2.1 介绍
    • 2.2 原理
    • 2.3 websoket API
      • 2.3.1 客户端【浏览器】API
      • 2.3.2 服务端API
  • 3. 代码实现
    • 3.1 流程分析
    • 3.2 pom依赖
    • 3.3 配置类
    • 3.4 消息格式
    • 3.5 消息类
  • 4. 前端代码(非视频源码)

参考视频
【后端&网络&大数据&数据库目录贴】

1. 消息推送常见方式

  • 轮询
  • 长轮询
  • websocket
  • SSE

1.1 轮询 VS 长轮询

在这里插入图片描述

1.2 SSE(server-sent event)服务器发送事件

  • SSE在服务器和客户端之间打开一个单向通道
  • 服务端响应的不再是一次性的数据包,而是text/event-stream类型的数据流信息
  • 服务器有数据变更时将数据流式传输到客户端
    在这里插入图片描述

2. websocket介绍

2.1 介绍

websocket是一种基于TCP链接上进行全双工通信的协议

  • 全双工:允许数据在两个方向上同时传输。(TCP是全双工,HTTP是基于TCP的)
  • 半双工:允许数据在两个方向上传输,但是同一个时间段内只允许一个方向上传输。
    在这里插入图片描述

2.2 原理

在这里插入图片描述

  • ws://localhost?chat 依然是http协议
  • Connection:UpgradeUpgrade: websocket表明连接升级
  • 响应码 101说明已经切换成功

2.3 websoket API

2.3.1 客户端【浏览器】API

  • websocket对象创建
let ws=new WebSocket(URL);
  • websocket对象相关事件
    在这里插入图片描述
  • websocket对象提供的方法
    在这里插入图片描述

2.3.2 服务端API

在这里插入图片描述

  • 服务端如何接收客户端发送的数据呢?
    在这里插入图片描述
  • 服务端如何推送数据给客户端呢?
    在这里插入图片描述

3. 代码实现

3.1 流程分析

在这里插入图片描述

3.2 pom依赖

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

3.3 配置类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4 消息格式

在这里插入图片描述

3.5 消息类

@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfigurator.class)
@Component
public class ChatEndpoint {public static final Map<String, Session> sessionsMap = new ConcurrentHashMap<>();private HttpSession httpSession;/*** 建立websocket连接后,被调用** @param session*/@OnOpenpublic void onOpen(Session session, EndpointConfig config) {//1.将session进行保存this.httpSession = (HttpSession) config.getUserProperties().get("httpSession");String userName = (String) httpSession.getAttribute("userName");ChatEndpoint.sessionsMap.put(userName, session);//2. 广播消息,需要将登录的所有的用户推送给所有用户String sendMessage = MessageUtil.sendMessage(true, null, userName + "上线");boardcast(sendMessage);}/*** 广播消息*/private void boardcast(String message) {// 遍历 map 集合Set<Map.Entry<String, Session>> entries = ChatEndpoint.sessionsMap.entrySet();for (Map.Entry<String, Session> entry : entries) {Session session = entry.getValue();try {session.getBasicRemote().sendText(message);} catch (IOException e) {// 记录日志}}}@OnMessagepublic void onMessage(String message) {try {String fromName = (String) this.httpSession.getAttribute("userName");// 将消息推送给指定的用户   message : {"toName":"张三","message":"你好"}ClientMessage clientMessage = JSON.parseObject(message, ClientMessage.class);Session session = ChatEndpoint.sessionsMap.get(clientMessage.getToName());String sendMessage = MessageUtil.sendMessage(false, fromName, clientMessage.getMessage());session.getBasicRemote().sendText(sendMessage);} catch (IOException e) {throw new RuntimeException(e);}}/*** 当websocket连接断开时,此方法会被处罚*/@OnClosepublic void onClose(Session session) {
// 从在线用户集合中剔除断开连接的用户String userName = (String) this.httpSession.getAttribute("userName");ChatEndpoint.sessionsMap.remove(userName);// 通知其他用户当前用户下线String sendMessage = MessageUtil.sendMessage(true, null, userName + "上线");boardcast(sendMessage);}
}

4. 前端代码(非视频源码)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="js/jquery.min.js"></script>
</head>
<body>
<p>【fromUserId】:<div><input id="userId" name="userId" type="text" value="10"></div>
<p>【toUserId】:<div><input id="toUserId" name="toUserId" type="text" value="20"></div>
<p>【发送的消息】:<div><input id="contentText" name="contentText" type="text" value="hello websocket"></div>
<p>【收到的内容】:<div><textarea id="receText"></textarea></div><button id="openSocket">开启socket</button><button id="sendMessage">发送消息</button><button id="closeWs">关闭连接</button>
<script>$(function (){console.log('加兹阿勒')const urlParams = new URLSearchParams(window.location.search);console.log(urlParams)var fromUserId = urlParams.get('fromUserId');$('#userId').val(fromUserId)})var ws ;function openSocket() {if(typeof(WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");}else{console.log("您的浏览器支持WebSocket");//实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接//等同于socket = new WebSocket("ws://localhost:8888/xxxx/im/25");//var socketUrl="${request.contextPath}/im/"+$("#userId").val();var socketUrl="http://localhost:8081/chat";socketUrl=socketUrl.replace("https","wss").replace("http","ws");console.log(socketUrl);if(ws !=null){ws .close();ws =null;}ws = new WebSocket(socketUrl);// 当 WebSocket 成功建立连接时触发ws.onopen  = function(event) {console.log("WebSocket is connected now.");// 在这里你可以发送一些初始消息到服务器// ws.send("Hello, Server!");};// 当接收到来自服务器的消息时触发ws.onmessage = function(event) {console.log("Received data from server: " + event.data);// 处理从服务器接收到的数据var parse = JSON.parse(event.data);$('#receText').val(parse.message);};// 当 WebSocket 连接关闭时触发ws.onclose = function(event) {if (event.wasClean) {console.log("WebSocket connection closed cleanly, code=" + event.code + " reason=" + event.reason);} else {// 例如,服务器进程被终止而关闭console.log("WebSocket connection died");}};// 当 WebSocket 连接出现错误时触发ws.onerror = function(error) {console.error("WebSocket Error: " + error);};}}function sendMessage() {if(typeof(WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");}else {console.log("您的浏览器支持WebSocket");console.log('{"toUserId":"'+$("#toUserId").val()+'","contentText":"'+$("#contentText").val()+'"}');ws.send('{"toName":"'+$("#toUserId").val()+'","message":"'+$("#contentText").val()+'"}');}}function closeWs(){ws.close();}$("#openSocket").on('click', openSocket);$("#sendMessage").on('click',sendMessage);$("#closeWs").on('click', closeWs);
</script>
</body>
</html>

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

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

相关文章

Weevil-Optimizer象鼻虫优化算法的matlab仿真实现

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 Weevil-Optimizer象鼻虫优化算法的matlab仿真实现&#xff0c;仿真输出算法的优化收敛曲线&#xff0c;对比不同的适应度函数。 2.测试软件版本以及运行结果展示…

Linux - 进程

一、什么是进程 首先&#xff0c;Linux是一个多用户多进程的操作系统&#xff0c;系统上可以同时运行多个进程。 进程的产生&#xff1a;①是在执行程序或者命令时产生的&#xff1b;②定时任务进程 进程的类型&#xff1a;前台进程/后台进程 前台进程&#xff1a;一个终端…

WDC西部数据闪存业务救赎之路,会成功吗?

一、序言 在存储界的江湖里&#xff0c;WDC就像是一位手握两大秘籍&#xff08;闪迪和铠侠NAND工厂&#xff09;的武林高手&#xff0c;本以为能在企业级SSD的擂台上大展身手&#xff0c;结果却发现自己更像是被误邀参加学霸聚会的学渣&#xff0c;心里那个苦啊&#xff0c;只…

Java15-API

目录 Math类 概述 常见方法 练习 System类 概述 常见方法 Runtime 概述 常见方法 Object类 概述 常见方法 一.演示toString方法 二.演示equals方法 三、对象克隆 分类&#xff1a; 浅克隆 深克隆&#xff1a; Objests类 概述 常见方法 BigInteger类 概…

jenkins安装和使用 (二)

参考视频资料 https://www.bilibili.com/video/BV1bS4y1471A?p10&vd_sourcee0dcd147bd5d730317de804d788cd6f9 安装maven插件 新建item 配置构建信息 项目地址替换为自己的实际地址 其余保持先保持默认 先然后在主页就看到了这个项目 查看控制台输出 稍等一…

李宏毅2023机器学习作业HW06解析和代码分享

ML2023Spring - HW6 相关信息&#xff1a; 课程主页 课程视频 Sample code HW06 视频 HW06 PDF 个人完整代码分享: GitHub | Gitee | GitCode P.S. HW06 是在 Judgeboi 上提交的&#xff0c;出于学习目的这里会自定义两个度量的函数&#xff0c;不用深究&#xff0c;遵循 Sugge…

【计算机毕业设计】211校园约拍微信小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

网工内推 | 中国电信、香港宽频系统工程师,CCIE认证优先,最高年薪25w

01 中国电信股份有限公司浙江分公司 &#x1f537;招聘岗位&#xff1a;系统架构师 &#x1f537;岗位职责&#xff1a; 1、做好客户网络和信息安全产品的解决方案支撑、交付及后续运营维护&#xff0c;做好相关产数项目的支撑。 2、根据信息安全管理要求&#xff0c;负责客户…

调取Windows系统虚拟键盘

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 using System.Diagnostics;namespace 调取Windows虚拟键盘 {public partial class Form1 : Form{public Form1(){InitializeComponent();}private void richTextBox1_DoubleClick(object sender, EventArgs e){Proces…

Cloudflare API 令牌完整指南:快速掌握查询与创建(手把手教你查询和创建 Cloudflare API 令牌)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 Cloudflare API 令牌 📒📝 查询 Cloudflare API 令牌📝 创建编辑区域 DNS 令牌⚓️ 相关链接 ⚓️📖 介绍 📖 在管理网站和应用程序时,Cloudflare 提供了强大的 API 接口,可以极大地简化各种操作。本文将详细介绍如…

Debian12安装Nvidia官方驱动

1、下载驱动&#xff08;下载到一个英文目录例如你的用户目录/home/用户名下&#xff0c;我下载到dowload目录&#xff0c;由于默认显示中文&#xff0c;在命令行不支持中文显示的是一串数字&#xff0c;当然你仍然可以cd 那串数字进目录&#xff0c;显示有有引号就加引号&…

【宠粉赠书】科技图表绘制:R语言数据可视化

为了回馈粉丝们的厚爱&#xff0c;今天小智给大家送上一套科研绘图的必备书籍——《R语言数据可视化&#xff1a;科技图表绘制》。下面我会详细给大家介绍这套图书&#xff0c;文末留有领取方式。 图书介绍 《R语言数据可视化&#xff1a;科技图表绘制》结合编者多年的数据分析…

PLC模拟量和数字量到底有什么区别?

PLC模拟量和数字量的区别 在工业自动化领域&#xff0c;可编程逻辑控制器&#xff08;PLC&#xff09;是控制各种机械设备和生产过程的核心组件。PLC通过处理模拟量和数字量来实现对工业过程的精确控制。了解模拟量和数字量的区别对于设计高效、可靠的自动化系统至关重要。 1. …

C++之STL(二三)

1、vector源码刨析 1.1、数据结构以及动态扩充算法 其实vector内部有三个指针&#xff0c;分别是数据的第一个元素Myfirst、数据的最后一个元素的下一个位置Mylast&#xff0c;最后一个空间的下一个位置Myend&#xff1b;当你插入数据的时候&#xff0c;先判断当前容量够不够&…

尚品汇项目2

p68 加入产品个数操作 p69 加入购物车

立讯精密:“果链一哥”怎么摆脱依赖症

AI手机创新赋能&#xff0c;隔岸苹果股价走出历史新高&#xff0c;消费电子有望迎来复苏&#xff1f; 这里我们聊聊苹果产业链代工龙头——立讯精密 作为早早入场的代工企业&#xff0c;立讯精密曾经吃足“果链”红利&#xff0c;如今摆在它面前的是增长、毛利、安全等难题。 …

人工智能—美国加利福尼亚州房价预测实战

引言 在当今快速发展的房地产市场中&#xff0c;房价预测已成为一个至关重要的领域。它不仅关系到投资者的决策&#xff0c;也直接影响到普通购房者的生活质量。特别是在美国加利福尼亚州&#xff0c;这个以其高房价和房地产市场的波动性而闻名的地方&#xff0c;准确的房价预…

TF-IDF、BM25传统算法总结

1. TF-IDF算法 F-IDF&#xff08;词频-逆文档频率&#xff09;是一种用于衡量文本中词语重要性的方法&#xff0c;特别适用于信息检索和文本挖掘任务。下面会拆分为两部分深入讲解TF-IDF的计算过程&#xff0c;以便更好地理解。 TF-IDF的计算过程可以分为两个主要部分&#xf…

【漏洞复现】契约锁电子签章平台 add 远程命令执行漏洞(XVE-2023-23720)

0x01 产品简介 契约锁电子签章平台是上海亘岩网络科技有限公司推出的一套数字签章解决方案。契约锁为中大型组织提供“数字身份、电子签章、印章管控以及数据存证服务”于一体的数字可信基础解决方案,可无缝集成各类系统,让其具有电子化签署的能力,实现组织全程数字化办公。通…

03 - matlab m_map地学绘图工具基础函数 - 设置坐标系(m_coord)

03 - matlab m_map地学绘图工具基础函数 - 设置坐标系&#xff08;m_coord&#xff09; 0. 引言1. m_proj使用方法2. 结语 0. 引言 上一篇介绍了m_proj函数用于初始化投影&#xff0c;本篇介绍的函数m_coord用于初始化地理坐标系或地磁坐标系&#xff0c;地理/地磁坐标系和投影…