EventSource

1,605 阅读1分钟

概念

server-sent events(缩写SSE)。EventSource 基于http协议的单向通信。IE兼容解决的办法: npm install event-source-polyfill。可以自动重连接(WebSocket要借助第三方库比如socket.io实现重连。)

MDN

API

let sse = new EventSource('/xxxx')

// `0` — connecting
// `1` — open
// `2` — closed
console.log(sse.readyState);

// 连接成功
sse.onopen = function (event) {
  console.log('成功连接')
}

sse.onmessage = function (e) {
  console.log('onmessage', e.data)
}
// 监听错误
sse.onerror = function (err) { 
  console.log('onerror', err)
}
// 监听指定类型的事件
sse.addEventListener("notice", function(e) {
  console.log(e.data)
})

sse.addEventListener("update", function(e) {
  console.log(e.data)
})

sse.addEventListener("message", function(e) {
  console.log(e.data)
})

封装

class EventSource {
  constructor(url, onmessage) {
    this.eventSourceUrl = url;
    this.onmessage = onmessage;
    this.eventSource = null;
    this.initEventSource(url);
  }

  initEventSource(url) {
    if ('EventSource' in window) {
      let _that = this;

      //实例化EventSource
      this.eventSource = new EventSource(_that.eventSourceUrl);

      //EventSource打开
      this.eventSource.onopen = function () {
        console.log('EventSource连接成功', _that.eventSourceUrl);
      };

      //EventSource接收到新消息
      this.eventSource.onmessage = function (event) {
        try {
          if (event.data && typeof event.data === 'string') {
            let data = JSON.parse(JSON.parse(event.data));

            //业务逻辑回调
            if (typeof _that.onmessage === 'function') {
              _that.onmessage(data);
            }
          }
        } catch (error) {
          console.log('EventSource初始化异常', error);
        }
      };

      //EventSource关闭
      this.eventSource.onclose = function () {
        console.log('EventSource连接断开', _that.eventSourceUrl);
      };

      //EventSource错误
      this.eventSource.onerror = function (error) { // 监听错误
        console.log('EventSource连接错误', error);
        this.close();
      }
    }
    else {
      throw new Error('当前浏览器不支持EventSource对象')
    }
  }

  //关闭eventSource
  close() {
    this.eventSource.close();
    this.eventSourceUrl = '';
    this.eventSource = null;
    this.onmessage = null;
  }
}

export default EventSource