springboot websocket簡單入門

以前作的需求都是客戶端請求服務器響應,新需求是服務器主動推送信息到客戶端.百度以後有流、長輪詢、websoket等方式進行.可是目前更加推崇且合理的顯然是websocket.

從springboot官網翻譯了一些資料,再加上百度簡單實現了springboot使用websocekt與客戶端的雙工通訊.html

1.首先搭建一個簡單的springboot環境

<!-- Inherit defaults from Spring Boot -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
    </parent>

    <!-- Add typical dependencies for a web application -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

2.引入springboot整合websocket依賴

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-websocket -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
    <version>2.0.4.RELEASE</version>
</dependency>

3.建立啓動springboot的核心類

package com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GlobalConfig {
    public static void main(String[] args) {
        SpringApplication.run(GlobalConfig.class, args);
    }
}

4.建立websocket服務器

正如springboot 官網推薦的websocket案例,須要實現WebSocketHandler或者繼承TextWebSocketHandler/BinaryWebSocketHandler當中的任意一個.html5

package com.xiaoer.handler;

import com.alibaba.fastjson.JSONObject;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.HashMap;
import java.util.Map;

/**
 * 至關於controller的處理器
 */
public class MyHandler extends TextWebSocketHandler {
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        Map<String, String> map = JSONObject.parseObject(payload, HashMap.class);
        System.out.println("=====接受到的數據"+map);
        session.sendMessage(new TextMessage("服務器返回收到的信息," + payload));
    }
}

5.註冊處理器

package com.xiaoer.config;

import com.xiaoer.handler.MyHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "myHandler/{ID}");
    }
    public WebSocketHandler myHandler() {
        return new MyHandler();
    }

}

6.運行訪問

clipboard.png
出現如上圖是由於不能直接經過http協議訪問,須要經過html5的ws://協議進行訪問.java

7.建立Html5 客戶端

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <input id="text" type="text" />
        <button onclick="send()">Send</button>    
        <button onclick="closeWebSocket()">Close</button>
        <div id="message">
        </div>
        <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
        <script>
            
            var userID="888";
            var websocket=null;

            $(function(){
                connectWebSocket();
            })
            
            //創建WebSocket鏈接
            function connectWebSocket(){

                console.log("開始...");
              
              //創建webSocket鏈接
               websocket = new WebSocket("ws://127.0.0.1:8080/myHandler/ID="+userID);
              
              //打開webSokcet鏈接時,回調該函數
               websocket.onopen = function () {      
                    console.log("onpen");  
               }
               
               //關閉webSocket鏈接時,回調該函數
               websocket.onclose = function () {
               //關閉鏈接    
                    console.log("onclose");
               }

               //接收信息
               websocket.onmessage = function (msg) {
                    console.log(msg.data);
               }

            }
            //發送消息
            function send(){
                var postValue={};
                postValue.id=userID;
                postValue.message=$("#text").val();          
                websocket.send(JSON.stringify(postValue));
            }
            //關閉鏈接
            function closeWebSocket(){
                if(websocket != null) {
                    websocket.close();
                }
            }
        </script>
    </body>
</html>

8.運行

clipboard.png
利用客戶端運行以後仍然會出現上圖中的一鏈接就中斷了websocket鏈接.
這是由於spring默認不接受跨域訪問:jquery

As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is to accept only same origin requests.

須要在WebSocketConfig中設置setAllowedOrigins.web

package com.xiaoer.config;

import com.xiaoer.handler.MyHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "myHandler/{ID}")
            .setAllowedOrigins("*");
    }
    public WebSocketHandler myHandler() {
        return new MyHandler();
    }

}

以下圖,並未輸出中斷,說明鏈接成功.
clipboard.pngspring

9.服務器和客戶端的相互通訊

服務器端收到消息
clipboard.png
客戶端收到服務器主動推送消息
clipboard.pngjson

以上就是一個最基礎的springboot簡單應用.還能夠經過攔截器、重寫WebSocketConfigurer中的方法進行更爲複雜的屬性操做.具體能夠參考SpringBoot集成WebSocket【基於純H5】進行點對點[一對一]和廣播[一對多]實時推送跨域

相關文章
相關標籤/搜索