springboot 之 webscoket 服務端推送

因爲最近有後端實時推送數據的需求,所以想到了websocket組件,在此寫一下springboot集成使用websocket的方法,供各位童鞋參考。

注:基於test項目。

1.首先打開pom.xml引入相關依賴

<!-- webSocket -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- thymeleaf模板引擎 -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2.編寫websocket配置文件:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //註冊STOMP協議的節點(endpoint),並映射指定的url
        //註冊一個STOMPendpoint,並指定使用SockJS協議
        // 允許使用socketJs方式訪問,訪問點爲webSocketServer,允許跨域
        // 在網頁上我們就可以通過這個鏈接來和服務器的WebSocket連接
        registry.addEndpoint("/endpointTest").setAllowedOrigins("*").withSockJS();

    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //配置消息代理(Message Broker)
        //廣播式應配置一個/topic消息代理
        //queue 點對點
        registry.enableSimpleBroker("/queue","/topic");

    }
}

3.webmvc配置

/**
 * @author xiaofeng
 * @version V1.0
 * @title: WebMvcConfig.java
 * @package: com.yingda.xsignal.test
 * @description: 配置viewController, 爲頁面提供路徑映射
 * @date 2018/3/30 0030 下午 7:05
 */
@Controller
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    /**
     * 配置viewController,提供映射路徑
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/webSocket").setViewName("/webSocket");
    }
}

4.websocket控制器

/**
 * @author xiaofeng
 * @version V1.0
 * @title: WebSocketController.java
 * @package: com.yingda.xsignal.test
 * @description: webSocket控制器
 * @date 2018/3/30 0030 下午 7:04
 */
@RestController
@EnableScheduling
public class WebSocketController {

    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 當瀏覽器向服務端發送請求時,通過@MessageMapping映射/sendTest這個地址,類似於@ResponseMapping
     * 當服務器有消息時,會對訂閱了@SendTo中的路徑的瀏覽器發送消息
     *
     * @param message
     * @return
     */
    @MessageMapping("/sendTest")
    @SendTo("/topic/responseTest")
    public String say(String message) {
        try {
            //睡眠1            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return message;
    }


    @SubscribeMapping("/topic/responseTest")
    public String sub() {
        logger.info("X用戶訂閱了");
        return "thanks for your subscribe!";
    }


    @Autowired
    WebSocketTemplate webSocketTemplate;

    /**
     * 模擬服務端推送數據(注:必須在同一個服務內,否則無法進行訂閱推送)
     */
    @Scheduled(fixedRate = 2000)
    public void task() {
        webSocketTemplate.sendMessage("服務器端推送~" + UUID.randomUUID());
    }

}


WebSocketTemplate:

/**
 * @author xiaofeng
 * @version V1.0
 * @title: WebSocketTemplate.java
 * @package: com.yingda.xsignal.test.websocket.send
 * @description: webSocket發送模板
 * @date 2018/3/30 0030 下午 3:57
 */
@Component
public class WebSocketTemplate {
    private SimpMessagingTemplate messagingTemplate;

    @Autowired
    public WebSocketTemplate(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    /**
     * 向訂閱了 /topic/responseTest 客戶端websocket實例發送數據
     *
     * @param message
     */
    public void sendMessage(String message) {
        AricMessage aricMessage = new AricMessage();
        aricMessage.setName(message);
        messagingTemplate.convertAndSend("/topic/responseTest", aricMessage);
    }
}

5.在resources -> templates中創建html文件

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>SpringBoot 服務端推送消息</title>
    <script src="http://cdn.bootcss.com/sockjs-client/1.1.1/sockjs.min.js"></script>
    <script src="http://cdn.bootcss.com/stomp.js/2.3.3/stomp.js"></script>
    <script src="http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div>
    <div>
        <button id="connect" onclick="connect();">connect</button>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">disconnect</button>
    </div>
    <div id="conversationDiv">
        <div id="response"></div>
    </div>
</div>
</body>
<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(){
        var socket = new SockJS('/endpointTest'); //連接SockJSendpoint名稱爲"endpointTest"
        stompClient = Stomp.over(socket);//使用STMOP子協議的WebSocket客戶端
        stompClient.connect({},function(frame){//連接WebSocket服務端
            setConnected(true);
            console.log('Connected:' + frame);
            //通過stompClient.subscribe訂閱/topic/responseTest 目標(destination)發送的消息,這個是在控制器的@SentTo中定義的
            stompClient.subscribe('/topic/responseTest',function(response){
                showResponse(JSON.parse(response.body).name);
            });
        });
    }

    function disconnect(){
        if(stompClient != null) {
            stompClient.disconnect();
        }
        setConnected(false);
        console.log("Disconnected");
    }

    function showResponse(message){
        var response = $("#response");
        response.html(message);
    }
</script>
</html>

啓動服務,測試,點擊connect,發現每隔幾秒隨機字符串都會發生變化,說明後臺服務一直在向前端推送數據


ok,至此我們的springboot集成websocket並向前端推送數據成功,congratulation!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章