前端vue使用stomp.js、sock.js完成websocket


前端vue使用stomp.js、sock.js完成websocket

Sock.js

Sock.js 是一個JavaScript庫,為了應對很多瀏覽器不支持websocket協議問題。SockJ會自動對應websocket,如果websocket不可用,就會自動降為輪訓的方式。

Stomp.js

STOMP-Simple Text Oriented Message Protocol-面向消息的簡單文本協議。Sockjs為websocket提供了備選方案,但是通信形式層級過低。Stompjs則增加了語義

WebSocket、SockJs、STOMP三者關系

WebSocket 是底層協議,SockJS 是WebSocket 的備選方案,也是底層協議,而 STOMP 是基於 WebSocket(SockJS)的上層協議。

  1. HTTP協議解決了 web 瀏覽器發起請求以及 web 服務器響應請求的細節,假設 HTTP 協議 並不存在,只能使用 TCP 套接字來 編寫 web 應用。

  2. 直接使用 WebSocket(SockJS) 就很類似於 使用 TCP 套接字來編寫 web 應用,因為沒有高層協議,就需要我們定義應用間所發送消息的語義,還需要確保連接的兩端都能遵循這些語義;

  3. 同HTTP在TCP 套接字上添加請求-響應模型層一樣,STOMP在WebSocket 之上提供了一個基於幀的線路格式層,用來定義消息語義;

實例

<template>
  <div>
    <p>
      <button @click="send('1')">1分鍾</button>
      <button @click="send('2')">10分鍾</button>
      <button @click="send('3')">1小時</button>
      <button @click="send('4')">24小時</button>
    </p>
    <ul>
      <li v-for="(item,index) in tableData" :key="index">{{ item.name }}:{{ item.value }}</li>
    </ul>
  </div>
</template>

<script>
import Stomp from 'stompjs'
import SockJS from 'sockjs-client'

// const headers = {}
const headers = {
  login: 'mylogin',
  passcode: 'mypasscode',
  // additional header
  'client-id': 'my-client-id',
  Author: '1235465tyrgw32rsgg'
};
export default {
  data () {
    return {
      socketUrl: '/websocket/ws', // ws://localhost:8080/websocket/ws
      tableData: [],
      reconnecting: false,
      socket: null,
      stompClient: null
    }
  },
  mounted () {
    this.initWebsocket()
  },
  beforeDestroy() {
    this.closeSocket()
  },
  methods: {
    /* 只需要在連接服務器注冊端點endPoint時,寫訪問服務器的全路徑URL:
      new SockJS('http://127.0.0.1:9091/sbjm-cheng/endpointOyzc');
      其他監聽指定服務器廣播的URL不需要寫全路徑
      stompClient.subscribe('/topic/getResponse',function(response){})
    */
    /* 創建stompClient: (1) 使用原生的websocket (2) 使用定制的websocket(例如sockjs包裹的websocket)
    ① Stomp.client("ws://localhost:61614/stomp")
    ② SockJS的url是http、https協議,而不是 ws
      const socket = new SockJS("http://127.0.0.1:9091/sbjm-cheng/endpointOyzc"); 
       Stomp.over(socket)

       const ws = new Websocket("ws://localhost:61614/ws")
       Stomp.over(ws)
    */
    initWebsocket () {
      /* 
      ① 創建sockJS對象;
      ② 創建stomp客戶端
      ③ stompClient客戶端 連接 stomp服務器
      */
      this.socket = new SockJS(this.socketUrl)
      this.stompClient = Stomp.over(this.socket)

      this.stompClient.connect(
        headers, // headers頭部信息。可添加客戶端的認證信息。也可以不添加信息,headers 直接就設置為 {}
        frame => {
          // 連接成功: 訂閱服務器的地址。為了瀏覽器可以接收到消息,必須先訂閱服務器的地址
          this.connectSucceed()
        }, err => {
          // 連接失敗的回調
          this.reconnect(this.socketUrl, this.connectSucceed)
        })
    },
    /* 連接成功的回調:訂閱服務器的地址。為了瀏覽器可以接收到消息,必須先訂閱服務器的地址 */
    connectSucceed () {
      // 設置心跳發送接受頻率(ms)默認為10000ms。 heart-beating是利用window.setInterval()去規律地發送heart-beats或者檢查服務端的heart-beats。
      this.stompClient.heartbeat.outgoing = 10000
      this.stompClient.heartbeat.incoming = 0

      this.stompClient.subscribe('/topic/dashboard/data', res => {
        this.tableData = res.body.list
      })

    /* 
    當客戶端與服務端連接成功后,可以調用 send()來發送STOMP消息。這個方法必須有一個參數,用來描述對應的STOMP的目的地。
    另外可以有兩個可選的參數:headers,object類型包含額外的信息頭部;body,一個String類型的參數。

    client.send("/queue/test", {priority: 9}, "Hello, STOMP");
    // client會發送一個STOMP發送幀給/queue/test,這個幀包含一個設置了priority為9的header和內容為“Hello, STOMP”的body。
    */
      this.stompClient.send('/topic/dashboard/send',{}, '1')
    },
    reconnect (socketUrl, callback) {
      this.reconnecting = true
      let connected = false
      const timer = setInterval(() => {
        this.socket = new SockJS(socketUrl)
        this.stompClient = Stomp.over(this.socket)
        this.stompClient.connect(headers, frame => {
          this.reconnectting = false
          connected = true
          clearInterval(timer)
          callback()
        }, err => {
          console.log('Reconnect failed!');
          if(!connected) console.log(err);
        })
      }, 1000);
    },
    closeSocket(){
      if(this.stompClient != null){
        this.stompClient.disconnect()
        // this.stompClient.disconnect(()=>{
        //   console.log('連接關閉')
        // });
      }
    },
    send(flag){
      this.stompCLient.send('/topic/dashboard/send',{}, flag)
    }
  },
}
</script>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM