当前位置: 首页 > article >正文

WebSocket入门介绍及编程实战

HTTP的限制

全双工和半双工:
全双工:全双工(Full Duplex)是允许数据在两个方向上同时传输。
半双工:半双工(Half Duplex)是允许数据在两个方向上传输,但是同一个时间段内只允许一个方向上传输。

这里半双工我们可以类比我们熟知的HTTP协议,它的工作方式就是类似于半双工(但是,我们也应该明白,它还不如半双工呢!)。并且,它是只允许客户端主动请求,而服务器端被动响应,即所谓的请求响应模式。显然这种模式是有一种缺陷的,对于某些功能的实现是很麻烦的!
例如,如果需要在客户端上维持某个数据的实时性,那么该如何实现呢? 如果这个数据发生了改变,服务器并不能主动通知到客户端,因此需要客户端自己去服务器上拉取数据。但是请求一次,只能知道当前数据是否更新,如果数据早就更新了呢?因此需要客户端不断的请求服务器,询问数据是否改变,这种方式即称为轮询(通常是ajax轮询)。轮询是一种很低效的方式,并且它只是伪实时的,因为轮询需要间隔一定的时间,如果时间长了数据的实时性就低了,时间短了,服务器的压力也很大的(客户端也会有一定的压力)。这里的伪实时指的是假如轮询间隔时间为t,那么数据更新以后到客户端获取到数据的时间间隔即为0-t。

再举一个很常见的例子,如果开发web的话,有时候出了问题,我们通常会刷新一下,这就是HTTP协议的特性限制的,你不刷新的话,是无法得到响应的。

那么有什么解决办法呢? 既然有需求,一定会有解决办法的!如果你有Socket编程经验的话,应该知道只要连接建立以后,任何一端都可以同时向对方发送数据,这本身就是一种全双工的工作方式。

WebSocket

WebSocket的百度百科定义:

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

因此当一个WebSocket连接建立以后,通信的两端就可以以全双工的模式进行通信了。这样对于上面那种需要维持数据实时性的需求,就可以抛弃掉轮询这种方式,转而使用WebSocket解决,并且大大提高了实时性,而且只需要维持一个WebSocket连接即可,这样也减轻了网络压力。

上面这幅图很好的展示了AJAX轮询和WebSocket之间的区别,并且你可以发现WebSocket是需要使用HTTP去建立连接的,这一点很重要,因为待会的代码实战需要用到它!WebSocket是一个应用层协议,并且它是建立在TCP之上的,具体可以看下图即可知道它们的关系了。

WebSocket连接的建立及数据传输:
首先会发送一个HTTP报文,然后会响应一个HTTP报文,接下来会传输WebSocket协议的数据帧。可以这样来理解,HTTP是建立在TCP上的协议,HTTP协议本身是TCP的数据部分(首部+实体),然后WebSocket是和HTTP平级的另一种应用层协议,它的协议数据帧部分也是TCP的数据部分。

SpringBoot整合WebSocket

1.添加WebSocket依赖:在pom.xml文件中添加以下依赖:

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

2.配置WebSocket:创建一个配置类WebSocketConfig并实现WebSocketConfigurer接口,用于配置WebSocket。在这个类中,你需要注册一个ServerEndpointExporter Bean,这样Spring Boot才能扫描到WebSocket的注解。

@Configuration  
@EnableWebSocket  
public class WebSocketConfig implements WebSocketConfigurer {  
  
    @Override  
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {  
        registry.addHandler(myHandler(), "/my-websocket-endpoint");  
    }  
  
    @Bean  
    public MyHandler myHandler() {  
        return new MyHandler();  
    }  
}

3.创建WebSocket处理器:创建一个处理器类MyHandler并实现WebSocketHandler接口,这个类将处理WebSocket的连接、消息和错误事件。在这个类中,你可以根据需要添加业务逻辑。

import org.springframework.web.socket.TextMessage;  
import org.springframework.web.socket.WebSocketSession;  
import org.springframework.web.socket.handler.TextWebSocketHandler;  
  
public class MyHandler extends TextWebSocketHandler {  
  
    @Override  
    public void handleTextMessage(WebSocketSession session, TextMessage message) {  
        // 处理接收到的消息  
        System.out.println("Received message: " + message.getPayload());  
        // 发送回复消息  
        session.sendMessage(new TextMessage("Hello, " + message.getPayload() + "!"));  
    }  
}

4.创建客户端连接:在前端代码中创建一个WebSocket客户端并连接到服务器。你可以使用原生的JavaScript WebSocket API或者使用第三方库如SockJS和StompJS。

以下是一个使用原生JavaScript的示例:

const socket = new WebSocket('ws://localhost:8080/my-websocket-endpoint');  
socket.addEventListener('open', (event) => {  
    socket.send('Hello Server!');  
});  
socket.addEventListener('message', (event) => {  
    console.log('Received message: ', event.data);  
});

5.测试WebSocket连接:启动Spring Boot应用并访问前端页面,你应该能看到WebSocket连接成功并建立双向通信。

websocket小案例


http://www.kler.cn/a/156982.html

相关文章:

  • 【Qt】在 Qt Creator 中使用图片资源方法(含素材网站推荐)
  • 【Python TensorFlow】进阶指南(续篇一)
  • window下安装rust 及 vscode配置
  • F5全新报告揭示AI时代API安全面临严峻挑战
  • 三种单例实现
  • 深入了解Git、GitHub、GitLab及其应用技巧
  • 【23-24 秋学期】NNDL 作业11 LSTM
  • 使用com组件编辑word
  • Nacos与Eureka的区别
  • 【COCI2011-2012#5】 EKO / 砍树
  • Mybatis总结
  • C++11改进单例模式
  • CMMI认证有什么意义
  • GPIO的使用--操作PF09 PF10 PF08实现呼吸灯、跑马灯、警报闪烁灯
  • 开源CDN软件GoEdge —— 筑梦之路
  • 马斯克没继续的工作,我帮他继续下去
  • [蓝桥杯 2019 省 B] 特别数的和-C语言的解法
  • Anaconda和Python关系详解和使用选择
  • Educational Codeforces Round 159(div2) --- E. Collapsing Strings-- 题解
  • Redis数据库
  • 卷麻了,00后测试用例写的比我还好,简直无地自容......
  • spring日志输出到elasticsearch
  • 【有机化学(药学类)】醛和酮3
  • 刷题系列——排序算法
  • Python面向对象③:封装【侯小啾Python基础领航计划 系列(二十一)】
  • 5.【自动驾驶与机器人中的SLAM技术】2D点云的scan matching算法 和 检测退化场景的思路