Spring Boot实战之基于WebSocket协议构建交互式Web应用
本文阅读时间大约8分钟。
1. WebSocket简介
WebSocekt协议诞生于2008年,在2011年成为国际标准,目前所有的浏览器都已经支持WebSocket协议了。WebSocket协议属于服务器推送技术的一种,它最大的特点就是可以实现服务端和客户端的双向通信。
WebSocket协议和HTTP协议一样,也是在TCP协议层之上的应用层协议,刚接触WebSocket协议的人通常会有个疑问:都有HTTP这个应用层协议了,为啥还要再搞出一个WebSocket协议?
事实上,HTTP是无状态的,并且只能支持单向通信,即都是浏览器向服务端发送HTTP请求,然后得到一个响应。
在实际应用中,还有另外一种场景:服务端有数据更新的时候,希望客户端能够及时感知到。针对这种场景,在WebSocket出现之前,只能采用长轮询的方案(如下图所示)——客户端通过一个AJAX请求和定时器进行轮询查询;这样的方案在服务端数据变化比较频繁的时候,是比较适合使用的,但是当服务端数据变化不频繁的时候,就会面临一个两难的选择:轮询间隔时间短了,会增加服务端的负担,轮询得时间间隔长了,又不能及时感知到服务端数据的变化。
WebSocket协议的出现就是为了解决上面这个两难问题的,可以弥补长轮询方案的不足,使用WebSocket协议的方案的时序图如下图所示,浏览器和服务端之间会建立一个WebSocket连接,基于这个连接客户端可以给服务端发送信息,服务端也可以给客户端发送信息,如果服务端的数据变更不频繁,或者客户端对数据感知的时效性要求不高,就比较适合使用WebSocket这种方案。
2. Spring Boot实战
下面我们会使用Spring Boot中的Websocket支持组件,实现一个交互式的Web应用程序,演示下WebSocket协议的工作过程。
2.1 服务端
1. 新建一个Spring Boot工程,在pom中加入下面的依赖:
Spring Boot Maven插件提供了很多方便的特性:
将classpath下的Jar包打包成一个独立的可以运行的Jar包,方便应用的交付和部署;
搜索所有的类,将含有main方法的那个类标记为运行入口类;
内置了一个依赖解析器,可以自动选择跟当前的Spring Boot版本适配的版本号
2. 创建请求和响应的消息类,分别是:HelloMessage.java和Greeting.java,代码如下所示:
3. 接下来增加Spring配置,开启WebSocket和STOMP消息的支持,具体的WebSocketConfig
代码如下所示:
@Configuration
注解表示WebSocketConfig
是一个Spring配置类;@EnableWebSocketMessageBroker
注解用来启动Spring的WebSocket消息处理代理;configureMessageBroker()
方法用来配置消息代理的一些特性,通过调用enableSiampleBroker()
方法,启动一个基于内存的消息代理,该消息代理会将打招呼的消息广播给那些订阅了“/topic”卡头的客户端;setApplicationDestinationPrefixes()
方法用来跟@MessageMapping
注解一起起作用,这个注解指定的是服务端接口的前缀,整体下来,greeting()
方法对应的请求路径是"/app/hello"。registerStompEndpoints()
方法用来注册"/gs-guide-websocket"端点,使得SockJS客户端在不支持WebSocket协议的时候,可以选择其他的传输协议连接服务端,例如:xhr-streaming、xhr-polling等等。
4. 创建基于ws协议的消息处理Controller类,在Spring中,我们计划使用STOMP协议来演示ws协议的应用,STOMP协议并不是为websocket设计的,它属于消息队列的一种协议,和AMQP、 JMS是一个层面的东西,只不过由于它的简单性恰巧可以用于定义websocket的消息体格式。
@MessageMapping
注解的作用类似于Spring MVC中的@RequestMapping
,表示greeting()
方法可以处理发往“/hello”的消息;greeting()
方法的参数是HelloMessage类,消息的内容会被转换成HelloMessage对象,这个方法的内部会先休眠1秒——模拟服务端的处理过程,然后给客户端返回一个消息响应对象(Greeting对象);@SendTo
注解表示:消息的响应使用的是广播模式,greeting()
方法返回的消息,会发送给所有订阅了“/topic/greetings”的订阅者
2.2 客户端
前面准备好了服务端代码,接下来我们需要开发一个JS客户端,用来跟服务端进行双向通信。
1. 创建客户端界面,这里非常简单,就一个index.html文件,在这个文件的开头,引入了SOCKJS
和STOMP
两个JS库,用来跟服务端进行通信。
2. 编写客户端逻辑,创建一个JS文件——app.js,代码如下所示,其中最需要关注的是connect()
方法和sendName()
方法。
connect()
方法利用SOCKJS
和stomp.js
访问服务端的"/gs-guide-websocket"端点来建立连接,如果建连成功,客户单就会订阅主题“/topic/greetings”——服务端会将返回的消息广播发送到该主题;如果该主题收到了消息,那么客户端会调用showGreeting()
方法,在浏览器上渲染出它收到的消息内容;sendName()
方法用来接收用户的输入,并利用STOMP客户端将用户输入的内容发送到服务端——"/app/hello",相应地,该请求会被服务端的GreetingController.greeting()
方法处理。
最后,前后端的代码架构如下图所示
2.3 运行演示
1. 通过WebsocketdemoApplication.main()
启动应用程序,启动过程如下:
2. 打开两个浏览器页面,都访问localhost:8080
,分别点击Connect按钮,将这两个客户端都跟服务端建立连接,如下图所示:
3. 在任意一个客户端中发送消息,延迟一会,可以看到两个客户端页面都看到了服务端返回的消息——这就是前文说的广播模式。
3. 总结
本文首先介绍了WebSocket的定义,然后比较了HTTP协议和WebSocket协议的异同点,并且针对实际应用中的服务端-客户端数据同步的场景进行了不同方案的分析和讨论,分别讨论了长轮询方案和基于WebSocket协议的方案的优劣点;最后利用Spring Boot提供的组件,实现了一个简单的交互应用,用来展示WebSocket协议的实际应用和效果。
4. 参考资料
http://www.ruanyifeng.com/blog/2017/05/websocket.html
https://www.fullstackpython.com/websockets.html
https://spring.io/guides/gs/messaging-stomp-websocket/
《Spring Boot实战》
往期精选
Spring Boot实战之定时任务调度
Spring Boot实战之业务状态机
跟着阿杜拆书:《慢思考》
Mac高效开发之iTerm2、Prezto和Solarized主题
本号专注于后端技术、JVM问题排查和优化、Java面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。
Spring Boot实战之基于WebSocket协议构建交互式Web应用相关推荐
- 【Spring boot 实战】使用Maven插件构建Docker镜像
本文主要介绍如何使用Maven插件将SpringBoot应用打包为Docker镜像,并上传到私有镜像仓库Docker Registry的过程. 使用Maven构建本地Docker镜像 我们以项目spr ...
- 程序猿最终之路-架构师:Spring boot实战战役解析
什么是架构师 所谓架构师,通俗地说就是设计师或结构设计者,这些定义如果用在建筑学上,则是很容易理解的.在软件工程领域中,软件架构师实际上就是软件项目的总体设计师,是软件组织新产品的开发与集成.新技术体 ...
- 最新Spring Boot实战项目(权限后台管理系统)详解
Spring Boot实战项目 - 权限后台管理系统 简介 这是一套基于spring boot 2.16.shiro.jwt.redis.swagger2.mybatis .thymeleaf.lay ...
- 视频教程-spring cloud与spring boot实战视频教程-Java
spring cloud与spring boot实战视频教程 从事互联网开发架构11年,曾在阿里任职java架构师,擅长SOA.分布式搜索的架构设计; 精于JVM.TCP.CPU.缓存.磁盘.网络等大 ...
- JavaEE开发的颠覆者 Spring Boot实战
网站 更多书籍点击进入>> CiCi岛 下载 电子版仅供预览及学习交流使用,下载后请24小时内删除,支持正版,喜欢的请购买正版书籍 电子书下载(皮皮云盘-点击"普通下载" ...
- spring boot 实战 / 可执行war启动参数详解
概述 上一篇文章<spring boot 实战 / mvn spring-boot:run 参数详解>主要讲解了spring boot 项目基于maven插件启动过程中借助profil ...
- Spring Boot实战系列《六》:人事管理系统的登录设计
Spring Boot实战系列<六>:人事管理系统的登录设计 Spring Boot实战系列<六>:人事管理系统的登录设计 1.前言 在上一篇中教大家在IEDA或者eclips ...
- 《Spring Boot实战》读书笔记
2019独角兽企业重金招聘Python工程师标准>>> 一. 读后感 Spring Boot在技术圈火了好多年了,直到最近才去系统学习它,真是相见恨晚.当我在IDE编写几行代码就把W ...
- 视频教程-Spring Boot实战入门视频课程-Java
Spring Boot实战入门视频课程 国内上市大型医疗软件公司产品研发部总经理,技术培训总监.6年以上大型项目一线开发.架构.管理经验,曾主导医疗大数据+移动BI产品设计与研发.技术狂热爱好者,擅长 ...
最新文章
- linux root ssh 安全,linux ssh安全加固方法
- [Java基础]为什么会出现字符流?与编码表介绍
- linux数组操作 增删改查,linuxea:go数组与数组增删改查(19)
- MSSQL优化之————探索MSSQL执行计划
- 阿里腾讯前端一面小结
- 来学习几个简单的Hive函数啦
- python3 x和python2 x区别_Python3.x和Python2.x的区别(转存参考)
- 马斯克刚骂了激光雷达,这篇用纯视觉代替激光雷达的名校论文「力挺」了他...
- 2022年春运火车票明起开卖
- python列表功能默写_python基础学习——列表list的功能
- HttpClient4 TIME_WAIT和CLOSE_WAIT
- Eclipse(ADT)找不到android.support.v4.view.ViewPager,2步搞定!
- 苹果mac幻灯片演示文稿制作软件:PowerPoint 2019
- 【前端开发】:行间距和首行缩进
- 【Java基础】Java综合练习
- 类ku6未注册域名分享
- 梯度下降和正规方程的区别
- 英语句子成分和词类的关系
- LatentFusion:End-to-End Differentiable Reconstruction and Rendering for Unseen Object Pose Estimatio
- 西游之路——python全栈——通用模块(pager、check_code、form验证)
热门文章
- 站长之家最新备案域名信息爬取
- 计算机系的学ansys吗,学ansys软件需要什么样的电脑配置才能运行?
- 【SIM卡】补充省下一些其他的SIM相关问题
- 专项训练——数量关系题
- 他把闲鱼APP长列表流畅度翻了倍(良心教程)
- 亚马逊广告点击率如何才能提高?
- 苹果内存其他怎么清理_这才是清理苹果手机内存的方法,清理后流畅好几倍,太好用了...
- SI模型下传染病模型的参数估计以及图像显示
- VirtualBox虚拟机启动爆出:fatal:No bootable medium found! System halted的错误
- 基于php学生学籍管理系统获取(php毕业设计)