之前公司的某个系统为了实现推送技术,所用的技术都是Ajax轮询,这种方式浏览器需要不断的向服务器发出请求,显然这样会浪费很多的带宽等资源,所以研究了下WebSocket,本文将详细介绍下。

一、什么是WebSocket?

WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据,在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

二、SpringBoot整合WebSocket

新建一个spring boot项目spring-boot-websocket,按照下面步骤操作。

  1. pom.xml引入jar包
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-websocket</artifactId>
  4. </dependency>
  1. 新建WebSocket的配置类

这个配置类检测带注解@ServerEndpoint的bean并注册它们,配置类代码如下:

  1. @Configuration
  2. public class WebSocketConfig {
  3. /**
  4. * 给spring容器注入这个ServerEndpointExporter对象
  5. * 相当于xml:
  6. * <beans>
  7. * <bean id="serverEndpointExporter" class="org.springframework.web.socket.server.standard.ServerEndpointExporter"/>
  8. * </beans>
  9. * <p>
  10. * 检测所有带有@serverEndpoint注解的bean并注册他们。
  11. *
  12. * @return
  13. */
  14. @Bean
  15. public ServerEndpointExporter serverEndpointExporter() {
  16. System.out.println("我被注入了");
  17. return new ServerEndpointExporter();
  18. }
  19. }
  1. 新建WebSocket的处理类

这个处理类需要使用@ServerEndpoint,这个类里监听连接的建立关闭、消息的接收等,具体代码如下:


  1. @ServerEndpoint(value = "/ws/asset")
  2. @Component
  3. public class WebSocketServer {
  4. @PostConstruct
  5. public void init() {
  6. System.out.println("websocket 加载");
  7. }
  8. private static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
  9. private static final AtomicInteger OnlineCount = new AtomicInteger(0);
  10. // concurrent包的线程安全Set,用来存放每个客户端对应的Session对象。
  11. private static CopyOnWriteArraySet<Session> SessionSet = new CopyOnWriteArraySet<Session>();
  12. /**
  13. * 连接建立成功调用的方法
  14. */
  15. @OnOpen
  16. public void onOpen(Session session) {
  17. SessionSet.add(session);
  18. int cnt = OnlineCount.incrementAndGet(); // 在线数加1
  19. log.info("有连接加入,当前连接数为:{}", cnt);
  20. SendMessage(session, "连接成功");
  21. }
  22. /**
  23. * 连接关闭调用的方法
  24. */
  25. @OnClose
  26. public void onClose(Session session) {
  27. SessionSet.remove(session);
  28. int cnt = OnlineCount.decrementAndGet();
  29. log.info("有连接关闭,当前连接数为:{}", cnt);
  30. }
  31. /**
  32. * 收到客户端消息后调用的方法
  33. *
  34. * @param message
  35. * 客户端发送过来的消息
  36. */
  37. @OnMessage
  38. public void onMessage(String message, Session session) {
  39. log.info("来自客户端的消息:{}",message);
  40. SendMessage(session, "收到消息,消息内容:"+message);
  41. }
  42. /**
  43. * 出现错误
  44. * @param session
  45. * @param error
  46. */
  47. @OnError
  48. public void onError(Session session, Throwable error) {
  49. log.error("发生错误:{},Session ID: {}",error.getMessage(),session.getId());
  50. error.printStackTrace();
  51. }
  52. /**
  53. * 发送消息,实践表明,每次浏览器刷新,session会发生变化。
  54. * @param session
  55. * @param message
  56. */
  57. public static void SendMessage(Session session, String message) {
  58. try {
  59. // session.getBasicRemote().sendText(String.format("%s (From Server,Session ID=%s)",message,session.getId()));
  60. session.getBasicRemote().sendText(message);
  61. } catch (IOException e) {
  62. log.error("发送消息出错:{}", e.getMessage());
  63. e.printStackTrace();
  64. }
  65. }
  66. /**
  67. * 群发消息
  68. * @param message
  69. * @throws IOException
  70. */
  71. public static void BroadCastInfo(String message) throws IOException {
  72. for (Session session : SessionSet) {
  73. if(session.isOpen()){
  74. SendMessage(session, message);
  75. }
  76. }
  77. }
  78. /**
  79. * 指定Session发送消息
  80. * @param sessionId
  81. * @param message
  82. * @throws IOException
  83. */
  84. public static void SendMessage(String message,String sessionId) throws IOException {
  85. Session session = null;
  86. for (Session s : SessionSet) {
  87. if(s.getId().equals(sessionId)){
  88. session = s;
  89. break;
  90. }
  91. }
  92. if(session!=null){
  93. SendMessage(session, message);
  94. }
  95. else{
  96. log.warn("没有找到你指定ID的会话:{}",sessionId);
  97. }
  98. }
  99. }
  1. 新建一个html

目前大部分浏览器支持WebSocket,比如Chrome, Mozilla,Opera和Safari,在html页面进行websocket的连接建立、收消息的监听,页面代码如下:

  1. <html>
  2. <head>
  3. <meta charset="UTF-8">
  4. <title>websocket测试</title>
  5. <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
  6. <style type="text/css">
  7. h3,h4{
  8. text-align:center;
  9. }
  10. </style>
  11. </head>
  12. <body>
  13. <h3>WebSocket测试,客户端接收到的消息如下:</h3>
  14. <textarea id = "messageId" readonly="readonly" cols="150" rows="30" >
  15. </textarea>
  16. <script type="text/javascript">
  17. var socket;
  18. if (typeof (WebSocket) == "undefined") {
  19. console.log("遗憾:您的浏览器不支持WebSocket");
  20. } else {
  21. console.log("恭喜:您的浏览器支持WebSocket");
  22. //实现化WebSocket对象
  23. //指定要连接的服务器地址与端口建立连接
  24. //注意ws、wss使用不同的端口。我使用自签名的证书测试,
  25. //无法使用wss,浏览器打开WebSocket时报错
  26. //ws对应http、wss对应https。
  27. socket = new WebSocket("ws://localhost:8080/ws/asset");
  28. //连接打开事件
  29. socket.onopen = function() {
  30. console.log("Socket 已打开");
  31. socket.send("消息发送测试(From Client)");
  32. };
  33. //收到消息事件
  34. socket.onmessage = function(msg) {
  35. $("#messageId").append(msg.data+ "\n");
  36. console.log(msg.data );
  37. };
  38. //连接关闭事件
  39. socket.onclose = function() {
  40. console.log("Socket已关闭");
  41. };
  42. //发生了错误事件
  43. socket.onerror = function() {
  44. alert("Socket发生了错误");
  45. }
  46. //窗口关闭时,关闭连接
  47. window.unload=function() {
  48. socket.close();
  49. };
  50. }
  51. </script>
  52. </body>
  53. </html>

三、查看运行效果

启动SpringBoot项目

  1. 打开首页

本地浏览器打开首页http://localhost:8080/,出现WebSocket测试页面,同时后台打印连接的日志。

  1. 有连接加入,当前连接数为:1,sessionId=0
  1. 往客户端发送消息

通过上面日志可以看到客户端连接连接的sessionId,我测试时候sessionId是0,然后浏览器访问下面接口即可往客户端发送消息。

  1. //参数说明: id:sessionID
  2. //参数说明: message:消息内容
  3. http://localhost:8080/api/ws/sendOne?id=0&message=你好Java碎碎念

到此SpringBoot整合WebSocket的功能已经全部实现,有问题欢迎留言沟通哦!

完整源码地址: https://github.com/suisui2019/springboot-study

推荐阅读

1.一分钟带你了解下MyBatis的动态SQL!

2.一分钟带你了解下Spring Security!

3.一分钟带你学会利用mybatis-generator自动生成代码!

4.手把手带你实战下Spring的七种事务传播行为

5.SpringBoot系列-整合Mybatis(注解方式)


如果觉得文章不错,希望可以随手转发或者”在看“哦,非常感谢哈!

关注下方公众号后回复「1024」,有惊喜哦!

本文由博客一文多发平台 OpenWrite 发布!

SpringBoot2.0整合WebSocket,实现后端数据实时推送!的更多相关文章

  1. Springboot:SpringBoot2.0整合WebSocket,实现后端数据实时推送!

    一.什么是WebSocket? B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化Web服务器,减少服务器的负担,加快响应速度,因为服务器不 ...

  2. WebSocket和kafka实现数据实时推送到前端

    一. 需求背景      最近新接触一个需求,需要将kafka中的数据实时推送到前端展示.最开始想到的是前端轮询接口数据,但是无法保证轮询的频率和消费的频率完全一致,或造成数据缺失等问题.最终确定用利 ...

  3. Django2.0.4 + websocket 实现实时通信,主动推送,聊天室及客服系统

    webSocket是一种在单个TCP连接上进行全双工通信的协议. webSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebSocket API中,浏览器 ...

  4. Javascript中数据实时推送

    数据变化后前端需要更新,有几种方式:(参考http://www.xiaocai.name/post/cf1f9_7b6507) .利用setInterval函数,每隔n秒去异步拉取数据.对数据实时性要 ...

  5. 用node.js(socket.io)实现数据实时推送

    在做商品拍卖的时候,要求在商品的拍卖页面需要实时的更新当前商品的最高价格.实现的方式有很多,比如: 1.setInterval每隔n秒去异步拉取数据(缺点:更新不够实时) 2. AJAX轮询方式方式推 ...

  6. springboot2.0整合springsecurity前后端分离进行自定义权限控制

    在阅读本文之前可以先看看springsecurity的基本执行流程,下面我展示一些核心配置文件,后面给出完整的整合代码到git上面,有兴趣的小伙伴可以下载进行研究 使用maven工程构建项目,首先需要 ...

  7. WebSocket实现站内消息实时推送

    关于WebSocket WebSocket是HTML5 开始提供的一种在单个TCP连接上进行全双工通讯的协议.什么是全双工?就是在同一时间可以发送和接收消息,实现双向通信,比如打电话.WebSocke ...

  8. SpringBoot2.0 整合 QuartJob ,实现定时器实时管理

    一.QuartJob简介 1.一句话描述 Quartz是一个完全由java编写的开源作业调度框架,形式简易,功能强大. 2.核心API (1).Scheduler 代表一个 Quartz 的独立运行容 ...

  9. SpringBoot2.0 整合 Dubbo框架 ,实现RPC服务远程调用

    一.Dubbo框架简介 1.框架依赖 图例说明: 1)图中小方块 Protocol, Cluster, Proxy, Service, Container, Registry, Monitor 代表层 ...

随机推荐

  1. CentOS 7 安装并配置 MySQL 5.7

    Linux使用MySQL Yum存储库上安装MySQL 5.7,适用于Oracle Linux,Red Hat Enterprise Linux和CentOS系统. 1.添加MySQL Yum存储库 ...

  2. python 计算两个日期间的小时数

    #!/usr/bin/env python #encoding: utf-8 import datetime def dateDiffInHours(t1, t2): td = t2 - t1 ret ...

  3. milvus安装及其使用教程

    milvus 简介 milvus是干什么的?通俗的讲,milvus可以让你在海量向量库中快速检索到和目标向量最相似的若干个向量,这里相似度量标准可以是内积或者欧式距离等.借用官方的话说就是: Milv ...

  4. 为什么查询出来的数据保存到Arraylist?插入删除数据为啥用LinkedList?

    引言:这是我在回答集合体系时,被问到的一个问题,也是因为没有深入学习所以回答的并不是很好,所以这两天看了一下,以下是我的一些回答与学习方法. 学习方法:我们学习,系统性的学习肯定是比零散的学习更有效的 ...

  5. Docker系列之常用命令操作手册

    目录 1.安装虚拟机 2.安装Docker 3.Docker镜像操作 4.Docker容器操作 Docker系列之常用命令操作手册 继上一篇博客Docker系列之原理简单介绍之后,本博客对常用的Doc ...

  6. Mybatis_resultMap的关联方式实现多表查询(一对多)

    a)在 ClazzMapper.xml 中定义多表连接查询 SQL 语句, 一次性查到需要的所有数据, 包括对应学生的信息. b)通过<resultMap>定义映射关系, 并通过<c ...

  7. CyAPI环境搭建

    http://jingyan.baidu.com/article/e6c8503c0690cee54f1a1893.html

  8. 虚拟链路(virtual-link)

    第四部分,虚拟链路配置.我们都知道,在ospf多区域中,所有与主干区域(ospf0)相连接的其他区域可以相互学系路由信息,但是,如果是非主干区域和非主干区域相连,就不能相互学习路由信息,这时候,我们可 ...

  9. 201871010119-帖佼佼《面向对象程序设计(java)》第十五周学习总结

    博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.co ...

  10. 东拼西凑完成一个“前端框架”(4) - Tabs页

    目录 东拼西凑完成一个后台 "前端框架" (1) - 布局  东拼西凑完成一个后台 "前端框架" (2) - 字体图标 东拼西凑完成一个"前端框架&q ...