Springboot怎么实现WebSocket通信(一)
创始人
2024-05-30 00:38:39
0
文章示例环境配置信息
jdk版本:1.8
开发工具:Intellij iDEA 2020.1
springboot:2.3.9.RELEASE

什么是WebSocket?

WebSocket,是HTML5下一种新的协议,支持web浏览器和服务器端之间双向全双工通信 ,基于TCP协议实现。

WebSocket主要特性

1、WebSocket是一种全新的协议,不属于http无状态协议,协议名为“ws”;

2、WebSocket是基于TCP的,属于可靠性传输协议,按OSI网络模型划分,归属应用层协议;

3、WebSocket是双向通信协议,可以双向发送或接受信息,与http相比最明显的区别就是允许服务端向客户端浏览器主动推送数据,而HTTP是单向的,只能由客户端发起请求,服务端针对客户端请求作出响应;

4、使用WebSocket通信前,浏览器和服务器端需要先进行握手建立连接;

5、WebSocket在握手建立连接的时候,数据是通过HTTP传输的,但是在建立连接之后,真正传输数据的时候是不需要HTTP协议的;

6、WebSocket建立连接后,数据是以帧序列的形式传输,浏览器端与服务器端的发送和接受消息是在同一个持久连接上发起,即浏览器端与服务器端的WebSocket连接未断开时,不需要重新发起连接请求就可以多次发送和接受消息;在并发及交互负载流量大的情况下,极大节省了网络带宽资源,有明显的性能优势,实现了真正的“长连接”;

WebSocket基本使用演示

通过WebSocket功能特性来看,WebSocket是一个非常重要的有实际应用意义的通信协议,下面以单机模式下的Springboot项目中集成WebSocket,来学习一下WebSocket使用方法及主要功能特性。

后端

1、引入WebSocket所需要starter模块依赖包;

org.springframework.bootspring-boot-starter-websocket

2、定义WebSocketConfig配置类,引入WebSocket的Springboot的自动配置类ServerEndpointExporter,这个配置类主要用于扫描WebSocket相关的注解;

@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}
}

3、定义一个WebSocket类,使用@Component注解把WebSocket类注册到Spring容器中,使用@ServerEndpoint注解把当前类定义成一个服务器端并标记好客户端发起WebSocket连接请求的URL;在WebSocket类内用到了四个注解:@Open、@Close、@OnMessage、@OnError:

@Open:当WebSocket连接建立成功后会触发这个注解修饰的方法;

@Close:当WebSocket连接关闭或中断后会触发这个注解修饰的方法;

@OnMessage:当客户端发送消息到服务端时,会触发这个注解修饰的方法;

@OnError:当 websocket 建立连接时出现异常会触发这个注解修饰的方法;

@Component
@ServerEndpoint("/websocket/{userId}")
@Slf4j
public class WebSocket {private Session session;private static Map webSocketMap = new ConcurrentHashMap<>();/*** 客户端发起websocket连接请求成功建立连接时触发* @param session* @param userId*/@OnOpenpublic void onOpen(Session session, @PathParam("userId") String userId) {this.session = session;this.webSocketMap.put(userId, this);log.info("【websocket消息】有新的连接, 总数:{}", webSocketMap.size());}/*** 客户端关闭时websocket连接时触发*/@OnClosepublic void onClose(@PathParam("userId") String userId) throws IOException {session.close();this.webSocketMap.remove(userId);log.info("【websocket消息】连接断开, 总数:{}", webSocketMap.size());}/*** 客户端向服务端发送消息时触发* @param session* @param message* @throws IOException*/@OnMessagepublic void onMessage(Session session,  String message) throws IOException {Map> requestParameterMap = session.getRequestParameterMap();String userId = requestParameterMap.get("userId").get(0);log.info("【websocket消息】收到客户端发来的消息:{}", message);if (message.startsWith("hello")) {session.getBasicRemote().sendText("你好,"+userId+"!信息已经收到,欢迎光临" + message.replace("hello", ""));}}/*** 当 websocket 建立连接时出现异常会触发* @param session*/@OnErrorpublic void onError(Session session){Map> requestParameterMap = session.getRequestParameterMap();String userId = requestParameterMap.get("userId").get(0);log.info("连接异常,请求参数:"+userId);}
}

前端

在resources目录下的静态资源目录static下,新建一个index.html;

index.html的逻辑很简单,就是在页面上放三个按钮,分别用于建立websocket连接、关闭websocket连接、向服务端发送文本消息;具体的实现步骤是这样的:

1、引入jquery.js,这样就可以使用"$"符号了;

2、在body标签内分别放置三个按钮,标签id分别是open、close、send;

3、定义一个div标签,用来显示操作信息和从服务端发送过来的文本消息;

4、在标签内,声明websocket变量,然后在open按钮的点击事件触发进,向服务端发起连接请求,这里要特别注意一下,请求的URL是:“ws://172.18.229.61/websocket/gaox2”;与http请求类似的是,http请求的开头是http,websocket请求的开头是ws;

5、与服务端比较类似的是,客户端在websocket连接建立后,也会注册websocket连接事件在连接成功建立、连接发生错误、接收到服务端消息、连接关闭时的回调方法;

6、websocket连接建立成功后,在发送信息、关闭连接按钮被触发时,编写相应的处理逻辑;



websocket测试


测试结果

总结

至此,在Springboot项目中,如何使用WebSocket进行数据交互的基本方法就是这样了。其实还是挺简单的,主要就是两部分:1、前端如何发起请求和处理服务端发回的消息;2、后端处理如何处理前端发起的websocket请求以及如何主动发消息给浏览器端;

但是大家有没有发现一个问题:单机模式下,浏览器端向服务端发起websocket请求,服务端处理请求并主动发消息给浏览器端,这种点对点的通信确实不复杂,但是实际的业务场景中,大部分项目都是分布式部署的,一个工程布署了多个服务节点,前端并不直接请求具体服务节点,而是先到nginx或其他代理服务器,通过nginx的负载均衡机制再转发到具体的服务节点,浏览器端在发起websocket连接时,直接连接到具体的服务节点显然不太合适的,那么向nginx发起websocket连接,再由其转发到具体的节点是否可以呢?又是怎么配置的呢?另外服务端向客户端发送消息时,用到了session,当然这里的session和servlet的session不是一个session,servlet中的session是jvm级别的,本身是不支持跨节点共享的,那websocket的session是否支持跨节点共享?如果不支持,则用什么办法实现session的共享?

这篇文章和大家一块简单学习一下websocket的基本使用方法,下一篇文章再来和大家一块分享一下,如何把websocket应用到实际的业务开发中。

相关内容

热门资讯

编程安卓系统和鸿蒙主题,跨平台... 你有没有想过,手机的世界里,除了苹果的iOS和安卓的操作系统,还有个神秘的鸿蒙系统?今天,咱们就来聊...
哪个安卓机系统好用,探索安卓系... 你有没有想过,手机里的安卓系统就像是个大厨,不同的系统就像不同的烹饪手法,有的让你吃得津津有味,有的...
安卓如何控制苹果系统,从安卓到... 你知道吗?在这个科技飞速发展的时代,安卓和苹果两大操作系统之间的较量从未停歇。虽然它们各自有着忠实的...
安卓原生系统文件夹,安卓原生系... 你有没有发现,每次打开安卓手机,里面那些文件夹就像是一个个神秘的宝箱,里面藏着各种各样的宝贝?今天,...
基于安卓系统的游戏开发,从入门... 你有没有想过,为什么安卓手机上的游戏总是那么吸引人?是不是因为它们就像是你身边的好朋友,随时随地都能...
安卓系统怎样装驱动精灵,安卓系... 你那安卓设备是不是突然间有点儿不给力了?别急,今天就来手把手教你如何给安卓系统装上驱动精灵,让你的设...
如何本地安装安卓系统包,详细步... 你有没有想过,把安卓系统装在你的电脑上,是不是就像给电脑穿上了时尚的新衣?想象你可以在电脑上直接玩手...
安卓12卡刷系统教程,体验全新... 你有没有发现,你的安卓手机最近有点儿不给力了?运行速度慢得像蜗牛,是不是也想给它来个“换血大法”,让...
安卓系统无法打开swf文件,安... 最近是不是发现你的安卓手机有点儿不给力?打开SWF文件时,是不是总是出现“无法打开”的尴尬局面?别急...
鸿蒙系统依赖于安卓系统吗,独立... 你有没有想过,我们手机里的那个鸿蒙系统,它是不是真的完全独立于安卓系统呢?这个问题,估计不少手机控都...
适合安卓系统的图片软件,精选图... 手机里堆满了各种美美的照片,是不是觉得找起来有点头疼呢?别急,今天就来给你安利几款超级适合安卓系统的...
阴阳师安卓系统典藏,探寻阴阳师... 亲爱的阴阳师们,你是否在安卓系统上玩得如痴如醉,对那些精美的典藏式神们垂涎欲滴?今天,就让我带你深入...
安卓系统有碎片化缺点,系统优化... 你知道吗?在手机江湖里,安卓系统可是个响当当的大侠。它那开放、自由的个性,让无数手机厂商和开发者都为...
安卓4系统手机微信,功能解析与... 你有没有发现,现在市面上还有很多安卓4系统的手机在使用呢?尤其是那些喜欢微信的朋友们,这款手机简直就...
鸿蒙系统是安卓的盗版,从安卓“... 你知道吗?最近在科技圈里,关于鸿蒙系统的讨论可是热闹非凡呢!有人说是安卓的盗版,有人则认为这是华为的...
安卓系统怎么剪辑音乐,轻松打造... 你是不是也和我一样,手机里存了超多好听的歌,但是有时候想给它们来个变身,变成一段专属的旋律呢?别急,...
怎么把安卓手机系统变为pc系统... 你有没有想过,把你的安卓手机变成一台PC呢?听起来是不是有点酷炫?想象你可以在手机上玩电脑游戏,或者...
手机怎么装安卓11系统,手机安... 你有没有想过,让你的手机也来个“青春焕发”,升级一下系统呢?没错,就是安卓11系统!这个新系统不仅带...
安卓系统如何拼网络,构建高效连... 你有没有想过,你的安卓手机是怎么和网络“谈恋爱”的呢?没错,就是拼网络!今天,就让我带你一探究竟,看...
安卓系统怎么看小说,轻松畅享电... 你有没有发现,手机里装了那么多应用,最离不开的竟然是那个小小的小说阅读器?没错,就是安卓系统上的小说...