湛江网站建设招聘/一站式快速网站排名多少钱
文章目录
- 前言
- websockt
- 什么是websockt?
- websockt和Socket区别
- 代码部分
- 实战应用
前言
websockt
什么是websockt?
WebSocket是一种在Web应用程序中实现实时双向通信的技术。Web应用程序通常是基于HTTP协议的,HTTP是一种请求/响应式的协议,客户端发起请求,服务器响应请求并发送响应,客户端收到响应后关闭连接。这意味着,如果客户端需要不断地从服务器获取更新,它必须定期发送请求以检查更新,这将导致大量的网络流量和不必要的服务器负载。
WebSocket通过在客户端和服务器之间创建持久化连接,允许双向实时通信。这意味着服务器可以主动向客户端推送更新,而不必等待客户端不停地请求。WebSocket连接始于HTTP握手,然后升级到WebSocket协议。在升级过程中,客户端和服务器之间的数据传输方式从HTTP变成了WebSocket协议,这样可以降低传输数据的延迟和提高传输数据的可靠性。
在WebSocket协议中,数据是以帧的形式传输的,帧包括数据头和数据体两个部分。数据头指示数据类型,数据传输的方向等信息,数据体则包括实际传输的数据。WebSocket支持文本类型和二进制类型的数据。文本类型的数据使用UTF-8编码,而二进制类型的数据可以包括任何二进制数据,如图像、音频、视频等。
WebSockets是非常适合实时通信的技术。它可以用于在线游戏、在线聊天、推送通知、实时监控等,并且比传统的轮询技术更加高效和可靠。对于现代Web应用程序而言,WebSockets已经成为不可或缺的技术之一。
websockt和Socket区别
区别 | WebSocket | Socket |
---|---|---|
应用层协议 | 基于HTTP协议,升级为WebSocket协议 | 没有明确的应用层协议,常用于传输TCP或UDP数据 |
传输数据类型 | 支持文本和二进制类型的数据 | 通常用于传输二进制数据,如图片、视频等 |
客户端和服务器通信 | 支持实时双向通信 | 支持双向通信,但通常需要进行轮询或长连接 |
传输效率 | 比传统的轮询技术更加高效和可靠,不会频繁请求服务器 | 传输效率较低,需要进行轮询或者长连接来保持连接,会频繁请求服务器 |
应用场景 | 适用于实时通信,如在线游戏、在线聊天、推送通知、实时监控等 | 适用于需要传输大量二进制数据的场景,如文件传输、图片处理等 |
代码部分
引入maven依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
说明:默认版本为1.5.10RELEASE,可自定义版本,加入“<version">"”标签即可
常量类
package com.dmsdbj.itoo.utils;
public class Constant {//webSocket相关配置//链接地址public static String WEBSOCKETPATHPERFIX = "/ws-push";public static String WEBSOCKETPATH = "/endpointWisely";//消息代理路径public static String WEBSOCKETBROADCASTPATH = "/topic";//前端发送给服务端请求地址public static final String FORETOSERVERPATH = "/welcome";//服务端生产地址,客户端订阅此地址以接收服务端生产的消息public static final String PRODUCERPATH = "/topic/getResponse";//点对点消息推送地址前缀public static final String P2PPUSHBASEPATH = "/user";//点对点消息推送地址后缀,最后的地址为/user/用户识别码/msgpublic static final String P2PPUSHPATH = "/msg";
}
接收前端消息实体
package com.dmsdbj.itoo.vo;
public class WiselyMessage {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
后台发送消息实体
package com.dmsdbj.itoo.vo;public class WiselyResponse {private String responseMessage;public WiselyResponse(String responseMessage){this.responseMessage = responseMessage;}public String getResponseMessage() {return responseMessage;}public void setResponseMessage(String responseMessage) {this.responseMessage = responseMessage;}
}
配置websocket
package com.dmsdbj.itoo.config;import com.dmsdbj.itoo.utils.Constant;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
// @EnableWebSocketMessageBroker注解用于开启使用STOMP协议来传输基于代理(MessageBroker)的消息,这时候控制器(controller)
// 开始支持@MessageMapping,就像是使用@requestMapping一样。
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {@Overridepublic void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {//注册一个Stomp的节点(endpoint),并指定使用SockJS协议。stompEndpointRegistry.addEndpoint(Constant.WEBSOCKETPATH).withSockJS();}@Overridepublic void configureMessageBroker(MessageBrokerRegistry registry) {//服务端发送消息给客户端的域,多个用逗号隔开registry.enableSimpleBroker(Constant.WEBSOCKETBROADCASTPATH, Constant.P2PPUSHBASEPATH);//定义一对一推送的时候前缀registry.setUserDestinationPrefix(Constant.P2PPUSHBASEPATH);//定义websoket前缀registry.setApplicationDestinationPrefixes(Constant.WEBSOCKETPATHPERFIX);}
}
采用JPA方法进行操作数据库DAO层
package com.dmsdbj.itoo.repository;
import com.dmsdbj.itoo.entity.TbUser;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TbUseRepository extends JpaRepository<TbUser,Long> {}
sql语句
CREATE TABLE `tb_user` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`username` varchar(50) DEFAULT NULL COMMENT '用户名',`password` varchar(32) DEFAULT NULL COMMENT '密码,加密存储',`phone` varchar(20) DEFAULT NULL COMMENT '注册手机号',`email` varchar(50) DEFAULT NULL COMMENT '注册邮箱',`created` datetime DEFAULT NULL,`updated` datetime DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `username` (`username`) USING BTREE,UNIQUE KEY `phone` (`phone`) USING BTREE,UNIQUE KEY `email` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=18333611875 DEFAULT CHARSET=utf8 COMMENT='用户表';
TbUser实体类
package com.dmsdbj.itoo.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.io.Serializable;
@Entity
@Data
public class TbUser implements Serializable {@Idprivate Long id;private String username;private String password;private String phone;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}
}
Service实现类
@Service
public class TbUseServiceImpl implements TbUseService {@AutowiredTbUseRepository repository;/*** 从数据库查询用户,给订阅者发送消息* @return*/@Overridepublic List<Long> send2Users() {return repository.findAll().stream().map(s -> s.getId()).collect(Collectors.toList());}
}
Service接口类
public interface TbUseService {List<Long> send2Users();
}
Façade实现类
@Service
public class TbUseFacadeImpl implements TbUseFacade {@AutowiredTbUseService tbUseService;@Overridepublic List<Long> send2Users() {return tbUseService.send2Users();}
}
Façade接口类
public interface TbUseFacade {
List<Long> send2Users();
}
Controller类
@Controller
public class SendInfoController {@ReferenceTbUseFacade tbUseFacade;@Autowiredprivate SimpMessagingTemplate template;@ResourceWebSocketService webSocketService;@MessageMapping(Constant.FORETOSERVERPATH)//@MessageMapping和@RequestMapping功能类似,用于设置URL映射地址,浏览器向服务器发起请求,需要通过该地址。
// @SendTo(Constant.PRODUCERPATH)//如果服务器接受到了消息,就会对订阅了@SendTo括号中的地址传送消息。public WiselyResponse say(WiselyMessage message) throws Exception {List<Long> userId = tbUseFacade.send2Users();userId.forEach(s->{template.convertAndSendToUser(s.toString(),Constant.P2PPUSHPATH, new WiselyResponse(message.getName()));});return null;}
}
前端页面
sendws.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8" /><title>Spring Boot+WebSocket+广播式</title></head>
<body onload="disconnect()">
<noscript><h2 style="color: #ff0000">貌似你的浏览器不支持websocket</h2></noscript>
<div><div><button id="connect" onclick="connect();">连接</button><button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button></div><div id="conversationDiv"><label>输入要发送的消息</label><input type="text" id="name" /><button id="sendName" onclick="sendName();">发送</button><p id="response"></p><p id="response1"></p></div>
</div>
<!--<script th:src="@{sockjs.min.js}"></script>
<script th:src="@{stomp.min.js}"></script>
<script th:src="@{jquery.js}"></script>-->
<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script th:inline="javascript">var stompClient = null;//此值有服务端传递给前端,实现方式没有要求//var userId = [[${userId}]];var userId = 'd892bf12bf7d11e793b69c5c8e6f60fb';function setConnected(connected) {document.getElementById('connect').disabled = connected;document.getElementById('disconnect').disabled = !connected;document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';$('#response').html();}function connect() {var socket = new SockJS('/endpointWisely'); //1连接SockJS的endpoint是“endpointWisely”,与后台代码中注册的endpoint要一样。stompClient = Stomp.over(socket);//2创建STOMP协议的webSocket客户端。stompClient.connect({}, function(frame) {//3连接webSocket的服务端。setConnected(true);console.log('开始进行连接Connected: ' + frame);});}function disconnect() {if (stompClient != null) {stompClient.disconnect();}setConnected(false);console.log("Disconnected");}function sendName() {var name = $('#name').val();console.log(name);//通过stompClient.send()向地址为"/welcome"的服务器地址发起请求,与@MessageMapping里的地址对应。因为我们配置了registry.setApplicationDestinationPrefixes(Constant.WEBSOCKETPATHPERFIX);所以需要增加前缀/ws-push/stompClient.send("/ws-push/welcome", {}, JSON.stringify({ 'name': name }));}
</script>
</body>
</html>
subws.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8" /><title>Spring Boot+WebSocket+广播式</title></head>
<body onload="disconnect()">
<noscript><h2 style="color: #ff0000">貌似你的浏览器不支持websocket</h2></noscript>
<div><div><button id="connect" onclick="connect();">连接</button><button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button></div><div id="conversationDiv"><label>输入你的userId</label><input type="text" id="userId" /><button id="subMsg" onclick="subMsg();">订阅消息</button><p id="response"></p><p id="response1"></p></div>
</div>
<!--<script th:src="@{sockjs.min.js}"></script>
<script th:src="@{stomp.min.js}"></script>
<script th:src="@{jquery.js}"></script>-->
<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script th:inline="javascript">var stompClient = null;//此值有服务端传递给前端,实现方式没有要求//var userId = [[${userId}]];function setConnected(connected) {document.getElementById('connect').disabled = connected;document.getElementById('disconnect').disabled = !connected;document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';$('#response').html();}function connect() {var socket = new SockJS('/endpointWisely'); //1连接SockJS的endpoint是“endpointWisely”,与后台代码中注册的endpoint要一样。stompClient = Stomp.over(socket);//2创建STOMP协议的webSocket客户端。stompClient.connect({}, function(frame) {//3连接webSocket的服务端。setConnected(true);console.log('开始进行连接Connected: ' + frame);//4通过stompClient.subscribe()订阅服务器的目标是'/topic/getResponse'发送过来的地址,与@SendTo中的地址对应。/*stompClient.subscribe('/topic/getResponse', function(respnose){showResponse(JSON.parse(respnose.body).responseMessage);});*/});}function subMsg() {var userId = $('#userId').val();console.log(userId);$.ajax({type: 'GET',url: '/user/insert?userId='+userId,//data: userId,success: function (data) {console.log(data);//4通过stompClient.subscribe()订阅服务器的目标是'/user/' + userId + '/msg'接收一对一的推送消息,其中userId由服务端传递过来,用于表示唯一的用户,通过此值将消息精确推送给一个用户stompClient.subscribe('/user/' + userId + '/msg', function(respnose){console.log(respnose);showResponse1(JSON.parse(respnose.body).responseMessage);});}});}function disconnect() {if (stompClient != null) {stompClient.disconnect();}setConnected(false);console.log("Disconnected");}function showResponse1(message) {var response = $("#response1");response.html(message);}
</script>
</body>
</html>
实战应用
①启动springboot-dubbo-service的主启动类“SpringbootDubboServiceApplication”
②启动springboot-dubbo-web的主启动类“SpringbootDubboWebApplication”
③访问
http://localhost:9000/sendws 发送消息方
http://localhost:9000/subws 订阅消息方
④分别进行连接操作
订阅方输入订阅方的连接账号userid,后期就可以接收发送端发送的消息
连接后的结果展示
相关文章:

SpringBoot整合websockt实现消息对话
文章目录 前言websockt什么是websockt?websockt和Socket区别代码部分实战应用 前言 websockt 什么是websockt? WebSocket是一种在Web应用程序中实现实时双向通信的技术。Web应用程序通常是基于HTTP协议的,HTTP是一种请求/响应式的协议&…...

MIME类型(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型)MultipartFile 多媒体文件上传
目录 MIME媒体类型介绍MediaTypes 有哪些MultipartFile 类介绍MultipartFile 类 接收的文件是二进制嘛代码举例 上传的文件 实现接口 MultipartFile 类有哪些最终调用接口的方法时,会有哪个类实现 如何决定哪个类去实现呢 Spring 会根据运行环境自动选择合适的实现类…...

数据库(MySQL)的存储过程
一、存储过程介绍 存储过程是事先经过编译并存储在数据库中的一段SQL 语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。 存储过程思想上很简单࿰…...

Flutter:getX的学习
前言 学习教程:Getx教程_FlutterGetx系列实战教程 简介 getX是第三方的状态管理插件,不仅具有状态管理的功能,还具有路由管理、主题管理、国际化多语言管理、网络请求、数据验证等功能。相比其他状态管理组件,getX简单、功能强大…...

leetcode - 360周赛
一,2833. 距离原点最远的点 这道题的意思是,遇到 "L" 向左走,遇到 "R" 向右走,遇到 "_" 左右都可以走,那么要想找到距离原点最远的点,就是在找 | "L" "R&qu…...

Android 1.1 背景相关与系统架构分析
目录 1.1 背景相关与系统架构分析 分类 Android 基础入门教程 1.Android背景与当前的状况 2.Android系统特性与平台架构 系统特性: 平台架构图: 架构的简单理解: 3.本节小结: 1.1 背景相关与系统架构分析 分类 Android 基础…...

系统架构技能之设计模式-抽象工厂模式
一、上篇回顾 上篇我们主要讲述了简单工厂模式和工厂模式。并且分析了每种模式的应用场景和一些优缺点,我们现在来回顾一下: 简单工厂模式:一个工厂负责所有类型对象的创建,不支持无缝的新增新的类型对象的创建。 工厂模式&…...

clangd的使用,实现跳转提示
一、插件卸载c插件下载clangd 二、设置搜索clangd --compile-commands-dirbuild文件中compile_commands的绝对路径若没有找到compile_commands.json文件可以通过如下方式之后再便于即可生成 cmake项目: 在项目最顶层的.cmake文件中或者CMakeList文件中加入如下命令…...

2023应届生java面试搞笑之一:CAS口误说成开心锁-笑坏面试官
源于:XX网,如果冒犯,表示歉意 面试官:什么是CAS 我:这个简单,开心锁 面试官:WTF? 我:一脸自信,对,就是这个 面试官:哈哈大笑ÿ…...

nginx-concat
为了减少tcp请求数量,nginx从上有服务器获取多个静态资源(css,js)的时候,将多个静态资源合并成一个返回给客户端。 这种前面有两个问号的请求都是用了cancat合并功能。 先到官网下载安装包,拷贝到服务器编译…...
Java 大厂面试 —— 常见集合篇 List HashMap 红黑树
23Java面试专题 八股文面试全套真题(含大厂高频面试真题)多线程_软工菜鸡的博客-CSDN博客 常见集合篇-01-集合面试题-课程介绍 02-算法复杂度分析 2 List相关面试题 2.1 数组 2.1.1 数组概述 数组(Array)是一种用连续的内存空…...

剪枝基础与实战(5): 剪枝代码详解
对模型进行剪枝,我们只对有参数的层进行剪枝,我们基于BatchNorm2d对通道重要度 γ \gamma γ参数进行稀释训练。对BatchNorm2d及它的前后层也需要进行剪枝。主要针对有参数的层:Conv2d、BatchNorm2d、Linear。但是我们不会对Pool2d 层进行剪枝,因为Pool2d只用来做下采样,没…...

Acwing 897. 最长公共子序列 (每日一题)
最长公共子序列 题目描述 给定两个长度分别为 N 和 M 的字符串 A 和 B,求既是 A 的子序列又是 B 的子序列的字符串长度最长是多少。 输入格式 第一行包含两个整数 N和 M。 第二行包含一个长度为 N 的字符串,表示字符串 A。 第三行包含一个长度为 M …...

CSS中border-radius的来美化table的实战方案
border-radius是一种CSS属性,用于设置元素的边框的圆角程度。其具体的用法如下: 设置一个值:可以为元素设置一个单一的圆角半径,这个半径将应用于元素的四个角。例如: div {border-radius: 10px; }设置四个值&#x…...

移除链表元素_每日一题
“路虽远,行则将至” ❤️主页:小赛毛 ☕今日份刷题:移除链表元素 题目描述: 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 示例1&…...

spring boot + Consul 示例 (Kotlin版)
文章目录 1.docker 安装consul2.创建基于springboot的client2.1 依赖版本2.2 pom.xml2.3 启动类2.4 application.properties 3 搭建完成4. 总结 1.docker 安装consul docker-compose.yaml version: "3"services:consul:image: consul:1.4.4container_name: consule…...

Git企业开发控制理论和实操-从入门到深入(四)|Git的远程操作|Gitee
前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…...

SpringCloudAlibaba Gateway(二)详解-内置Predicate、Filter及自定义Predicate、Filter
Predicate(断言) Predicate(断言),用于进行判断,如果返回为真,才会路由到具体服务。SpirnngCloudGateway由路由断言工厂实现,直接配置即生效,当然也支持自定义路由断言工厂。 内置路由断言工厂实现 SpringClo…...

调用chat-gpt
调用chat-gpt 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifact…...

Element组件浅尝辄止6:Dialog 对话框组件
Dialog 对话框组件:在保留当前页面状态的情况下,告知用户并承载相关操作。 大白话就是弹窗组件,日常开发中比较常见 1.怎样使用? //触发方式 <el-button type"text" click"dialogVisible true">打开&…...

Bert和LSTM:情绪分类中的表现
一、说明 这篇文章的目的是评估和比较 2 种深度学习算法(BERT 和 LSTM)在情感分析中进行二元分类的性能。评估将侧重于两个关键指标:准确性(衡量整体分类性能)和训练时间(评估每种算法的效率)。…...

【面试经典150题】跳跃游戏
题目链接 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 1 < nums…...

【Rust】003-基础语法:流程控制
【Rust】003-基础语法:流程控制 文章目录 【Rust】003-基础语法:流程控制一、概述二、if 表达式1、语法格式2、多个3、获取表达式的值 三、循环1、loop:无限循环,可跳出无限循环跳出循环返回值 2、while:条件循环&…...

0829【综述】面向时空数据的区块链研究综述
摘要:时空数据包括时间和空间2个维度,常被应用于物流、供应链等领域。传统的集中式存储方式虽然具有一定的便捷性,但不能充分满足时空数据存储及查询等要求,而区块链技术采用去中心化的分布式存储机制,并通过共识协议来保证数据的安全性。研究现有区块链1.0、2.0和以Block-DAG为…...

MySQL高级篇(SQL优化、索引优化、锁机制、主从复制)
目录 0 存储引擎介绍1 SQL性能分析2 常见通用的JOIN查询 SQL执行加载顺序七种JOIN写法3 索引介绍 3.1 索引是什么3.2 索引优劣势3.3 索引分类和建索引命令语句3.4 索引结构与检索原理3.5 哪些情况适合建索引3.6 哪些情况不适合建索引4 性能分析 4.1 性能分析前提知识4.2 Expla…...

YOLOV8模型使用-检测-物体追踪
这个最新的物体检测模型,很厉害的样子,还有物体追踪的功能。 有官方的Python代码,直接上手试试就好,至于理论,有想研究在看论文了╮(╯_╰)╭ 简单介绍 YOLOv8 中可用的模型 YOLOv8 模型的每个类别中有五个模型用于检…...

springmvc:设置后端响应给前端的json数据转换成String格式
设置spring-mvc.xml: xml <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:context"http://www.springframework.org/schema/context"xmlns:xsi"http://www.w…...

Mac安装brew、mysql、redis
mac安装brew mac安装brewmac安装mysql并配置开机启动mac安装redis并配置开机启动 mac安装brew 第一步:执行. /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"第二步:输入开机密码 第三…...

MLC-LLM 部署RWKV World系列模型实战(3B模型Mac M2解码可达26tokens/s)
0x0. 前言 我的 ChatRWKV 学习笔记和使用指南 这篇文章是学习RWKV的第一步,然后学习了一下之后决定自己应该做一些什么。所以就在RWKV社区看到了这个将RWKV World系列模型通过MLC-LLM部署在各种硬件平台的需求,然后我就开始了解MLC-LLM的编译部署流程和…...

Unity 之 参数类型之值类型参数的用法
文章目录 基本数据类型结构体结构体的进一步补充 总结: 当谈论值类型参数时,我们可以从基本数据类型和结构体两个方面详细解释。值类型参数指的是以值的形式传递给函数或方法的数据,而不是引用。 基本数据类型 基本数据类型的值类型参数&…...