记录一下扫码登录的socket.io实践(前端)

in nodejs with 0 comments, 4203 views

需求描述

最近工作中遇到一个从APP扫码登录WEB站的开发需求,想着以为会用ajax轮询的方案,毕竟登录的使用频率不会太高,令人意外的最终和后端确认的是websocket的实现方式.不过借些机会正好恶补下这个以前没用过的"新技术".

websocket介绍

作为web下的长连接技术已经出现很久了,可以方便的在客户端和服务端进行双向通信。相比ajax轮询能更好的节省服务器资源和带宽,并且能够更实时地进行通讯.

方案选择

考虑到以下几点,我们选择了socket.io

扫码时序图

qrcode-login.svg

关键代码

import io from 'socket.io-client';
import QrCodeWithLogo from 'qr-code-with-logo';

export default class QrcodeLogin {
  constructor(opts) {
    this.socketUrl = opts.socketUrl;
    this.connectSocket();
    this.oCanvas = document.getElementById('js_canvas');
    this.init();
  }
  init() {
    this.emitQrCode();
    this.handleSocketEvent(); 
  }
  handleSocketEvent() {
    this.socket.on('获取二维码', this.getQrCode.bind(this));
    this.socket.on('二维码过期事件', (res) => {
      // ui变化
    this.socket.on('APP扫码事件', (res) => {
      // ui变化
    })
    // 接收登录事件完成登录
    this.socket.on('APP登录事件', (res) => {
      if (!(res && res.data)) {
        return;
      }
      // 后续处理
    });
  }
  connectSocket() {
    this.socket = io(this.socketUrl, {
      transports: ["websocket"],
      secure: true
    });
  }
  emitQrCode() {
    this.socket.emit('获取二维码事件', {/* 传参 */});
  }
  refreshQrCode() {
    this.socket.close();
    this.connectSocket();
    // 重新绑定事件
    this.handleSocketEvent();
    this.emitQrCode();
  }
  getQrCode(res){
    QrCodeWithLogo.toCanvas({
      canvas: this.oCanvas,
      content: res.url,
      width: 156,
      logo: {
        src: 'logo.png',
        logoSize: 0.25,
        radius: 8
      }
    }).catch(err=> {
      console.log(err);
    })
  }
}

总结

用了socket方案后,相比ajax轮询代码结构变得更清晰,只须针对服务端推送过来的对应事件编写相应处理逻辑即可。socket重新连接后,socket实例已经变化,需要重新绑定事件处理函数。

Responses ${replyToWho} / Cancel Reply