轮询长连接实现扫码操作

轮训长连接实现扫码操作

首先是jsp页面当二维码生成后该做如何操作
jsp页面部分:
其中keepPool方法中的$.get方法可以用ajax代替(避免出现重复调用get的参数状态码为sucess,而不进入controller方法)

		var flag = 'true';
		 //生成二维码之后,调用keeppool方法
	    function scanLogin(){
	        var uuid = $("#uuid").val();
	        //二维码内容
	        var content = "url地址?uuid="+uuid+"&type=1";
	        //拿到项目根路径
	        var contextRootPath = "${ctx}";
	        //在固定的的地方生生二维码,详情可见之前的二维码生成文章,通过jquery.qrcode.js生成
	        $('.pc_qr_code').qrcode({
	            render:"canvas",
	            width:200,
	            height:200,
	            correctLevel:0,
	            text:content,
	            background:"#ffffff",
	            foreground:"black"
	        });
	        setCookie("sid", 123, -1*60*60*1000);
	        if( 'true' == flag ){
	        	 keepPool(flag);//自动循环调用
	        }
	       
	    };
	    
	    //改为采用长连接请求方式
	    function keepPool(flag){
		   var uuid = $("#uuid").val();
		   //传参到pool方法下
	        $.get("/pool",{uuid:uuid,},function(msg){
	        	//如果操作成功
	            if(msg.successFlag == '1'){
	                $("#result").html("<font color='green' size='2px'>请勿刷新页面,在手机端确认登录!</font>");
	                //保存cookie
	                setCookie(msg.cname, msg.cvalue, 3*60*60*1000);
	                //扫码成功后开始手机端确认监听,采用长连接
	                phoneLogin();
	            //如果操作失败
	            }else if(msg.successFlag == '0'){
	                $("#result").html(msg.msg);
	                $("#result").css({
	                    "color":"red"
	                })
	             
	            }
	        });
	    }
 		//手机端确认监听
	    function phoneLogin(){
	    //页面调整
	    	$(".pc_qr_code").hide();
	    	$("#phoneLoginImg").show();
		    var uuid = $("#uuid").val();
		    //跳转success方法
	        $.get("/success",{uuid:uuid,},function(msg){
	            if(msg.successFlag == '1'){
	                $("#result").html("<font color='red'>扫码成功,请在手机端确认登录</font>");
	                setCookie(msg.cname, msg.cvalue, 3*60*60*1000);
	                //alert("将跳转...");
	               window.location.href = "url扫码成功后跳转的路径";
	            }else if(msg.successFlag == '0'){
	                $("#result").html(msg.msg);
	                $("#result").css({
	                    "color":"red"
	                })
	            }
	        });
	    }


jsp中跳转到controller中的方法:


    /**
     * 查询扫码状态,判断二维码是否被扫描的方法 
     * loginUserMap 是一个静态的map结构的登录池,uuid为key , 登录信息为value
     * @return
     */
    @RequestMapping("/pool")
    @ResponseBody
    public JSONObject pool(String uuid){
    	JSONObject jsonObj  = new JSONObject();
        DataResultInfo result = new DataResultInfo();
        UserVo pool = null;
		//采用长连接监听
      	long startTime=new Date().getTime();
		Boolean scanPool=true;
	    while(scanPool){//每隔2秒循环监听
		  try {
			Thread.sleep(2 * 1000L);//休眠2秒钟
//			System.out.println("检测[" + uuid + "]是否登录");
			if("".equals(uuid)||uuid==null){
				scanPool=false;//没有获取到uuid则不扫描
			}else{
			    //从redis中获取用户扫码信息
	            pool =(UserVo)JedisUtils.getObject(uuid);	
			}
          
            if (pool == null) {
            	scanPool=false;//没有获取到pool则不扫描
                // 扫码超时,进线程休眠
                Thread.sleep(2 * 1000L);
                jsonObj.put("successFlag",CodeConstant.SUCESSFLAG_0);
                jsonObj.put("msg","该二维码已经失效,请重新访问登陆页面获取");
            } else {
           		//获取扫描状态,app扫码后会在redis里边修改状态码                               
                boolean scanFlag = pool.getScanStatus();
                if (scanFlag) {//获取扫描状态
                	scanPool=false;//二维码已被扫描将结束长连接循环,将结果信息返回页面
                    // 根据uuid从redis中获取pool对象,得到对应的sessionId,返给页面,通过js存cookie中
                	jsonObj.put("successFlag",CodeConstant.SUCESSFLAG_1);
                	jsonObj.put("cname", "SESSIONKEY");
                	jsonObj.put("cvalue", pool.getSession());
                	result.setData(jsonObj);
                } else {
                	if(new Date().getTime()-startTime>180000){//3分钟后超时不再循环
                		scanPool=false;
    		    		jsonObj.put("successFlag",CodeConstant.SUCESSFLAG_0);
    					jsonObj.put("msg","等待手机扫描超时,请重新刷新扫描!");
    		    	}
                }
            }
        } catch (InterruptedException e) {
        	logger.error("查询扫码状态异常", e);
			Thread.currentThread().interrupt();
        }
		}
        return jsonObj;
    }




    /**
     * 二维码扫描手机确认登录监听扫描类
     * @param uuid
     * @return
     */
    @RequestMapping("/success")
    @ResponseBody
    public JSONObject success(String uuid){
          JSONObject jsonObj  = new JSONObject();
          String  flag="false";
		//采用长连接监听
      	long startTime=new Date().getTime();
		Boolean bool=true;
		 while(bool){//每隔一秒循环监听
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					logger.error("扫码登录监听异常", e);
					Thread.currentThread().interrupt();
				}
			//从redis中获取用户信息
			 UserVo  user =null;
			 user =(UserVo)JedisUtils.getObject(uuid);
		    if(user!=null){
		    	flag = user.getIsFlag();//是否确认登录标志
		    }
		    if(CodeConstant.TRUE.equals(flag)){//已在手机确认登录
		    	bool=false;//手机确认登录后将结束长连接循环,将结果信息返回页面
		    	//根据用户名查询用户信息,以获取可用的登录信息用于系统登录
		    	PhoneLog phoneLog=new PhoneLog();
		    	phoneLog.setYWLX("扫码登录-查找用户信息");
		    	JSONObject resultObj =UserUtils.findbackPassword2(user,phoneLog);
		    	if(CodeConstant.SUCCESS.equals(resultObj.get("msg"))) {//成功
		    		logger.info(user.getUserName()+"的登录信息------------>"+resultObj.toJSONString());
					List<UserInfoEntity> list=JSONArray.parseArray(resultObj.get("result").toString(), UserInfoEntity.class);
					if(list.size()==1) {//正常数据
						UserVo  userVo = new UserVo();//重新创建对象,以清空原有值
						UserInfoEntity userInfoEntity=list.get(0); 
						userVo.setUserName(userInfoEntity.getAA006());//用户名
						userVo.setPassword(userInfoEntity.getAA002());//密码
				      //调用拦截的登录方法
						UserUtils.getUserByName(userVo);
						jsonObj.put("msg","手机已确认,可以登录!");
						jsonObj.put("successFlag",CodeConstant.SUCESSFLAG_1);
						//JedisUtils.delObject(uuid);删除缓存
					}else {
						jsonObj.put("successFlag",CodeConstant.SUCESSFLAG_0);
						jsonObj.put("msg","等待超时,请重新登录!");
					}
				}else {//失败
					 jsonObj.put("successFlag",CodeConstant.SUCESSFLAG_0);
					 jsonObj.put("msg","调用二维码登录接口服务失败,请稍后重试!");
				}
		    }else{
		    	if(new Date().getTime()-startTime>180000){//3分钟后超时不再循环
		    		bool=false;
		    		jsonObj.put("successFlag",CodeConstant.SUCESSFLAG_0);
					jsonObj.put("msg","等待手机确认登录超时,请重新登录!");
		    	}
		    	 
		    }
		}
        return jsonObj;
    }

其次,如果需要通过接口取得某些参数,可以使用如下方法

 //controller中调用接口获取参数
 Map<String, String> map1 = new HashMap<>();
                map1.put("参数名1","参数1");
                map1.put("参数名2","参数2");
                String result = SSLSendUtil.sendHttpPost(map1, "http://x.xx.xx.xxx:xxxx/aaa/bbb/ccc/ddd/eee");


//SSLSendUtil中的sedHttpPost方法
 public static String sendHttpPost(Map<String,String> map, String url) throws Exception {
        List<NameValuePair> paramList = new ArrayList<>();
        //  请求参数填充
        for(Map.Entry<String, String> entry : map.entrySet()){
            String key = entry.getKey();
            String value = entry.getValue();
            paramList.add(new BasicNameValuePair(key,value));
        }
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);

        httpPost.addHeader(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded;charset=utf-8");
        UrlEncodedFormEntity postEntity = new UrlEncodedFormEntity(paramList, "UTF-8");
        httpPost.setEntity(postEntity);
        CloseableHttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        String responseContent = EntityUtils.toString(entity, "UTF-8");
        response.close();
        httpClient.close();
        return responseContent;
    }

以上方法仅供参考,如果有什么不对的地方还请指教.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值