Skip to content

mw138/my-scan-login

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 

Repository files navigation

两种实现方式都是简单实现, 只是说明了原理

第一种轮询的方式: 原理: 1 浏览器发送登录请求,获取二维码,将二维码代表的uuid放入application中; 2 手机扫码, 获取uuid, 把user放入application中; 3 浏览器轮询, 判断user是否为null, 如果不是则登录成功, 同时删除uuid;

涉及到的多线程操作: 1 所有登录共享了一个存放键值对的map, 就是这个地方需要同步; 2 user的状态不会被改变; 3 多个线程发起登录操作, 每个线程获得不同的uuid; 4 多个线程扫码, 对于同一个uuid只能一个线程更改状态; 5 多个线程轮询, 同一个浏览器一个时间段只有一个线程轮询;

考虑到安全性: 
  1 多个手机扫同一个码哪个有效?
       以轮询时获取的为准
  2 多个浏览器轮询, 哪一个能登录?
       可能都成功, 也可能成功一个
	   
	   
优势: 不占用连接池资源!

劣势: 频繁登录增加服务器负担!

第二种登录等待的方式:

原理: 1 浏览器发送登录请求,获取二维码,使用UUID生成一个表示登录动作的entity, 放置与appliaction中
      2 浏览器发出登录请求, 获取entity, 然后进入等待状态, 等待手机扫码
	  3 手机扫码, 确认浏览器登录请求已经发送, 获取entity, 唤醒等待的线程完成登录


涉及到的多线程操作: 
   1  所有登录共享了一个存放键值对的map, 就是这个地方需要同步;
   2  多个线程发起登录操作, 每个线程获得不同的entity, entity设置登录线程, 然后开始等待;       3  多个线程扫码, 每个线程获得不同的entity, entity设置user, 然后唤醒;
   
   
   
   
考虑到的线程安全问题:
   1 发送登录请求, entity是变化的, 并且同时被多个线程访问, 会有多个线层同时等待, 在唤醒时只有最后一个会唤醒,其余超时; 所以需要确保一个uuid接受一个请求; 避免
   2 扫码时可能有多个手机扫码, entity 设置user和notify的动作被调用多次, 导致不能确认最后登录的是哪个; 可以接受
   
   
优势: 不频繁访系统, 不占用系统资源

   
劣势: 占用线程资源

About

模拟扫码登录

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages