赞
踩
目录
2.1.3、实现 WebSocketConfigurer 接口
基于 WebSocket、Spring Boot 下,用一个简易的小 demo 讲解一下“QQ聊天”功能原理~
用户看到的实际效果:用户A 给用户B 发送了一条消息,用户B在聊天框看到了消息,接着用户B回复消息......
底层实现:主机A 给服务器发送了一个 HTTP 请求,这个请求中就包含了用户A 要给用户B 发送的消息,服务器将收到的请求进行解析,在将响应发送给 主机B,这个响应中就包含了用户A 要发送的消息~
对于以上场景,我们应该如何实现呢?接着往下看!
WebSocket 是从 HTML5 开始支持的一种网页端和服务端保持长连接的 消息推送机制。
传统的 web 程序都是 “一问一答” 的形式,客户端给服务器发送了个 HTTP 请求,服务器根据请求计算响应返回客户端。显然,这种传统的 web 程序如果客户端不主动发起请求,服务器就无法主动给客户端发送响应~
Ps:若想使用原生的 HTTP 协议实现消息推送,需要进行“轮询”,反复询问服务器是否收到请求,成本太高
而 WebSocket 则是更接近 TCP 这种级别的通信方式——一旦连接建立完成,客户端或服务器都可以主动向对方发送数据。
相同点:
不同点:
WebSocket 协议本质上是基于 TCP 协议的,为了建立一个 WebSocket 连接,客户端先创建 WebSocket 对象,然后向服务器发起一个 HTTP 请求建立连接(类似 ws://cyk.com/aaa ).
第一次客户端请求报文格式类似于:
- GET /cyk/websocket/ HTTP/1.1
- Host: localhost
- Upgrade: websocket
- Connection: Upgrade
- Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
- Origin: http://localhost:8080
- Sec-WebSocket-Version: 13
第一次服务器收到报文后返回的数据格式类似于:
- HTTP/1.1 101 Switching Protocols
- Upgrade: websocket
- Connection: Upgrade
- Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=
经过这样的请求响应之后,两端的 WebSocket 连接握手完成,后续就可以进行 TCP 通讯了.
创建一个 Spring Boot 项目,接着我们需要引入 Spring Web 依赖,以及 Web Socket 依赖。
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-websocket</artifactId>
- </dependency>
这里我们先创建一个类,自定义名为 TestAPI ,继承 TextWebSocketHandler 类,重写这个类下4个最关键的方法:
这个类就是用来处理 WebSocket 相关请求的~
于是,我们就可这样写:
- import org.springframework.stereotype.Component;
- import org.springframework.web.socket.CloseStatus;
- import org.springframework.web.socket.TextMessage;
- import org.springframework.web.socket.WebSocketSession;
- import org.springframework.web.socket.handler.TextWebSocketHandler;
-
- @Component
- public class TestAPI extends TextWebSocketHandler {
-
- @Override
- public void afterConnectionEstablished(WebSocketSession session) throws Exception {
- System.out.println("连接成功");
- }
-
- @Override
- protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
- System.out.println("收到消息:" + message.getPayload());
- //收到消息后向客户端反馈信息(这里反馈相同数据)
- session.sendMessage(message);
- }
-
- @Override
- public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
- System.out.println("连接异常");
- }
-
- @Override
- public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
- System.out.println("连接关闭");
- }
-
- }
第一步,创建一个类,自定义类名为WebSocketConfig,实现 WebSocketConfigurer接口,这个接口下只需要实现一个方法 registerWebSocketHandlers,这个类就是用来注册添加 WebSocket (当前项目要添加的就是我们刚刚写的 TestAPI 这个类)以及注册路由(这个路由就将客户端与服务器联系起来了:前端创建 WebSocket 实例时,就需要写下对应的路由)。
第二步、注入 TestAPI 类,最后使用 addHander方法添加注册这个类,基于这个类才能进一步的找到 TestAPI 这个类,去处理 WebSocket相关的请求~
代码实现如下:
- import com.example.demo.api.TestAPI;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.socket.config.annotation.EnableWebSocket;
- import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
- import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
-
- @Configuration
- @EnableWebSocket //启动 WebSocket
- public class WebSocketConfig implements WebSocketConfigurer {
-
- @Autowired
- private TestAPI testAPI;
-
- @Override
- public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
- webSocketHandlerRegistry.addHandler(testAPI, "/test");
- }
- }
Ps:
@EnableWebSocket
注解是用来让 Spring 框架认识这个类是用来配置 webSocket 的类,基于这个类才能进一步的找到 TestAPI 这个类,去处理 WebSocket相关的请求~
前端需要创建 WebSocket 实例,并写下相应路由,这个路由就是与后端 webSocket 相对应的那个路由,如下:
接着前端也可以通过 WebSocket 的4个重要方法,根据响应打印对应日志:
最后通过按钮输入框的形式来发送相应的 HTTP 请求,代码如下:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- </head>
- <body>
- <input type="text" id="message">
- <button id="submit">提交</button>
-
- <script>
- // 创建 websocket 示例
- let websocket = new WebSocket("ws://127.0.0.1:8080/test");
-
- websocket.onopen = function() {
- console.log("建立连接");
- }
-
- websocket.onmessage = function(e) {
- console.log("收到消息: " + e.data);
- }
-
- websocket.onerror = function() {
- console.log("连接异常");
- }
-
- websocket.onclose = function() {
- console.log("连接关闭");
- }
-
- let input = document.querySelector("#message");
-
- //点击按钮发送请求
- let button = document.querySelector("#submit");
- button.onclick = function() {
- console.log("发送消息:" + input.value);
- websocket.send(input.value);
- }
-
- </script>
-
- </body>
- </html>
启动程序,输入对应URL,如下结果;
发送消息,点击按钮(相当于主机A 给主机B 发送消息,这里实现的是一个简易版,是一个回显服务),如下结果:
最后关闭浏览器,断开连接:
这样一个简单 demo 就完成了~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。