Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >SpringBoot 实战 (十六) | 整合 WebSocket 基于 STOMP 协议实现广播消息

SpringBoot 实战 (十六) | 整合 WebSocket 基于 STOMP 协议实现广播消息

作者头像
JavaFish
发布于 2019-10-17 08:46:03
发布于 2019-10-17 08:46:03
3.6K017
代码可运行
举报
运行总次数:17
代码可运行

微信公众号:一个优秀的废人。如有问题或建议,请后台留言,反正我也不会听。

前言

如题,今天介绍的是 SpringBoot 整合 WebSocket 实现广播消息。

什么是 WebSocket ?

WebSocket 为浏览器和服务器提供了双工异步通信的功能,即浏览器可以向服务器发送信息,反之也成立。

WebSocket 是通过一个 socket 来实现双工异步通信能力的,但直接使用 WebSocket ( 或者 SockJS:WebSocket 协议的模拟,增加了当前浏览器不支持使用 WebSocket 的兼容支持) 协议开发程序显得十分繁琐,所以使用它的子协议 STOMP。

STOMP 协议简介

它是高级的流文本定向消息协议,是一种为 MOM (Message Oriented Middleware,面向消息的中间件) 设计的简单文本协议。

它提供了一个可互操作的连接格式,允许 STOMP 客户端与任意 STOMP 消息代理 (Broker) 进行交互,类似于 OpenWire (一种二进制协议)。

由于其设计简单,很容易开发客户端,因此在多种语言和多种平台上得到广泛应用。其中最流行的 STOMP 消息代理是 Apache ActiveMQ。

STOMP 协议使用一个基于 (frame) 的格式来定义消息,与 Http 的 request 和 response 类似 。

广播

接下来,实现一个广播消息的 demo。即服务端有消息时,将消息发送给所有连接了当前 endpoint 的浏览器。

准备工作

  • SpringBoot 2.1.3
  • IDEA
  • JDK8

Pom 依赖配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependencies>
        <!-- thymeleaf 模板引擎 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- web 启动类 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- WebSocket 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <!-- test 单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

代码注释很详细,不多说。

配置 WebSocket

实现 WebSocketMessageBrokerConfigurer 接口,注册一个 STOMP 节点,配置一个广播消息代理

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
// @EnableWebSocketMessageBroker注解用于开启使用STOMP协议来传输基于代理(MessageBroker)的消息,这时候控制器(controller)
// 开始支持@MessageMapping,就像是使用@requestMapping一样。
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //注册一个 Stomp 的节点(endpoint),并指定使用 SockJS 协议。
        registry.addEndpoint("/endpointNasus").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        // 广播式配置名为 /nasus 消息代理 , 这个消息代理必须和 controller 中的 @SendTo 配置的地址前缀一样或者全匹配
        registry.enableSimpleBroker("/nasus");
    }
}

消息类

客户端发送给服务器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Client2ServerMessage {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

服务器发送给客户端:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Server2ClientMessage {

    private String responseMessage;

    public Server2ClientMessage(String responseMessage) {
        this.responseMessage = responseMessage;
    }

    public String getResponseMessage() {
        return responseMessage;
    }

    public void setResponseMessage(String responseMessage) {
        this.responseMessage = responseMessage;
    }
}

演示控制器代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RestController
public class WebSocketController {

    @MessageMapping("/hello") // @MessageMapping 和 @RequestMapping 功能类似,浏览器向服务器发起消息,映射到该地址。
    @SendTo("/nasus/getResponse") // 如果服务器接受到了消息,就会对订阅了 @SendTo 括号中的地址的浏览器发送消息。
    public Server2ClientMessage say(Client2ServerMessage message) throws Exception {
        Thread.sleep(3000);
        return new Server2ClientMessage("Hello," + message.getName() + "!");
    }

}

引入 STOMP 脚本

将 stomp.min.js (STOMP 客户端脚本) 和 sockJS.min.js (sockJS 客户端脚本) 以及 Jquery 放在 resource 文件夹的 static 目录下。

演示页面

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Spring Boot+WebSocket+广播式</title>

</head>
<body onload="disconnect()">
<noscript><h2 style="color: #ff0000">貌似你的浏览器不支持websocket</h2></noscript>
<div>
    <div>
        <button id="connect" onclick="connect();">连接</button>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button>
    </div>
    <div id="conversationDiv">
        <label>输入你的名字</label><input type="text" id="name" />
        <button id="sendName" onclick="sendName();">发送</button>
        <p id="response"></p>
    </div>
</div>
<script th:src="@{sockjs.min.js}"></script>
<script th:src="@{stomp.min.js}"></script>
<script th:src="@{jquery.js}"></script>
<script type="text/javascript">
    var stompClient = null;

    function setConnected(connected) {
        document.getElementById('connect').disabled = connected;
        document.getElementById('disconnect').disabled = !connected;
        document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
        $('#response').html();
    }

    function connect() {
        // 连接 SockJs 的 endpoint 名称为 "/endpointNasus"
        var socket = new SockJS('/endpointNasus'); 
        // 使用 STOMP 子协议的 WebSocket 客户端
        stompClient = Stomp.over(socket); 
        stompClient.connect({}, function(frame) {
            setConnected(true);
            console.log('Connected: ' + frame);
            // 通过 stompClient.subscribe 订阅 /nasus/getResponse 目标发送的信息,对应控制器的 SendTo 定义
            stompClient.subscribe('/nasus/getResponse', function(respnose){
            // 展示返回的信息,只要订阅了 /nasus/getResponse 目标,都可以接收到服务端返回的信息
            showResponse(JSON.parse(respnose.body).responseMessage);
            });
        });
    }


    function disconnect() {
        // 断开连接
        if (stompClient != null) {
            stompClient.disconnect();
        }
        setConnected(false);
        console.log("Disconnected");
    }

    function sendName() {
        // 向服务端发送消息
        var name = $('#name').val();
        // 通过 stompClient.send 向 /hello (服务端)发送信息,对应控制器 @MessageMapping 中的定义
        stompClient.send("/hello", {}, JSON.stringify({ 'name': name }));
    }

    function showResponse(message) {
          // 接收返回的消息
          var response = $("#response");
          response.html(message);
    }
</script>
</body>
</html>

页面 Controller

注意,这里使用的是 @Controller 注解,用于匹配 html 前缀,加载页面。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Controller
public class ViewController {

    @GetMapping("/nasus")
    public String getView(){
        return "nasus";
    }
}

测试结果

打开三个窗口访问 http://localhost:8080/nasus ,初始页面长这样:

初始页面

三个页面全部点连接,点击连接订阅 endpoint ,如下图:

点击连接订阅 endpoint

点击连接订阅 endpoint

点击连接订阅 endpoint

在第一个页面,输入名字,点发送 ,如下图:

输入名字,点发送

在第一个页面发送消息,等待 3 秒,结果是 3 个页面都接受到了服务端返回的信息,广播成功。

第一个页面结果

第二个页面结果

第三个页面结果

源码下载:

https://github.com/turoDog/Demo/tree/master/springboot_websocket_demo

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一个优秀的废人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
SpringCloudGateway笔记(10)-websocket
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
yingzi_code
2019/08/30
3.1K0
Springboot整合Websocket实现一对一消息推送和广播消息推送
同时因为控制器有注解@SendTo所以会向@SendTo的地址广播消息,客户端订阅了广播地址所有控制台显示接收了消息
业余草
2020/06/23
2.1K0
Springboot整合Websocket实现一对一消息推送和广播消息推送
在Spring Boot框架下使用WebSocket实现消息推送
按:最近公众号文章主要是整理一些老文章,以个人CSDN上的博客为主,也会穿插一些新的技术点。 ---- Spring Boot的学习持续进行中。前面两篇博客我们介绍了如何使用Spring Boot容器搭建Web项目(使用Spring Boot开发Web项目/http://blog.csdn.net/u012702547/article/details/53784992)以及怎样为我们的Project添加HTTPS的支持(使用Spring Boot开发Web项目(二)之添加HTTPS支持/http://blo
江南一点雨
2018/04/02
3.1K0
在Spring Boot框架下使用WebSocket实现消息推送
springboot整合websocket实现消息推送
maven依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" x
似水的流年
2018/06/20
2.5K1
Spring Boot实现带STOMP的WebSocket
WebSocket协议是应用程序处理实时消息的方法之一。最常见的替代方案是长轮询(long polling)和服务器推送事件(server-sent events)。这些解决方案中的每个都有其优缺点。在本文中,我将向您展示如何使用 SpringBoot实现 WebSocket。我将介绍服务器端和客户端设置,使用 WebSocket协议之上的 STOMP进行相互通信。
乱敲代码
2019/06/26
5.7K0
基于spring boot 2.x的websocket示例
spring boot 2/spring 5自带了websocket,下面是最基本的示例(包括java服务端、java客户端以及js客户端)
菩提树下的杨过
2018/10/10
2K0
基于spring boot 2.x的websocket示例
手把手搭建WebSocket多人在线聊天室
https://www.callicoder.com/spring-boot-websocket-chat-example/
Java3y
2019/08/27
4.7K1
手把手搭建WebSocket多人在线聊天室
Spring国际认证指南:使用 WebSocket 构建交互式 Web 应用程序
本指南将引导您完成创建“Hello, world”应用程序的过程,该应用程序在浏览器和服务器之间来回发送消息。WebSocket 是 TCP 之上的一个轻量级的薄层。这使得它适合使用“子协议”来嵌入消息。在本指南中,我们使用带有 Spring 的STOMP消息传递来创建交互式 Web 应用程序。STOMP 是在较低级别的 WebSocket 之上运行的子协议。
IT胶囊
2022/04/08
2K0
使用消息队列轻松实现 分布式 webSocket
简单的概括一下:如果我们的项目是分布式环境,登录的用户被Nginx的反向代理分配到多个不同服务器,那么在其中一个服务器建立了WebSocket连接的用户如何给在另外一个服务器上建立了WebSocket连接的用户发送消息呢?
码猿技术专栏
2023/09/07
6290
使用消息队列轻松实现 分布式 webSocket
Spring Boot Web Socket
在本章中,将了解和学习如何使用Spring Boot with Web套接字构建交互式Web应用程序。要使用Web套接字在Spring Boot中构建交互式Web应用程序,需要添加以下依赖项。Maven用户应在pom.xml 文件中添加以下依赖项。
黑洞代码
2021/11/09
7000
Spring Boot Web Socket
使用消息队列实现 分布式 webSocket
陈某的《Spring Cloud Alibaba实战项目》 视频教程已经录完了,涉及到Alibaba的各种中间件、OAuth2微服务认证鉴权、全链路灰度发布、分布式事务实战,戳这里--->Spring Cloud Alibaba 实战 视频专栏 开放订阅~
码猿技术专栏
2023/05/01
1.4K0
使用消息队列实现 分布式 webSocket
学习WebSocket
这些场景,都需要 服务器能主动实时的给浏览器或客户端推送消息,注意关键词是主动,还有实时!而在HTML5一统江湖之前,由于HTTP在推送场景下的"薄弱",我们需要借助一些复杂或者非标准的手段来实现。
Java3y
2019/11/21
1.4K0
第二十章:SpringBoot项目中使用WebSocket配置广播式通信
WebSocket为浏览器和服务端提供了双工异步通信的功能,浏览器可以向服务端发送消息,服务端也可以向浏览器发送消息。WebSocket需要浏览器的支持,目前大多数主流的浏览器都是支持的。 WebSocket是通过socket来实现双工异步通信能力的。但是直接使用WebSocket协议开发程序闲的特别繁琐,一般情况我们使用STOMP来实现交互。 SpringBoot在tomcat7内嵌版本就已经开始支持了WebSocket的支持,配置源码存在于org.springframework.boot.autocon
恒宇少年
2018/06/27
1.4K0
spring boot集成WebSocket实时输出日志到web页面
前言碎语 今天来做个有趣的东西,就是实时将系统日志输出的前端web页面,因为是实时输出,所有第一时间就想到了使用webSocket,而且在spring boot中,使用websocket超级方便,阅读本文,你会接触到以下关键词相关技术,WebSocket(stopmp服务端),stomp协议,sockjs.min.js,stomp.min.js(stomp客户端),本文使用到的其实就是使用spring boot自带的webSocket模块提供stomp的服务端,前端使用stomp.min.js做stomp的客户端,使用sockjs来链接,前端订阅后端日志端点的消息,后端实时推送,达到日志实时输出到web页面的目的,效果如下图
kl博主
2018/04/13
3.7K0
spring boot集成WebSocket实时输出日志到web页面
springboot整合websocket技术
简单来说就是一个基于TCP的持久化的网络通信协议。主要作用就是:服务端可以主动推送信息给客户端,不需要客户端重复的向服务端发请求查询。
海加尔金鹰
2020/06/09
1.1K0
RSocket vs WebSocket:Spring Boot 3.3 中的两大实时通信利器
RSocket vs WebSocket:Spring Boot 3.3 中的两大实时通信利器
程序员皮皮林
2024/10/23
1610
RSocket vs WebSocket:Spring Boot 3.3 中的两大实时通信利器
[WebSocket入门]手把手搭建WebSocket多人在线聊天室(SpringBoot+WebSocket)
https://www.callicoder.com/spring-boot-websocket-chat-example/
Rude3Knife的公众号
2019/08/16
2.8K0
[WebSocket入门]手把手搭建WebSocket多人在线聊天室(SpringBoot+WebSocket)
spring ws stomp接口式编程
在项目开发中,使用Websocket订阅可以实现实时推送数据更新和变化。但是,这也存在一些痛点。首先,Websocket订阅需要对订阅对象进行管理,确保订阅的准确性和及时性。其次,订阅的消息需要经过充分过滤和处理,以避免无效消息和重复消息的出现。同时,在高并发的情况下,Websocket订阅也需要进行限流和队列管理,以保证系统的稳定性和可靠性。除此之外,Websocket订阅还需要支持多种协议和格式,以适应不同类型的数据推送和处理场景。因此,在项目中使用Websocket订阅,需要充分考虑这些问题,确保系统的稳定性、可靠性和及时性。
查拉图斯特拉说
2023/10/25
3440
补习系列(20)-大话WebSocket与"尬聊"的实现
这些场景,都需要 服务器能主动实时的给浏览器或客户端推送消息,注意关键词是主动,还有实时!而在HTML5一统江湖之前,由于HTTP在推送场景下的"薄弱",我们需要借助一些复杂或者非标准的手段来实现。
美码师
2019/05/10
8340
补习系列(20)-大话WebSocket与"尬聊"的实现
SpringBoot 实战 (十七) | 整合 WebSocket 实现聊天室
昨天那篇介绍了 WebSocket 实现广播,也即服务器端有消息时,将消息发送给所有连接了当前 endpoint 的浏览器。但这无法解决消息由谁发送,又由谁接收的问题。所以,今天写一篇实现一对一的聊天室。
JavaFish
2019/10/17
1.5K0
SpringBoot 实战 (十七) | 整合 WebSocket 实现聊天室
推荐阅读
相关推荐
SpringCloudGateway笔记(10)-websocket
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验