Spring Websocket Stomp 消息订阅推送实战

本人项目环境:IDE为Intellij IDEA 2018.1.4,Java version 1.8.0_172,Tomcat version 8.5.32。
学习完这个DEMO,能对在基于stomp协议上使用Spring组件通信有一定了解,可将之应用到发送系统消息,建立聊天室等功能实践中。
项目下载地址:https://gitee.com/starCat/spring-websocket-stomp
话不多说,开始吧!这次使用Spring 4 零配置文件的方式建立项目
目录结构:
这里写图片描述

第一步,导入依赖

<properties>
        <spring.version>4.3.18.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
            <version>0.32-1</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>sockjs-client</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>stomp-websocket</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.1.0</version>
        </dependency>

    </dependencies>

**

第二步 建立程序入口

**,新建\spring-websocket-stomp\src\main\java\cn\justsoul\study\config\DispatcherServletInitializer.java类,继承自AbstractAnnotationConfigDispatcherServletInitializer,来快速implements WebApplicationInitializer。
这里要说的是WebApplicationInitializer这个接口是实现零配置文件的关键,无论你怎么实现了它,就可以以它的实现作为程序入口了。

public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { WebConfig.class, WebSocketConfig.class };
    }

    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
    @Override
    protected void customizeRegistration(Dynamic registration) {
        registration.setInitParameter("dispatchOptionsRequest", "true");
    }
}

第三步 (重点来了)创建配置类

新建\spring-websocket-stomp\src\main\java\cn\justsoul\study\config\WebConfig.java配置类,主要是配置SpringMVC

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "cn.justsoul.study.controller")
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/webjars/**").addResourceLocations("/webjars/")
                .resourceChain(false)
                .addResolver(new WebJarsResourceResolver())
                .addResolver(new PathResourceResolver());
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
    }

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
    }
}

新建\spring-websocket-stomp\src\main\java\cn\justsoul\study\config\WebSocketConfig.java类,进行WebSocket配置
这里要注意的是registry.enableSimpleBroker(“/topic”,”/queue”);和registry.setUserDestinationPrefix(“/queue”);两个配置项里都要有”/queue”,之后convertAndSendToUser(“user”, “destination”,”payload”);这个方法才能生效!!!

@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket-address").withSockJS();
    }
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic","/queue");//设置服务器广播消息的基础路径,可以是多个路径
        registry.setApplicationDestinationPrefixes("/app");//设置客户端订阅消息基础路径
        registry.setUserDestinationPrefix("/queue");//设置精准消息推送基础路径
    }
}

第四步 实现消息订阅推送

编写\spring-websocket-stomp\src\main\java\cn\justsoul\study\controller\TopicController.java类
这里科普一下@EnableScheduling与@Scheduled是Spring定时任务,没用过的了解一下:)

@Controller
public class TopicController {

    /*收到消息后广播推送*/
    @MessageMapping("/boardcast")
    @SendTo("/topic/boardcast")
    public String sendtousers(String s){
        System.out.println(s);
        return "我是广播消息";
    }

    /*收到消息后精准投送到单个用户*/
    @MessageMapping("/precise")
    /*broadcast = false避免把消息推送到同一个帐号不同的session中*/
    @SendToUser(value = "/topic/precise",broadcast = false)
    public String sendtouser(String s){
        System.out.println(s);
        return "我是精准投送消息";
    }


    private SimpMessagingTemplate template;
    @Autowired
    public TopicController (SimpMessagingTemplate template) {
        this.template = template;
    }
    /*下面2个是不用接收消息动态发送消息的方法*/
    /*Scheduled为定时任务,演示*/
    @Scheduled(fixedDelay = 1500)
    public void boardcast(){
        this.template.convertAndSend("/topic", "来自服务器广播消息");
    }

    @Scheduled(fixedDelay = 1500)
    public void precise(){
        this.template.convertAndSendToUser("abc", "/message","来自服务器精准投送消息");
    }

}

前端测试页面
\spring-websocket-stomp\src\main\webapp\WEB-INF\jsp\index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>spring-websocket-stomp</title>
  </head>
  <body>
  <h1>spring-websocket-stomp</h1>
  <button id="btn-send">广播消息</button>
  <button id="btn-send2">精准投送消息</button>
  <button id="btn-send3">动态广播</button>
  <button id="btn-send4">动态精准投送</button>
  </body>
</html>
<script src="webjars/jquery/jquery.min.js"></script>
<script src="webjars/sockjs-client/sockjs.min.js"></script>
<script src="webjars/stomp-websocket/stomp.min.js"></script>
<script src="js/app.js"></script>

\spring-websocket-stomp\src\main\webapp\js\app.js

var stompClient = null;
var subscription = null;
$(function () {
   var ws = new SockJS("/websocket-address");
    stompClient = Stomp.over(ws);
    stompClient.connect({'client-id': 'my-client'},function () {
    });

    $("#btn-send").click(function () {
        if(subscription != null){subscription.unsubscribe();}
        subscription = stompClient.subscribe("/topic/boardcast", function(){});
        stompClient.send("/app/boardcast",{},"请求广播");
    });
    $("#btn-send2").click(function () {
        if(subscription != null){subscription.unsubscribe();}
        subscription = stompClient.subscribe("/queue/topic/precise", function(){});
        stompClient.send("/app/precise",{},"请求精准投送");
    });
    // 请求动态广播
    $("#btn-send3").click(function () {
        if(subscription != null){subscription.unsubscribe();}
        subscription = stompClient.subscribe("/topic", function(){});
    });
    // 请求精准投送
    $("#btn-send4").click(function () {
        if(subscription != null){subscription.unsubscribe();}
        subscription = stompClient.subscribe("/queue/abc/message", function(){});
    });
});

大功告成,运行一下,使用浏览器控制台看看效果吧,就像这样:)
这里写图片描述

注意websocket请求地址要结合你自己的环境配置正确设置,一定不要弄错了哦。

猜你喜欢

转载自blog.csdn.net/chinatreeqy/article/details/81115296