WebSocket的使用(基於VUE與SpringBoot)

WebSocket 是 HTML5 開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議。
WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,容許服務端主動向客戶端推送數據。在 WebSocket API 中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。html

在 WebSocket API 中,瀏覽器和服務器只須要作一個握手的動做,而後,瀏覽器和服務器之間就造成了一條快速通道。二者之間就直接能夠數據互相傳送。前端

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

HTML5 定義的 WebSocket 協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。html5

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

由於近期所使用的技術棧爲VUE和SpringBoot,所以此文章所用技術環境也爲VUE以及SpringBoot下。spring

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

maven依賴(由於個人SpringBoot項目爲2.0以上,會自動選擇最優版本,所以此處沒有帶上版本號):api

<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>
相關文章
相關標籤/搜索