前言
本打算用CountDownLatch来实现,但有个问题我没有考虑,就是当用户APP没有扫二维码的时候,线程会阻塞5分钟,这反而造成性能的下降。好吧,现在回归传统方式:前端ajax每隔1秒或2秒发一次请求,去查询后端的登录状态。
一、支付宝和微信的实现方式
1.支付宝的实现方式
每隔1秒会发起一次http请求,调用https://securitycore.alipay.com/barcode/barcodeProcessStatus.json?securityId=web%7Cauthcenter_qrcode_login%7C【UUID】&_callback=light.request._callbacks.callback3
如果获取到认证信息,则跳转进入内部系统。
如图所示
2.微信的实现方式
每隔1分钟调用一次 https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=【UUID】&tip=0&r=-1524754438&_=1521943100181
而请求一次的时间预计是1分钟,如果没有查到到认证信息,则会返回
window.code=408;
没有扫码就会一直等待。当一定时间不扫码二维码,页面就会强制刷新。
我猜想后端的机制和我上篇《spring boot高性能实现二维码扫码登录(上)——单服务器版》类似。
那么如果用户长时间不扫二维码,服务器的线程将不会被唤醒,微信是怎么做到高性能的。如果有园友知道,可以给我留言。
3.我的实现方式
好了,我这里选用支付宝的实现方式。因为简单粗暴,还高效。
流程如下:
1.前端发起成二维码的请求,并得到登录UUID
2.后端生成UUID后写入Redis。
3.前端每隔1秒发起一次请求,从Redis中获取认证信息,如果没有认证信息则返回waiting状态,如果查询到认证信息,则将认证信息写入seesion。
二、代码编写
pom.xml引入Redis及Session的依赖:
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- session -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
完整的pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.demo</groupId> <artifactId>auth</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>auth</name> <description>二维码登录</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope