WebSocket——相关介绍以及后端配置
一、WebSocket介绍:
WebSocket是一种在单个TCP连接上进行全双工通信的协议,旨在改进客户端和服务器之间的实时通信。以下是关于WebSocket的详细介绍:
1、定义与标准
- WebSocket是独立的、创建在TCP上的协议,通过HTTP/1.1协议的101状态码进行握手。
- WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。
2、工作原理
- WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
- 在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
3、特点
- 实时性:由于协议是全双工的,服务器可以随时主动给客户端下发数据,相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少。
- 较少的控制开销:在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。
- 保持连接状态:与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。
- 更好的二进制支持:Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
- 跨域支持:WebSocket协议可以跨域使用,允许不同源的客户端与服务器进行通信。
4、用途
WebSocket特别适合需要连续数据交换的服务,如网络游戏、实时交易系统、在线聊天应用、实时协作编辑、实时数据展示、在线游戏、实时地图应用、在线投票系统、实时监控系统以及实时消息推送等。
5、帧结构
WebSocket的通信以帧为单位进行,帧的结构包括RSV1、RSV2、RSV3(默认为0,仅当使用extension扩展时,有扩展决定其值)、opcode(帧的类型)、FIN(表示消息的结尾)以及消息长度等内容。
二、WebSocket后端配置:
step1:首先是依赖下载:
下面是一般项目的常用依赖:
<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.25</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.14.0</version></dependency><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.3.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>org.dom4j</groupId><artifactId>dom4j</artifactId><version>2.1.3</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.10</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web-services</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></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><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>3.0.3</version><scope>test</scope></dependency><dependency><groupId>org.assertj</groupId><artifactId>assertj-core</artifactId></dependency></dependencies>
step2:然后是定义配置类:
GetHttpSession:
package com.example.cqcrhouduan.config;import jakarta.servlet.http.HttpSession;
import jakarta.websocket.HandshakeResponse;
import jakarta.websocket.server.HandshakeRequest;
import jakarta.websocket.server.ServerEndpointConfig;public class GetHttpSession extends ServerEndpointConfig.Configurator {@Overridepublic void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response){// 获取httpSession对象HttpSession httpSession = (HttpSession) request.getHttpSession();// 将httpSession保存起来sec.getUserProperties().put(HttpSession.class.getName(),httpSession);}
}
WebsocketConfig:
package com.example.cqcrhouduan.config;import jakarta.websocket.server.ServerEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration
public class WebsocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}
}
step3:然后是定义相关工具和信息类:
Message:
package com.example.cqcrhouduan.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Message {private String toName;private String message;
}
MessageUtil:
package com.example.cqcrhouduan.pojo;import com.alibaba.fastjson.JSON;public class MessageUtil {public static String getMessage(boolean isSystemMessage,String fromName,Object message){ResultMessage result = new ResultMessage();result.setSystem(isSystemMessage);result.setMessage(message);if(fromName != null){result.setFormName(fromName);}return JSON.toJSONString(result);}
}
ChatEndPoint:
package com.example.cqcrhouduan.pojo;import com.alibaba.fastjson.JSON;
import com.example.cqcrhouduan.config.GetHttpSession;
import jakarta.servlet.http.HttpSession;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;@ServerEndpoint(value = "/chat",configurator = GetHttpSession.class)
@Component
public class ChatEndPoint {private static final Map<String,Session> onlineUser = new ConcurrentHashMap<>();private HttpSession httpSession;@OnOpenpublic void onOpen(Session session, EndpointConfig config){this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());String user = (String) this.httpSession.getAttribute("user");// 1、将session进行保存onlineUser.put(user,session);// 2、广播消息,将所有登录的用户推送给所有的用户String message = MessageUtil.getMessage(true,null,getFriends());broadcastAllUser(message);}private void broadcastAllUser(String Message){try{// 遍历map集合Set<Map.Entry<String,Session>> entries = onlineUser.entrySet();for(Map.Entry<String,Session> entry : entries){// 获取所有用户对应的session对象Session session = entry.getValue();session.getBasicRemote().sendText(Message);}}catch (Exception e){// 记录日志等等}}public Set getFriends(){Set<String> set = onlineUser.keySet();return set;}@OnMessagepublic void opMessage(String message){try{// 将消息推送给指定的用户:Message msg = JSON.parseObject(message,Message.class);//获取 消息接收方的名称String toNmae = msg.getToName();String mes = msg.getMessage();Session session = onlineUser.get(toNmae);String user = (String) this.httpSession.getAttribute("user");String mess = MessageUtil.getMessage(false,user,mes);session.getBasicRemote().sendText(mess);}catch (Exception e){// log}}@OnClosepublic void onClose(Session session){String user = (String) this.httpSession.getAttribute("user");// 1.从onlinesUser中剔除当前用户onlineUser.remove(user);// 2.通知其它所有的用户String message = MessageUtil.getMessage(true,null,getFriends());broadcastAllUser(message);}
}
ResultMessage:
package com.example.cqcrhouduan.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResultMessage {private boolean System;private String formName;private Object Message;
}
至此关于Socket利用session来获取信息的后端类的配置就全部完成了,后面将会继续提供前端的配置方法。<( ̄︶ ̄)>!
相关文章:

WebSocket——相关介绍以及后端配置
一、WebSocket介绍: WebSocket是一种在单个TCP连接上进行全双工通信的协议,旨在改进客户端和服务器之间的实时通信。以下是关于WebSocket的详细介绍: 1、定义与标准 WebSocket是独立的、创建在TCP上的协议,通过HTTP/1.1协议的10…...

单片机设计注意事项
1.电源线可以30mil走线,信号线可以6mil走线 2.LDO推荐 SGM2019-3.3,RT9013,RT9193,1117-3.3V。 3.单片机VCC要充分滤波后再供电,可以接0.1uf的电容 4.晶振附件不要走其他元件,且放置完单片机后就放置晶振,晶振靠近X1,X2。...

Ubuntu 如何根据NVIDIA显卡型号确定对应的显卡驱动版本并安装
目录 一、查询推荐安装的驱动版本 二、安装推荐版本的驱动 1. 通过终端安装,只安装 nvidia 驱动(亲测可用!) 2. 通过 software & Updates 安装,安装 nvidia 驱动。 三、查询能安装的最新的显卡驱动版本 1. 方…...

如何选择一款安全高效的数据自动同步工具?
随着科技的不断发展,企业处理的数据量愈发庞大。数字化浪潮的涌现使得数据在业务活动和决策中的角色变得日益重要,然而这些数据往往分布在不同的位置,需要进行同步和分类,以便更有效地利用。以下是一些常见的数据自动同步场景&…...

【linux】docker下nextcloud安装人脸识别插件
一、插件源码地址: GitCode - 开发者的代码家园 二、插件官网地址: Releases - Face Recognition - Apps - App Store - Nextcloud 三、插件安装教程: 1、查看本地nextcloud版本号 http://ipAddress:8080/settings/admin/overview 2、找…...

2. C++服务器编程-信号
什么是信号 其实信号就是一个中断。就是在执行程序的时候突然来了一个信号,然后我们去执行这个新来的程序了,这就是中断。 处理方法 信号的处理方式∶忽略、捕获、默认处理 linux中都有那些信号 man7 signal 比如说kill -9 安装man中文手册 自己百…...

C#_库的引用
类库的引用 还可以自己引用类库:解决方案-添加-新建项目 主程序 using System; using System.Windows.Forms; using Tools;namespace ConsoleApp2 {class Program{static void Main(string[] args){//Console.WriteLine("helloword");// Form form ne…...

C++:STL—算法
C:STL—算法 算法 算法 STL(Standard Template Library)中的算法是为了操作数据集合(如容器)而设计的函数模板集合,它们提供了丰富的功能和灵活的接口,可以用于对数据进行排序、查找、遍历等操作。STL中的…...

深入探索:移动云服务器的强大之处
文章目录 一 什么是移动云二 移动云服务器的使用三 移动云服务器的优点四 在移动云上部署node.js项目五 移动云服务器的应用场景六 移动云服务器的使用体验总结 一 什么是移动云 移动云是指用户可以通过移动设备访问云端的数据和应用,无需在本地设备上进行存储和处…...

线性表(从数据结构的三要素出发)
文章目录 逻辑结构存储结构顺序存储链式存储单链表双链表循环单链表循环双链表静态链表 数据的操作顺序结构链式结构单链表双链表 逻辑结构 线性表是具有相同数据类型的 n ( n ≥ 0 ) n(n≥0) n(n≥0)个数据元素的有限序列,其中 n n n为表长,当 n 0 n0…...

[SCTF2019]babyre
打开看看还是有花指令 解除后首先pass1是解maze,好像又是三维的 x是25,也就是向下跳五层,注意是立体的 得到 passwd1: ddwwxxssxaxwwaasasyywwdd 接着往下看 有一个加密函数IDA逆向常用宏定义_lodword-CSDN博客 unsigned __int64 __fastca…...

uniapp实现下拉过滤查询列表
<picker bindchange"bindPickerChanges" value"{{selectedIndex}}"range"{{pickerArray}}"range-key"name"><view class"area-select">在线状态:<label for"">{{pickerArray[select…...

C++—— set、map、multiset、multimap的介绍及使用
目录 关联式容器 关联式容器的特点和使用场景 树形结构与哈希结构 树形结构 哈希结构 键值对 set set的介绍 set的定义方式 set的使用 multiset map map的介绍 map的定义方式 map的使用 multimap 关联式容器 C标准模板库(STL)中的关联…...

STM32 学习——1. STM32最小系统
这是一个最小系统的测试,LED灯会进行闪烁。选用PC13口,因为STM32F103C8T6 硬件开发板中,这个端口是一个LED 1. proteus8.15 原理图 2. cubemx 新建工程 3. keil 代码 while (1){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);HAL_Delay(100);…...

react实现table可拖拽表头(给react-jss样式传递参数、滚动条样式)
目录 react实现table可拖拽表头安装依赖resizableTitle / index.tsxdrapTable.tsx使用DragTable 组件滚动条样式效果 react实现table可拖拽表头 安装依赖 yarn add react-resizable yarn add react-jssresizableTitle / index.tsx import { createUseStyles } from react-js…...

如何跨过robots协议的限制爬取内容?
在讨论如何“跨过robots协议的限制爬取内容”之前,重要的是强调遵循网络礼仪和法律法规的必要性。robots协议(Robots Exclusion Standard)是网站所有者向网络爬虫(包括搜索引擎和其他自动化工具)传达其爬取意愿的一种方…...

Parasoft C++Test软件静态分析操作指南_编码规范/标准检查
系列文章目录 Parasoft CTest软件安装指南 Parasoft CTest软件静态分析操作指南_编码规范/标准检查 Parasoft CTest软件静态分析操作指南_软件质量度量 Parasoft CTest软件静态分析_自动提取静态分析数据生成文档 Parasoft CTest软件单元测试_操作指南 Parasoft CTest软件单元…...

[AIGC] CompletableFuture如何实现任务链式调用?
Java 中的 CompletableFuture 提供了多种方法来支持任务链式调用。这些方法允许你将一组操作链接在一起,形成一个任务链,每一个任务只有在上一个任务成功完成后才会被执行。现在,我们来看一下一些常用的链接任务的方法: thenAppl…...

神奇动物在哪里?斯洛文尼亚旅游之野生动物寻踪
不仅拥有优美动人的自然风光,斯洛文尼亚还以其丰富的生物多样性而闻名。得益于国家对大自然开展的保护工作,斯洛文尼亚超过三分之一的国土面积都被规划为保护区,拥有约1.5万种动物和6000种植物,其中不乏众多特有、稀有和濒危动植物…...

电商项目之有趣的支付签名算法
文章目录 1 问题背景2 思路3 代码实现 1 问题背景 在发起支付的时候,一般都需要对发送的请求参数进行加密或者签名,下文简称这个过程为“签名”。行业内比较普遍的签发算法有: (1)按支付渠道给定的字段排序进行拼接&am…...

Web开发核心
文章目录 1.http协议简介2.http协议特性3.http请求和响应协议4.最简单的Web程序5.基于flask搭建web⽹站6.浏览器开发者⼯具(重点) 1.http协议简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于 万维网(WWW:Norld W…...

【Python】【Scrapy 爬虫】理解HTML和XPath
为了从网页中抽取信息,必须对其结构有更多了解。我们快速浏览HTML、HTML的树状表示,以及在网页上选取信息的一种方式XPath。 HTML、DOM树表示以及XPath 互联网是如何工作的? 当两台电脑需要通信的时候,你必须要连接他们ÿ…...

【CTF Web】CTFShow web5 Writeup(SQL注入+PHP+位运算)
web5 1 阿呆被老板狂骂一通,决定改掉自己大意的毛病,痛下杀手,修补漏洞。 解法 注意到: <!-- flag in id 1000 -->拦截很多种字符,连 select 也不给用了。 if(preg_match("/\|\"|or|\||\-|\\\|\/|\…...

LeetCode 968.监控二叉树 (hard)
968.监控二叉树 力扣题目链接(opens new window) 给定一个二叉树,我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计算监控树的所有节点所需的最小摄像头数量。 贪心思路: 从下往上看,局部最…...

数理逻辑:1、预备知识
17.1 命题和联结词 命题:可以判定真假的陈述句。(则悖论,祈使句,疑问句都不是命题) 原子命题:不能被分割为更小的命题的命题 例如: 2既是素数又是偶数 可以由$p: 2 是素数,…...

14-云原生监控体系-Redis_exporter 监控 MySQL[部署Dashborad告警规则实战]
文章目录 环境准备切片集群主从哨兵1. 部署1.1. 二进制方式1.1.1. 下载二进制包1.1.2. 部署1.2. docker-compose 容器方式1.3. 配置连接&认证参数1.3.1. 连接认证参数1.3.2. 配置服务控制 systemd2. 配置到 Prometheus3 Dashboard4. 告警规则...

DOS学习-目录与文件应用操作经典案例-xcopy
新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 一.前言 xcopy命令是DOS系统中一个强大的文件和目录复制工具&…...

Midjourney是一个基于GPT-3.5系列接口开发的免费AI机器人
Midjourney是一个基于GPT-3.5系列接口开发的免费AI机器人,旨在提供多领域的智能对话服务。Midjourney在不同领域中有不同的定义和应用,以下是对其中两个主要领域的介绍: Midjourney官网:https://www.midjourney.com/ 一、AI绘画工…...

v-model详解
目录 原理 作用 表单类组件封装 编辑v-model简化代码 原理 v-model本质上是一个语法糖。例如应用在输入框上,就是value属性和input属性的合写。 作用 提供数据的双向绑定。 数据变,视图跟着变:value视图变,数据跟着变input 注意&…...
ArcGIS中分割与按属性分割的区别
1、分割ArcGIS批量导出各个市的县级行政边界 视频教学: ArcGIS批量导出各个市的县级行政边界002 2、ArcGIS批量导出全国各省的边界 视频教学: ArcGIS导出全国各省的边界003 推荐学习: ArcGIS全系列实战视频教程——9个单一课程组合系列直播回…...