http、socket以及websocket的区别(websocket使用举例)
一、http、socket、websocket介绍
1、HTTP(Hypertext Transfer Protocol):HTTP是一种应用层协议,用于在客户端和服务器之间传输超文本数据。它是基于请求-响应模型的,通过发送HTTP请求从服务器获取数据,并通过HTTP响应返回数据给客户端。HTTP是无状态的,每个请求和响应都是独立的,不保留状态信息。
2、Socket:Socket是一种底层的网络通信协议,用于实现进程间的通信。它提供了一种机制,使得应用程序能够通过网络进行数据传输。Socket通常用于实现客户端和服务器之间的双向通信,可以在两个终端之间建立持久连接,允许数据的双向流动。
3、WebSocket:WebSocket是一种基于TCP的全双工通信协议,它在HTTP基础上扩展而来。与HTTP不同,WebSocket允许服务器主动向客户端推送数据,而不需要客户端发起请求。WebSocket连接一旦建立,就可以保持长时间的双向通信,类似于Socket连接,但更加灵活和容易使用。
主要的区别:
HTTP是一种请求-响应协议,每个请求对应一个响应。而Socket和WebSocket是基于TCP的通信协议,支持全双工通信,允许实时的双向数据传输。
HTTP是无状态的协议,每个请求和响应都是独立的,不保留状态信息。而Socket和WebSocket可以保持连接状态,并允许在连接上持续传输数据。
HTTP通常用于客户端通过发送请求从服务器获取数据。Socket和WebSocket通常用于建立客户端和服务器之间的双向通信,支持实时的消息传递。
WebSocket是在HTTP协议基础上的扩展,使用了握手的方式建立连接,在连接建立后,双方可以随时互相发送消息。而HTTP和Socket需要在每次通信前先建立连接。
总结来说,HTTP适用于一次性请求和响应的场景,Socket适用于需要长时间、双向通信的场景,而WebSocket适用于实时通信、推送消息的场景。
二、工作流程
websocket的工作流程:
- 客户端通过向服务器发送 WebSocket 升级请求来启动连接,通常是通过 HTTP 连接。升级请求包含一个特殊的标头,表明客户端想要升级到 WebSocket 通信。
- 服务器响应升级请求,状态码为101,表示连接已成功升级为WebSocket通信。
- 从这一点开始,连接以全双工模式运行,这意味着客户端和服务器都可以随时向对方发送数据。WebSocket 协议提供了一种基于消息的通信模型,其中数据作为消息传输,而不是作为字节流传输。
- 消息使用紧凑的二进制格式传输,这比传统 HTTP 或 TCP 使用的基于文本的格式更有效。WebSocket 协议提供了一种机制,可以自动将大消息分成较小的数据包,并在另一端将数据包重新组合成原始消息。
- WebSocket 连接一直保持打开状态,直到客户端或服务器决定关闭它。关闭连接是一个简单的两步过程,包括发送关闭消息,然后等待另一端确认关闭消息。
socket工作流程: - 初始化:客户端和服务器应用程序各自创建一个套接字并将其绑定到特定的端口号。端口号用于标识网络上的应用程序。
- 连接建立:客户端通过向服务器的IP地址和端口号发送请求来建立与服务器的连接。服务器接受连接并为客户端创建一个新套接字。
- 数据交换:一旦建立连接,客户端和服务器就可以使用套接字相互交换数据。数据以数据包的形式发送,数据包是通过网络传输的小数据单元。
- 优雅关闭:当客户端和服务器完成交换数据时,它们通过向另一方发送消息以指示它们正在关闭连接来优雅地关闭连接。
- 终止:连接关闭后,客户端和服务器可以终止各自的套接字。
三、websocket代码实现
1、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、后端实现
2.1创建 WebSocketConfig 配置类,注入 websocket 服务
/**
* 开启WebSocket支持
**/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
2.2新建WebSocketServer服务端:WebSocket.java
/**
* @Description :
* @Date : 2023/7/17
* @Author :
*/
@ServerEndpoint(value = "/websocket/{userId}")
@Slf4j
@Component
@Data
public class WebSocket {
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
*/
private static ConcurrentHashMap<String, Session> webSocketSet = new ConcurrentHashMap<>();
//指定的sid,具有唯一性
private static String sid = "";
/**
* 连接建立成功调用的方法
*
* @param session 会话
*/
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) throws Exception {
sid = userId;
webSocketSet.put(sid, session); //加入set中
log.info("【websocket消息】有新的连接,总数为:" + webSocketSet.size());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) throws IOException {
log.info("参数信息:{}", message);
//群发消息
try {
log.info("【收到】,客户端{}的信息:{}", session, message);
} catch (Exception e) {
e.printStackTrace();
log.info("参数有误");
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session) {
webSocketSet.remove(this);
if (session != null) {
try {
session.close();
log.info("【websocket消息】关闭了一个连接,总数为:" + webSocketSet.size());
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 发生错误时调用
*
* @param session 会话
* @param error 错误信息
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("连接异常!");
error.printStackTrace();
}
/**
* 发送信息
*
* @param message 消息
*/
public void sendMessage(String message,String userId) throws IOException {
// 防止频繁断连问题引发的报错: The WebSocket session [3d] has been closed and no method (apart from close()) may be called on a closed session
Session session = webSocketSet.get(userId);
if (session.isOpen()) {
session.getBasicRemote().sendText(message);
}
}
/**
* 自定义消息推送、可群发、单发
*
* @param message 消息
*/
public boolean sendAllInfo(String message, List<String> userIds) {
log.info("给用户" + userIds.toString() + "发送消息:" + message);
if (CollectionUtils.isEmpty(userIds)){return false;}
for (String userId:userIds){
try {
sendMessage(message,userId);
return true;
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
}
注:@ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端。注解的值将被用于监听用户连接的终端访问URL地址。
onOpen 和 onClose 方法分别被@OnOpen和@OnClose 所注解。这两个注解的作用不言自明:他们定义了当一个新用户连接和断开的时候所调用的方法。
onMessage 方法被@OnMessage所注解。这个注解定义了当服务器接收到客户端发送的消息时所调用的方法。
2.3 测试controller类
@Resource
private WebSocket socketService;
@PostMapping("/test/socket")
public void testSocket(String msg){
try {
int i = 0;
while (true){
i++;
socketService.sendMessage("ces","1");
if (i == 100){
log.info("i到一百了");
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
3、前端实现
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<button onclick="send()">发送消息</button>
</body>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
</script>
<script>
var websocket = null;
//判断浏览器是否支持websocket
if('WebSocket' in window) {
//实现化WebSocket对象
websocket = new WebSocket("ws://localhost:8088/websocket/1");
} else {
alert('该浏览器不支持websocket')
}
//打开事件
websocket.onopen = function(event) {
console.log('建立连接');
}
//关闭事件
websocket.onclose = function(event) {
console.log("连接关闭");
}
//获得消息事件
websocket.onmessage = function(event) {
console.log("收到消息:" + event.data);
}
//发生了错误事件
websocket.onerror = function(event) {
console.log("websocket 通信发生错误");
}
window.onbeforeunload = function(event) {
websocket.close();
}
//发送消息
function send() {
$.ajax({
type: "post",
url: "http://localhost:8088/test/socket",
data: {
msg: "23"
},
dataType: "json",
async: false,
success: function(data) {
console.log(data);
},
error: function(e) {
console.log(e);
}
});
}
</script>
</html>
请求的时候出现跨域问题,解决,在后端加配置类
/**
* AJAX请求跨域
* @author Mr.W
* @time 2018-08-13
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry){
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedHeaders(CorsConfiguration.ALL)
.allowedMethods(CorsConfiguration.ALL)
.allowCredentials(true)
.maxAge(3600);
}
}
http、socket以及websocket的区别(websocket使用举例)的更多相关文章
- python中socket、socketio、flask-socketio、WebSocket的区别与联系
socket.socketio.flask-socketio.WebSocket的区别与联系 socket 是通信的基础,并不是一个协议,Socket是应用层与TCP/IP协议族通信的中间软件抽象层, ...
- 网络编程WebSocket 和socket、HTTP的区别和联系
一.WebSocket 是什么? WebSocket是HTML5规范提出的一种协议:目前除了完犊子的IE浏览器,其他浏览器都基本支持.他是一种协议,万变不离其宗,也是基于TCP协议的:和HTTP协议是 ...
- 谈一谈Tomcat中webSocket,Jetty WebSocket 和Spring WebSocket以及github中Java-WebSocket.jar分别对Socket协议的角色定位以及效果的不同点;
开局先上一张图:(http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html) 当前截图来自于apache的tomcat官网(问:为 ...
- HTTP 和 WebSocket的区别
有关http和WebSocket 的区别网上有很多的质料. 个人在此仅仅是记录以下自己的学习心得,自己的理解. 1. http协议是用在应用层的协议,他是基于tcp协议的,http协议建立链接也必须要 ...
- 小白需要了解的Ajax和websocket的区别以及使用场景!
在我们日常使用的互联网产品中,很多都是前后端数据的交互来完成的,说到数据交互就不得不提Ajax和websocket,它们可是数据交互的利器,那么它们分别是什么?websocket与Ajax轮询的区别又 ...
- WebSocket --为什么引入WebSocket协议
Browser已经支持http协议,为什么还要开发一种新的WebSocket协议呢?我们知道http协议是一种单向的网络协议,在建立连接后,它只允许Browser/UA(UserAgent)向WebS ...
- websocket之一:websocket简介
Websocket websocket为一次HTTP握手后,后续通讯为tcp协议的通讯方式. WebSocket 使用一种被称作“Upgrade handshake(升级握手)”的机制将标准的 HTT ...
- 一步一步学WebSocket (一) 初识WebSocket
众所周知,Http协议是无状态的,并且是基于Request/Response的方式与服务器进行交互,也就是我们常说的单工模式.但是随着互联网的发展,浏览器与服务端进行双向通信需求的增加,长轮询向服务器 ...
- python全栈开发day115、116-websocket、websocket原理、websocket加解密、简单问答机器人实现
1.websocket 1.websocket 与轮询 轮询: 不断向服务器发起询问,服务器还不断的回复 浪费带宽,浪费前后端资源 保证数据的实时性 长轮询: 1.客户端向服务器发起消息,服务端轮询, ...
- websocket之四:WebSocket 的鉴权授权方案
引子 WebSocket 是个好东西,为我们提供了便捷且实时的通讯能力.然而,对于 WebSocket 客户端的鉴权,协议的 RFC 是这么说的: This protocol doesn’t pres ...
随机推荐
- Python自动化测试面试题精选(一)
Python自动化测试面试题精选 今天由勇哥给你介绍一些Python自动化测试中常见的面试题,涵盖了Python基础.测试框架.测试工具.测试方法等方面的内容,希望能够帮助你提升自己的水平和信心. 项 ...
- JavaWeb编程面试题——MyBatis
引言 面试题==知识点,这里所记录的面试题并不针对于面试者,而是将这些面试题作为技能知识点来看待.不以刷题进大厂为目的,而是以学习为目的.这里的知识点会持续更新,目录也会随时进行调整. 关注公众号:编 ...
- Neo4J 图库的集群部署与基础使用
Ned4J 图库的集群部署与基础使用 部署机器 名称 配置 IP server1 8 核 16G 172.16.0.2 server2 8 核 16G 172.16.0.3 server3 8 核 1 ...
- 前端Vue自定义服务说明弹窗弹框 自下而上底部弹框
前端Vue自定义服务说明弹窗弹框 自下而上底部弹框, 请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13108 效果图如下: cc-serv ...
- 基于生成式预训练Transformer的跨语言文本摘要与情感分析
目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 3. 实现步骤与流程 3.1 准备工作:环境配置与依赖安装 3.2 核心模块实现 3.3 集成 ...
- 使用 Transformers 为多语种语音识别任务微调 Whisper 模型
本文提供了一个使用 Hugging Face Transformers 在任意多语种语音识别 (ASR) 数据集上微调 Whisper 的分步指南.同时,我们还深入解释了 Whisper 模型.Com ...
- 基于词袋(Bag of Words)和SVM的图片分类
目录 摘要 源码及完整报告: 词袋(Bag of Words, BoW) 基于词袋模型的图片分类基本流程 多尺度空间极值点检测 关键点精确定位 关键点主方向计算 生成描述子 特征词典的生成 SVM分类 ...
- Visual Studio C# 多环境配置 Web.config
目录 添加解决方案配置 添加配置转换 添加应对的配置 Visual Studio 为多环境配置 Web.config 不同的环境,存在不同的配置,如:数据库连接字符串,通过多配置,方便做环境切换,配置 ...
- RabbitMQ 中 exchange、route、queue 的关系
从 AMQP 协议可以看出,MessageQueue.Exchange 和 Binding 构成了 AMQP 协议的核心,下面我们就围绕这三个主要组件 从应用使用的角度全面的介绍如何利用 Rabbit ...
- CS144 LAB0~LAB4
CS144: LAB0 0.写在前面 这更倾向于个人完成 lab 后的思考和总结,而不是 CS144 lab 答案或者 lab document 翻译(指南或者翻译已经有大佬做的很好了,下面已经贴出链 ...