Spring整合WebSocket
WebSocket , 干什么用的?我们有了HTTP , 为什么还要用WebSocket?很多同学都会有这样的疑问 。 我们先来看一个场景 , 大家的手机里都有微信 , 在微信中 , 只要有新的消息 , 这个联系人的前面就会有一个红点 , 这个需求要怎么实现呢?大家思考3秒钟 。 哈哈 , 最简单 , 最笨的方法就行客户端轮询 , 在微信的客户端每隔一段时间(比如:1s或者2s) , 向服务端发送一个请求 , 查询是否有新的消息 , 如果有消息就显示红点 。 这种方法是不是太笨了呢?每次都要客户端去发起请求 , 难道就不能从服务端发起请求吗?这样客户端不就省事了吗 。 再看看股票软件 , 每个股票的当前价格都是实时的 , 这我们怎么做 , 每个一秒请求后台查询当前股票的价格吗?这样效率也太低了吧 , 而且时效性也很低 。 这就需要我们今天的主角WebSocket去实现了 。
什么是WebSocketWebSocket协议 , RFC 6455这个大家有兴趣可以看看 , 太深 , 太底层 。 它是通过一个TCP连接 , 在客服端与服务端之间建立的一个全双工、双向的通信渠道 。 它是一个不同于HTTP的TCP协议 , 但是它通过HTTP工作 。 它的默认端口也是80和443 , 和HTTP是一样的 。
一个WebSocket的交互开始于一个HTTP请求 , 这是一个握手请求 , 这个请求中包含一个Upgrade请求头 , 具体如下:
GET /spring-websocket-portfolio/portfolio HTTP/1.1Host: localhost:8080Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==Sec-WebSocket-Protocol: v10.stomp, v11.stompSec-WebSocket-Version: 13Origin: http://localhost:8080
我们看到的第3行和第4行就是这个特殊的请求头 , 既然包含了这个特殊的请求头 , 那么请求就要升级 , 升级成WebSocket请求 。 这个握手请求的响应也比较特殊 , 它的成功状态码是101 , 而不是HTTP的200 , 如下:
HTTP/1.1 101 Switching Protocols Upgrade: websocketConnection: UpgradeSec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=Sec-WebSocket-Protocol: v10.stomp
在这次成功的握手请求以后 , 在客户端和服务端之间的socket被打开 , 客户端和服务端可以进行消息的发送和接收 。
程序实现我们还是使用现在流程的SpringBoot去搭建我们的项目 , 在项目中 , 我们添加两个依赖 , 如下:
- spring-boot-starter-websocket , 这是我们今天的主角 , 我们WebSocket的实现都依赖于这个jar包;
- spring-boot-starter-thymeleaf , 这只是起个辅助作用 , 在项目中要写个页面;
public class MyHandler extends TextWebSocketHandler {?@Overrideprotected void handleTextMessage(WebSocketSession session,TextMessage message) throws Exception {String payload = message.getPayload();System.out.println("我接收到的消息:"+payload);?String rtnMsg = "我回复了";?for (int i=0;i<10;i++) {Thread.sleep(2000);session.sendMessage(new TextMessage(rtnMsg+i));}super.handleTextMessage(session, message);}}
- 我们创建一个MyHandler类 , 继承TextWebSocketHandler类 , 这个类主要是处理文本的 , 当然也可以继承其他的类 , 比如:处理二进制的BinaryWebSocketHandler;
- 然后 , 我们实现handleTextMessage方法 , 这个方法有两个参数 , WebSocketSession和TextMessage , TextMessage是接收客户端发来的消息 。 WebSocketSession用于设置WebSocket会话和向客户端发送消息;
- 在具体的方法实现中 , 我们调用TextMessage的getPayload方法 , 可以取出客户端发送的消息;
- 最后我们通过WebSocketSession的sendMessage方法向客户端发送消息 , 这里进行10次循环 , 每次循环我们间隔2秒;
@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer {@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myHandler(),"/websocket");}?@Beanpublic MyHandler myHandler() {return new MyHandler();}}
- 首先 , 我们写一个WebSocket的配置类WebSocketConfig去实现WebSocketConfigurer接口;
- 由于这是一个配置类 , 所以在类上加上注解@Configuration , 同时因为要做WebSocket的配置 , 还要加上@EnableWebSocket这个注解;
- 这个类要实现注册WebSocketHandler的方法registerWebSocketHandlers , 在这里 , 我们将前面写的Handler映射到/websocket这个URL;
- 专注于扩展|Yearn整合Sushiswap,AC的“DeFi宇宙”已初露端倪
- 互联网|60亿引战整合重组互联网平台业务,苏宁易购能否弯道超车?
- Spring security CSRF 跨域访问限制问题
- 资源|共享门店系统如何整合商家周边资源助力获客引流?
- Spring Boot搭建的一个在线文件预览系统
- 面试官:问你一个,Spring事务是如何传播的?
- 对Spring MVC接口进行Mock测试
- Spring Cloud Alibaba之 Sentinel
- SpringBoot+MyBatis+MySQL读写分离实现
- SpringBoot构造流程源码分析:Web应用类型推断