webSocket介绍与使用 spring boot 集成 websocket教程 java
创始人
2024-11-16 04:33:45
0

目录

一、WebSocket简介

二、WebSocket优缺点

三、spring boot集成webSocket

四、验证


一、WebSocket简介

        WebSocket建立在TCP协议上,是一种在单个TCP连接上进行全双工通信的协议。

        HTML5里面提出了WebSocket标准,目的是让服务器具有“主送”向浏览器推送信息的能力,它允许客户端和服务器之间建立持久连接,实现实时的数据传输功能。

WebSocket通讯分为两个阶段:

1.握手阶段

        客户端通过HTTP请求发起握手请求,请求头包含一些特殊字段,如pgrade:websocket和Connection:Upgrade以及其他的WebSocket相关字段。

服务器收到客户端的WebSocket握手请求后,进行协议升级,将HTTP升级为WebSocket连接。服务器返回一个WebSocket握手响应,相应头中包如:Upgrade:websocket和Connection:Upgrade等WebSocket相关字段。

客户端收到服务器的WebSocket握手响应后,WebSocket连接就建立成功,客户端和服务端都可以发送和接收WebSocket消息。

2.数据交换阶段

        WebSocket建立成功后,客户端和服务器都可以通过WebSocket会话进行实时的双向数据交换。同时,客户端和服务端可以通过发送心跳数据帧来维持连接,如果在一段时间内没有收到心跳响应,则断开WebSocket连接。

二、WebSocket优缺点

1.优点

        支持双向通讯,实时性比较高,更加灵活。

        开销少,ws建立成功后,客户端、服务端进行数据交换,协议控制的数据包头部较小。http需要完整的头部信息。

        可扩展,WebSocket协议定义了扩展,用户可以扩展协议。

2.缺点

        服务端需要支持WebSocket协议。

        客户端连接数多,服务端压力大。

三、spring boot集成webSocket

1.新建spring boot项目,再pom.xml加入以下配置

     org.springframework.boot     spring-boot-starter-parent     2.1.18.RELEASE                      org.springframework.boot         spring-boot-starter-web                        org.springframework.boot         spring-boot-starter-websocket      

2.再spring boot启动类开启websocket功能

package com.example.demo;  import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.socket.config.annotation.EnableWebSocket;  //开启WebSocket @EnableWebSocket @SpringBootApplication public class DemoApplication {     public static void main(String[] args) {         SpringApplication.run(DemoApplication.class, args);     }  }

3.新建WebSoketConfig配置类

package com.example.demo.common.config.websocket;  import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter;  /**  * WebSocket配置类  */ @Configuration public class WebSocketConfig {     @Bean     public ServerEndpointExporter serverEndpointExporter() {         return new ServerEndpointExporter();     } }

4.新建WebSocketServer服务类

package com.example.demo.common.config.websocket;  import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.concurrent.ConcurrentHashMap;  /**  * @ServerEndpoint:该注解用于暴漏外部ws的路径,类似@RequestMapping注解。例如服务端口8080,请求地址:ws://localhost:8080/myWs  * 路径上{userId}  可在onOpen连接成功方法使用@PathParam("userId") String userId接收数据  */ @ServerEndpoint("/myWs/{userId}") @Component public class WebSocketServer {     //线程安全的map,用来保存每个客户端对应的WebSocket对象     private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();     //单个客户端的session,通过session与对应客户端通讯     private Session session;     //用户id     private String userId;      /**      * 连接成功      * @OnOpen注解:websocket 连接成功后,触发该注解修饰的方法      * @param session      */     @OnOpen     public void onOpen(Session session, @PathParam("userId") String userId) {         this.session = session;         this.userId = userId;         if (webSocketMap.containsKey(userId)) {             webSocketMap.remove(userId);             webSocketMap.put(userId, this);         } else {             webSocketMap.put(userId, this);         }         System.out.println("连接成功");     }      /**      * 连接关闭      * @OnClose注解:websocket断开连接后,触发该注解修饰的方法      * @param session      */     @OnClose     public void onCLose(Session session) {         if (webSocketMap.containsKey(userId)) {             webSocketMap.remove(userId);         }         System.out.println("关闭连接");     }      /**      * 接收消息      * @OnMessage注解:客户端发送消息时,触发该注解声明的方法      * @param text      * @return      */     @OnMessage     public void onMessage(String text) {         System.out.println("后端接收前端web发送数据userId:" + userId + ",接收信息:" + text);         if (webSocketMap.containsKey(userId)) {             try {                 webSocketMap.get(userId).session.getBasicRemote().sendText("返回web数据userId:" + userId + ",返回消息:" + text);             } catch (IOException e) {                 e.printStackTrace();             }         }     }      /**      * 连接异常      * @OnError注解:当建立的连接出现异常后,触发该注解修饰的方法      * @param session      * @param throwable      */     @OnError     public void onError(Session session, Throwable throwable) {         System.out.println("websocket连接异常:" + throwable.getMessage());     }      /**      * 服务器给指定WebSocket客户端发送信息      * @param userId      * @param message      */     public static void sendInfo(String userId, String message) {         System.out.println("后端发送前端web数据userId:" + userId + "发送消息:" + message);         if (webSocketMap.containsKey(userId)) {             try {                 webSocketMap.get(userId).session.getBasicRemote().sendText("后端发送前端web数据userId" + userId + ",内容:" + message);             } catch (IOException e) {                 e.printStackTrace();             }         }     } }

5.新建DemoController测试类,增加接口通过webSocket给客户端发信信息

package com.example.demo.controller;  import com.example.demo.common.config.websocket.WebSocketServer; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;  @RestController public class DemoController {      @RequestMapping("/demo")     public boolean demo(@RequestParam("userId") String userId, @RequestParam("message") String mesage) {         //给前端web推送数据         WebSocketServer.sendInfo(userId, mesage);         return true;     } }

四、验证

1.启动服务,访问websocket在线测试页面,与后端建立连接

2.后端显示连接成功

3.通过websocket给后端发送数据

4.后端打印接收到的数据

5.调用后端接口,通过websocket给前端推送数据

6.websocket在线测试页面收到数据

相关内容

热门资讯

快手平台上的宝宝大眼睛特效是如... 快手宝宝大眼睛特效是一种美颜滤镜,它能够放大和美化用户的眼睛,创造出一种可爱、无辜的大眼效果。这种特...
为何QQ农场频繁遭遇服务器超时... qq农场服务器一直超时可能由于网络连接问题、服务器维护或更新、游戏本身bug,或者是用户设备性能不足...
请问,流行的端游吃鸡游戏的官方... "端游吃鸡服务器"通常指的是《绝地求生》(PlayerUnknown's Battlegrounds...
为什么互联网服务器不采用C语言... 互联网服务器不常用C语言编写,主要是因为现代开发更偏好使用如Python、Java等高级语言,它们提...
为何QQ群人数上限仅为600人... QQ好友数量上限为600人是因为腾讯公司为了优化用户体验,防止用户好友过多导致信息过载,同时也考虑到...
如何通过电脑键盘快捷键调整字体... 在大多数电脑上,你可以按住"Ctrl"键的同时按下"+"键(位于数字键盘上)来放大字体。如果你的电脑...
探索手机导航,如何轻松找到目的... 你可以使用手机上的地图应用程序,如Google Maps或Apple Maps,输入你想去的地方的名...
如何解决iPad提示的无法验证... 当iPad弹出“无法验证服务器身份”的提示时,意味着设备无法确认正在尝试连接的服务器的安全性。这可能...
解封微信账号究竟意味着什么? 解封微信账号指的是恢复被暂时封禁的微信账户的使用权限。这通常发生在用户违反了微信的服务条款或操作规则...
为何我的PUBG手游提示服务器... 手游PUBG显示服务器正在维修可能是因为官方正在进行更新或维护工作,以确保游戏的稳定性和安全性。玩家...