前端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>
原文地址:https://www.cnblogs.com/shine-lovely/p/15533286.html