1. 程式人生 > >WebSocket的使用(基於VUE與SpringBoot)

WebSocket的使用(基於VUE與SpringBoot)

WebSocket 是 HTML5 開始提供的一種在單個 TCP 連線上進行全雙工通訊的協議。
WebSocket 使得客戶端和伺服器之間的資料交換變得更加簡單,允許服務端主動向客戶端推送資料。在 WebSocket API 中,瀏覽器和伺服器只需要完成一次握手,兩者之間就直接可以建立永續性的連線,並進行雙向資料傳輸。

在 WebSocket API 中,瀏覽器和伺服器只需要做一個握手的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道。兩者之間就直接可以資料互相傳送。

現在,很多網站為了實現推送技術,所用的技術都是 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對伺服器發出HTTP請求,然後由伺服器返回最新的資料給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器需要不斷的向伺服器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的資料可能只是很小的一部分,顯然這樣會浪費很多的頻寬等資源。

HTML5 定義的 WebSocket 協議,能更好的節省伺服器資源和頻寬,並且能夠更實時地進行通訊。

詳細的WebSocket介紹請參考菜鳥教程WebSocket

因為近期所使用的技術棧為VUE和SpringBoot,因此此文章所用技術環境也為VUE以及SpringBoot下。

建議先在後端(SpringBoot)配置好WebSocket。

maven依賴(因為我的SpringBoot專案為2.0以上,會自動選擇最優版本,因此此處沒有帶上版本號):


<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

WebSocket配置類


@Configuration
public class WebSocketConfig {
     /**
     * 注入ServerEndpointExporter,
     * 這個bean會自動註冊使用了@ServerEndpoint註解宣告的Websocket endpoint
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
    
}

WebSocket操作類


WebSocket的向用戶推送可以為向所有使用者推送以及單點推送

@Component
@ServerEndpoint("/websocket/{shopId}")
//此註解相當於設定訪問URL
public class WebSocket {
    
    private Session session;
    
    private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();
    private static Map<String,Session> sessionPool = new HashMap<String,Session>();
    
    @OnOpen
    public void onOpen(Session session, @PathParam(value="shopId")String shopId) {
        this.session = session;
        webSockets.add(this);
        sessionPool.put(shopId, session);
        System.out.println("【websocket訊息】有新的連線,總數為:"+webSockets.size());
    }
    
    @OnClose
    public void onClose() {
        webSockets.remove(this);
        System.out.println("【websocket訊息】連線斷開,總數為:"+webSockets.size());
    }
    
    @OnMessage
    public void onMessage(String message) {
        System.out.println("【websocket訊息】收到客戶端訊息:"+message);
    }
    
    // 此為廣播訊息
    public void sendAllMessage(String message) {
        for(WebSocket webSocket : webSockets) {
            System.out.println("【websocket訊息】廣播訊息:"+message);
            try {
                webSocket.session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    // 此為單點訊息
    public void sendOneMessage(String shopId, String message) {
        Session session = sessionPool.get(shopId);
        if (session != null) {
            try {
                session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
}

在Controller中使用


@RestController
@RequestMapping("api")
public class TestController {
    @Autowired
    private WebSocket webSocket;

    @RequestMapping("/sendAllWebSocket")
    public String test() {    
        webSocket.sendAllMessage("清晨起來開啟窗,心情美美噠~");
        return "websocket群體傳送!";        
    }
    
    @RequestMapping("/sendOneWebSocket")
    public String sendOneWebSocket() {
        webSocket.sendOneMessage("DPS007", "只要你乖給你買條gai!");
        return "websocket單人傳送";
    }
}

在前端中(VUE)使用WebSocket


當然不在vue中使用也是一樣的,只不過要注意的是WebSocket在普通js中如何建立以及銷燬

<script>
    export default {
        data() {
            return {
                shopId:''
            }
        },
        created() { // 頁面建立生命週期函式
              this.initWebSocket()
        },
        destroyed: function () { // 離開頁面生命週期函式
              this.websocketclose();
        },
        methods: {
            collapse: function(){
                this.isCollapse = !this.isCollapse;
                if (this.isCollapse) {
                    this.iconClass = "cebianlanzhankai";
                } else{
                    this.iconClass = "cebianlanshouhui";
                }
            },
            initWebSocket: function () {
                // WebSocket與普通的請求所用協議有所不同,ws等同於http,wss等同於https
                this.websock = new WebSocket("ws://localhost:8046/websocket/DPS007");
                this.websock.onopen = this.websocketonopen;
                this.websock.onerror = this.websocketonerror;
                   this.websock.onmessage = this.websocketonmessage;
                this.websock.onclose = this.websocketclose;
              },
              websocketonopen: function () {
                console.log("WebSocket連線成功");
              },
              websocketonerror: function (e) {
                console.log("WebSocket連線發生錯誤");
              },
              websocketonmessage: function (e) {
                var da = JSON.parse(e.data);
                console.log(da);
                this.message = da;
              },
              websocketclose: function (e) {
                console.log("connection closed (" + e.code + ")");
              }
        }
    }
</script>

原文地址:https://segmentfault.com/a/1190000017268973