服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - 基于Spring Boot,一步步教你用Websockets和STOMP进行消息推送

基于Spring Boot,一步步教你用Websockets和STOMP进行消息推送

2023-12-21 13:21Java学研大本营 Java教程

在本文中,我们学习了如何使用Spring Boot应用程序、WebSockets和STOMP协议发送推送通知。如果希望使用外部的ActiveMQ实例,只需将其连接到应用程序,因为ActiveMQ也支持STOMP协议。

1 引言

推送通知是一种实时消息传递形式,通过它网站可以向用户实时通知特定事件。通常使用WebSockets实现推送通知,这种技术提供了客户端和服务器之间的双向通信,从而实现了实时消息的处理。

本文使用WebSockets来实现推送通知,并使用STOMP协议在客户端和服务器之间进行通信。

2 什么是STOMP

STOMP代表简单文本导向的消息协议(Simple Text Oriented Messaging Protocol)。由于WebSockets是一种低级协议,使用帧(frames)来传输数据,而STOMP是一种高级协议,定义了如何解释某些帧类型中的数据。这些帧类型包括CONNECT、SEND、ACK等。因此,使用STOMP能够更加简化使用WebSockets进行数据的发送、接收和解析过程。

有了这个基础,接下来创建服务器应用程序。

3 创建一个应用程序

到https://start.spring.io创建一个Spring Boot应用程序,并添加以下依赖项:

Spring Boot Starter Websockets

现在,使用一个嵌入式消息代理,它将是一个提供WebSocket功能的内存中代理。给代理添加一些目的地。这些目的地指的是将要发送消息的路径。

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/all","/specific");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
         registry.addEndpoint("/ws");
         registry.addEndpoint("/ws").withSockJS();
    }
}

在第一部分中,启用了一个带有两个目的地(/all和/specific)的代理。/all目的地将用于向所有用户发送通知,/specific目的地用于向特定用户发送通知。

接下来,设置应用程序的目的地,即 /app,这样就可以向应用程序发送信息了。

在第二部分中,注册了STOMP端点。其中一个启用了SockJS,另一个仅使用WebSocket。之所以这样做,是因为并非所有浏览器都支持WebSocket,当不可用时,可以回退到使用SockJS。

4 向所有用户发送推送通知

先看一下第一个用例,即向所有用户发送推送通知。

为此,首先实现一个控制器,该控制器会把来自一个客户端的信息转发给所有客户端。

@org.springframework.stereotype.Controller
public class Controller {

    @Autowired
    SimpMessagingTemplate simpMessagingTemplate;

    @MessageMapping("/application")
    @SendTo("/all/messages")
    public Message send(final Message message) throws Exception {
        return message;
    }
}

在上面的代码中,我们接受/application端点上的消息。这实际上是之前定义的应用程序目的地/app的子目的地。这意味着客户端必须把消息发送到/app/application目的地才能到达该处理程序。

接下来,把传入的消息转发到/all/messages。现在,订阅该目的地的所有客户端都将收到发送给所有客户端的消息。

来看看HTML页面上的客户端代码:

  1. < script type="text/javascript"
  2.         var stompClient = null
  3.  
  4.         var socket = new SockJS('/ws'); 
  5.         stompClient = Stomp.over(socket); 
  6.         stompClient.connect({}, function(frame) { 
  7.             console.log(frame); 
  8.             stompClient.subscribe('/all/messages'function(result) { 
  9.                 show(JSON.parse(result.body)); 
  10.             }); 
  11.         }); 

在这里,使用一个STOMP客户端,在WebSocket上建立连接,然后订阅/all/messages上的消息。

现在,为了将消息发送给应用程序,有以下的JavaScript函数,它将消息发送到/app/application:

function sendMessage() {
    var text = document.getElementById('text').value;
    stompClient.send("/app/application", {},
      JSON.stringify({'from':from, 'text':text}));
}

它简单地从文本字段中获取文本值,并将其发送到代理的应用程序目标。

这是通过下面显示的一个简单表单进行连接的。

基于Spring Boot,一步步教你用Websockets和STOMP进行消息推送图片

为了测试这个,我们向所有连接的客户端发送一个推送通知"Notification to all"。

基于Spring Boot,一步步教你用Websockets和STOMP进行消息推送图片

这里有两个连接的客户端,两个客户端都立即收到了通知。

现在,在这里只是显示了从WebSocket接收到的内容,但可以根据需要使用CSS和JavaScript来自定义通知弹出窗口或通知标签。

这就是如何向所有用户发送通知。那么如何向特定用户发送通知呢?

5 向特定用户发送推送通知

要向特定用户发送通知,我们需要收件人的用户ID。这意味着接收方用户需要登录并提供一个有效的会话来标识用户的用户ID。

为此,我们将集成Spring Security。因此,添加以下依赖项。

Spring Boot Starter Security

添加了Spring Security依赖项后,我们需要定义一个安全配置来允许使用WebSockets进行连接。

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
            .authorizeHttpRequests()
                .mvcMatchers("/","/ws/**")
                .permitAll()
            .and()
            .authorizeHttpRequests()
                .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .logout( logout -> logout.logoutSuccessUrl("/"));
    return http.build();
}

@Bean
public InMemoryUserDetailsManager userDetailsService() {
    UserDetails user = User.withDefaultPasswordEncoder()
            .username("test")
            .password("test")
            .roles("USER")
            .build();

    return new InMemoryUserDetailsManager(user);
}

在这里,我们允许所有连接到/ws路径的连接,以便在没有任何身份验证的情况下进行WebSocket通信,还定义了一个名为"test"的静态用户。

还记得在上面的消息代理设置中创建的/specific目标吗?现在将使用它来发送特定的消息。

首先,在控制器中添加一个处理程序,用于接收消息并将其发送给特定的用户,这些用户将使用它们的用户名进行标识。

@org.springframework.stereotype.Controller
public class Controller {

    @Autowired
    SimpMessagingTemplate simpMessagingTemplate;

    @MessageMapping("/application")
    @SendTo("/all/messages")
    public Message send(final Message message) throws Exception {
        return message;
    }

    @MessageMapping("/private")
    public void sendToSpecificUser(@Payload Message message) {
        simpMessagingTemplate.convertAndSendToUser(message.getTo(), "/specific", message);
    }
}

现在,在sendToSpecificUser方法中,我们接受使用/app/private发送的消息。消息包含要发送给接收者的文本以及接收者的用户ID。

消息模板所做的是将消息发送到以/user开头的目标,然后将其附加到我们在convertAndSendToUser函数调用中指定的目标,即/specific,然后附加所指定的用户的用户会话ID。

因此,convertAndSendToUser将消息发送到目标/user/specific-。这个目标是在用户登录并订阅/user/specific时创建的。

当用户登录并订阅/user/specific时,它会发送有效的已登录会话ID。然后,Spring自动处理订阅/user/specific将自动订阅已登录用户的特定目标,即/user/specific-

这也意味着只有用户登录时才能发送通知。

现在,添加一个新的文本块并订阅用户特定的目标。

socket = new SockJS('/ws');
privateStompClient = Stomp.over(socket);
privateStompClient.connect({}, function(frame) {
        console.log(frame);
        privateStompClient.subscribe('/user/specific', function(result) {
        console.log(result.body)
            show(JSON.parse(result.body));
        });
    });

基于Spring Boot,一步步教你用Websockets和STOMP进行消息推送图片

打开两个客户端,并使用"test"用户登录第二个客户端。可以使用/login端点触发登录。

在上面的图像中,正在以"test"用户登录第二个客户端。

登录后,首先向所有客户端发送消息。

基于Spring Boot,一步步教你用Websockets和STOMP进行消息推送图片

所以,即使已登录的用户也会收到发送给所有客户端的通知。

现在,向"test"用户发送一个私有通知。

基于Spring Boot,一步步教你用Websockets和STOMP进行消息推送图片

在上面的图像中,我们为特定用户提供了一条消息,并指定了特定用户的用户ID,即"test",通知只会传递给已登录的用户。

这是一个关于它是如何工作的简短演示。

基于Spring Boot,一步步教你用Websockets和STOMP进行消息推送图片

6 结语

在本文中,我们学习了如何使用Spring Boot应用程序、WebSockets和STOMP协议发送推送通知。如果希望使用外部的ActiveMQ实例,只需将其连接到应用程序,因为ActiveMQ也支持STOMP协议。这样,我们就可以通过应用程序将消息中继到外部的ActiveMQ实例,实现更灵活和可定制的消息传递。通过这种方式,可以轻松地实现推送通知功能,为用户提供实时的信息更新和交互体验。希望这篇文章对读者有所帮助!

原文地址:原文地址:https://mp.weixin.qq.com/s/F7iU1KugDTutqQ5aedPwZQ

延伸 · 阅读

精彩推荐
  • Java教程聊聊java并发编程的十个坑

    聊聊java并发编程的十个坑

    说实话,在Java中并发编程不光理解起来比较费劲,使用起来更容易踩坑。今天重点跟大家一起聊聊并发编程的十个坑,希望对你有帮助。...

    苏三说技术10892022-03-09
  • Java教程Java实现添加条码或二维码到Word文档

    Java实现添加条码或二维码到Word文档

    这篇文章主要介绍了如何在Word文档中添加条码、二维码。可在文档正文段落中添加,也可在页眉页脚中添加,感兴趣的小伙伴快跟随小编一起学习一下吧...

    E-iceblue8002023-02-09
  • Java教程解决java.sql.SQLException: validateConnection false问题的方法汇总(最全)

    解决java.sql.SQLException: validateConnection false问题的方法汇总(最全

    这篇文章主要给大家介绍了关于解决java.sql.SQLException: validateConnection false问题的方法汇总,文中通过图文介绍的非常详细,需要的朋友可以参考下...

    xingsy_hn10122023-03-05
  • Java教程详解springboot集成mybatis xml方式

    详解springboot集成mybatis xml方式

    这篇文章主要介绍了详解springboot集成mybatis xml方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    奔跑的蜗牛6252021-05-18
  • Java教程Java基础第三篇 构造器与方法重载

    Java基础第三篇 构造器与方法重载

    显式初始化要求我们在写程序时就确定初始值,这有时很不方便。我们可以使用构造器(constructor)来初始化对象。构造器可以初始化数据成员,还可以规定特...

    Vamei8052021-12-25
  • Java教程怎么在AVD上安装apk软件

    怎么在AVD上安装apk软件

    执行 Windows 开始菜单 => 所有程序 => 附件 => 命令提示符 或通过 Win+R 组合键调出 运行 对话框输入cmd 单击确定即可 ...

    java教程网5772019-10-14
  • Java教程java代理模式与动态代理模式详解

    java代理模式与动态代理模式详解

    代理就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户...

    java技术网2392019-11-06
  • Java教程Spring使用注解方式处理事务

    Spring使用注解方式处理事务

    这篇文章主要为大家详细介绍了Spring使用注解方式处理事务,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    少年啊!4392022-08-26