zoukankan      html  css  js  c++  java
  • springboot websocket的封装js ,STOMP使用

    参考地址:https://blog.csdn.net/m0_37542889/article/details/83750665

    1、启用STOMP功能

        STOMP 的消息根据前缀的不同分为三种。如下,以 /app 开头的消息都会被路由到带有@MessageMapping 或 @SubscribeMapping 注解的方法中;以/topic 或 /queue 开头的消息都会发送到STOMP代理中,根据你所选择的STOMP代理不同,目的地的可选前缀也会有所限制;以/user开头的消息会将消息重路由到某个用户独有的目的地上。

     View Code

    2、处理来自客户端的STOMP消息

        服务端处理客户端发来的STOMP消息,主要用的是 @MessageMapping 注解。如下:

      @MessageMapping("/marco")
      @SendTo("/topic/marco")
      public Shout stompHandle(Shout shout){
          LOGGER.info("接收到消息:" + shout.getMessage());
          Shout s = new Shout();
          s.setMessage("Polo!");
          return s;
      }

        2.1、@MessageMapping 指定目的地是“/app/marco”(“/app”前缀是隐含的,因为我们将其配置为应用的目的地前缀)。

        2.2、方法接收一个Shout参数,因为Spring的某一个消息转换器会将STOMP消息的负载转换为Shout对象。Spring 4.0提供了几个消息转换器,作为其消息API的一部分:

        2.3、尤其注意,这个处理器方法有一个返回值,这个返回值并不是返回给客户端的,而是转发给消息代理的,如果客户端想要这个返回值的话,只能从消息代理订阅。@SendTo 注解重写了消息代理的目的地,如果不指定@SendTo,帧所发往的目的地会与触发处理器方法的目的地相同,只不过会添加上“/topic”前缀。

        2.4、如果客户端就是想要服务端直接返回消息呢?听起来不就是HTTP做的事情!即使这样,STOMP 仍然为这种一次性的响应提供了支持,用的是@SubscribeMapping注解,与HTTP不同的是,这种请求-响应模式是异步的...

       @SubscribeMapping("/getShout")
       public Shout getShout(){
           Shout shout = new Shout();
           shout.setMessage("Hello STOMP");
           return shout;
       }

    3、发送消息到客户端

    3.1 在处理消息之后发送消息

        正如前面看到的那样,使用 @MessageMapping 或者 @SubscribeMapping 注解可以处理客户端发送过来的消息,并选择方法是否有返回值。

        如果 @MessageMapping 注解的控制器方法有返回值的话,返回值会被发送到消息代理,只不过会添加上"/topic"前缀。可以使用@SendTo 重写消息目的地;

        如果 @SubscribeMapping 注解的控制器方法有返回值的话,返回值会直接发送到客户端,不经过代理。如果加上@SendTo 注解的话,则要经过消息代理。

    3.2 在应用的任意地方发送消息

        spring-websocket 定义了一个 SimpMessageSendingOperations 接口(或者使用SimpMessagingTemplate ),可以实现自由的向任意目的地发送消息,并且订阅此目的地的所有用户都能收到消息。

      @Autowired
      private SimpMessageSendingOperations simpMessageSendingOperations;
    
    
      /**
      * 广播消息,不指定用户,所有订阅此的用户都能收到消息
      * @param shout
      */
      @MessageMapping("/broadcastShout")
      public void broadcast(Shout shout) {
          simpMessageSendingOperations.convertAndSend("/topic/shouts", shout);
      }

    3.3 为指定用户发送消息

        3.2介绍了如何广播消息,订阅目的地的所有用户都能收到消息。如果消息只想发送给特定的用户呢?spring-websocket 介绍了两种方式来实现这种功能,一种是 基于@SendToUser注解和Principal参数,一种是SimpMessageSendingOperations 接口的convertAndSendToUser方法。

    • 基于@SendToUser注解和Principal参数

        @SendToUser 表示要将消息发送给指定的用户,会自动在消息目的地前补上"/user"前缀。如下,最后消息会被发布在  /user/queue/notifications-username。但是问题来了,这个username是怎么来的呢?就是通过 principal 参数来获得的。那么,principal 参数又是怎么来的呢?需要在spring-websocket 的配置类中重写 configureClientInboundChannel 方法,添加上用户的认证。

     spring-websocket 用户认证

      @MessageMapping("/shout")
      @SendToUser("/queue/notifications")
      public Shout userStomp(Principal principal, Shout shout) {
            String name = principal.getName();
            String message = shout.getMessage();
            LOGGER.info("认证的名字是:{},收到的消息是:{}", name, message);
            return shout;
      }
    • convertAndSendToUser方法

        除了convertAndSend()以外,SimpMessageSendingOperations 还提供了convertAndSendToUser()方法。按照名字就可以判断出来,convertAndSendToUser()方法能够让我们给特定用户发送消息。

        @MessageMapping("/singleShout")
        public void singleUser(Shout shout, StompHeaderAccessor stompHeaderAccessor) {
            String message = shout.getMessage();
            LOGGER.info("接收到消息:" + message);
            Principal user = stompHeaderAccessor.getUser();
            simpMessageSendingOperations.convertAndSendToUser(user.getName(), "/queue/shouts", shout);
        }

        如上,这里虽然我还是用了认证的信息得到用户名。但是,其实大可不必这样,因为 convertAndSendToUser 方法可以指定要发送给哪个用户。也就是说,完全可以把用户名的当作一个参数传递给控制器方法,从而绕过身份认证!convertAndSendToUser 方法最终会把消息发送到 /user/sername/queue/shouts 目的地上。

  • 相关阅读:
    Glide只播放一次Gif以及监听播放完成的实现方案
    Android 插件化开发(四):插件化实现方案
    Android 插件化开发(三):资源插件化
    Android 插件化开发(二):加载外部Dex文件
    Android 插件化开发(一):Java 反射技术介绍
    Android框架式编程之架构方案
    Android 项目优化(六):项目开发时优化技巧总结
    Android 项目优化(五):应用启动优化
    Android 项目优化(四):内存优化
    Android 项目优化(三):MultiDex 优化
  • 原文地址:https://www.cnblogs.com/hcklqy/p/11898530.html
Copyright © 2011-2022 走看看