WebSocket 简介和使用

介绍:webSocket 是一种网络通信协议

有了HTTP协议什么还要使用webSocket

  因为 HTTP 协议有一个缺陷:通信只能由客户端发起。HTTP 协议做不到服务器主动向客户端推送信息。

     它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

其他特点包括:

(1)建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据。

(5)没有同源限制,客户端可以与任意服务器通信。

(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

 

简单封装使用

  webSocket.js

 /**

 * 参数:[socketOpen|socketClose|socketMessage|socketError] = func,[socket连接成功时触发|连接关闭|发送消息|连接错误]
 * timeout:连接超时时间
 * socket.readyState 状态码
 *  0        CONNECTING        连接尚未建立
    1        OPEN            WebSocket的链接已经建立
    2        CLOSING            连接正在关闭
    3        CLOSED            连接已经关闭或不可用
 * @type {module.webSocket}
 */
var isCheckTime;
var failedMaxTimes = 10//允许重连最大次数
var isSetCheckTime = 4000//设置延迟避免请求过多
export default class webSocket {
  constructor(props) {
    this.props = props;
    this.socket = null;
    this.taskRemindInterval = null;
    this.failedTimes0//失败次数
  }
  connection = () => {
    let { socketUrl } = this.props;
    // 检测当前浏览器是什么浏览器来决定用什么socket
    window.WebSocket = window.WebSocket || window.MozWebSocket;
    if (!window.WebSocket) {
      // 检测浏览器支持
      console.log('Error: WebSocket is not supported .');
      return;
    }
    this.socket = new WebSocket(socketUrl);
    this.socket.onopen = this.onopen;
    this.socket.onmessage = this.onmessage;
    this.socket.onclose = this.onclose;
    this.socket.onerror = this.onerror;
    this.socket.sendMessage = this.sendMessage;
    this.socket.closeSocket = this.closeSocket;
  };
  reconnect = () => {
    console.logthis.socket , '重新连接之前,获取连接状态。。。');
    if ( this.socket && this.socket.readyState === 2) {
      return;
    }
    this.socket = null;
    var _this = this;
    //没连接上会一直重连,设置延迟避免请求过多
    isCheckTime && clearTimeout(isCheckTime);
    isCheckTime = setTimeout(function () {
      _this.connection();
    }, isSetCheckTime);
  };
  // 连接成功触发
  onopen = () => {
    console.log('连接成功  发送心跳检测')
     //心跳检测重置
    let { socketOpen } = this.props;
    this.failedTimes = 0;
    socketOpen && socketOpen();
  };
  // 后端向前端推得数据
  onmessage = msg => {
    console.log('onmessage');
    let { socketMessage } = this.props;
    socketMessage && socketMessage(msg);
  };
  // 关闭连接触发
  onclose = e => {
    // clearInterval(this.setIntervalWesocketPush);
    console.log('websocket已断开....正在尝试重连onclose'ethis.socket);
    this.failedTimes++;
    let {timeout } = this.props;
    // 根据后端返回的状态码做操作  我的项目是当前页面打开两个或者以上,就把当前以打开的socket关闭  否则就20秒重连一次,直到重连成功为止
    if (e.code === '4500') {
      this.socket.close();
    } else {
      if (this.taskRemindInterval) {
        clearInterval(this.taskRemindInterval);
      }
      if (this.failedTimes < failedMaxTimes+1) {
        console.warn('connect is failed , try to reconnect, current time:' +this.failedTimes);
        this.taskRemindInterval = setInterval(() => {
          this.reconnect();
        }, 2000);
      } else {
        console.error('connected timeout , close interval!');
      }
    }
  };
  onerror = e => {
    // socket连接报错触发
    this.reconnect();
  };
  sendMessage = value => {
    console.log('sendMessage');
    // 向后端发送数据
    if (this.socket) {
      this.socket.send(JSON.stringify(value));
    }
  };
  /**
   * 发送心跳
   */
  sendPing = e => {
    let { time } = this.props;
    console.log('sendPing...心跳');
    this.setIntervalWesocketPush = setInterval(() => {
      if (this.socket) {
        this.socket.send(JSON.stringify(e));
      }
    }, time);
  };
}

index.js

import Socket from './webSocket';
var userInfo = JSON.parse(localStorage.getItem('userInfo'))?JSON.parse(localStorage.getItem('userInfo')):{};
var todo = process.env.REACT_APP_SOCKET_URL + '/websocket/' + process.env.REACT_APP_EBS + '/todo/' + userInfo.roleId + '/' + userInfo.phone;
var notice = process.env.REACT_APP_SOCKET_URL + '/websocket/' + process.env.REACT_APP_EBS + '/notice/' + userInfo.roleId + '/' + userInfo.phone;
var urls = { todo: todonotice: notice };
var createSocketObj = {},
  timeout = 20000,
  time = 20000,
  params = { msgType: '!12@+' };

export default function index(optscallback) {
  if (userInfo && userInfo.phone) {
    createSocketObj[opts] = new Socket({
      socketUrl: urls[opts],
      timeout,
      time//心跳时间
      socketMessage: receive => {
        console.log(receiveopts);
        callback(receive);
      },
      socketOpen: () => {
        createSocketObj[opts].sendPing(params);
      }
    });
    createSocketObj[opts].connection();
  }
}

页面实例调用

 let that = this;
    Socket('todo'function (receive) {
      console.log(receive'服务端返回的数据 ------todo');
红色字体是获取服务端数据之后逻辑展示
      let todoList = JSON.parse(localStorage.getItem('todoArray')) || [];
      todoList.unshift(JSON.parse(receive.data));
      localStorage.setItem('todoArray', JSON.stringify(todoList.slice(0, 50)));

      that.setState({
        todoArray: todoList
      });
      let itemData = JSON.parse(receive.data);
      const key = `open${Date.now()}`;
      notification.info({
        message: `${itemData.title}`,
        duration: 3,
        description: (
          <div>
            <div>
              <span>{itemData.content}</span>
            </div>
          </div>
        ),
        placement: 'bottomRight',
        key,
        onClick() {
          notification.close(key);
        }
      });
    });

 

WebSocket 

posted @ 2021-01-15 10:43  lxn*  阅读(257)  评论(0编辑  收藏  举报