springBoot 웹 소켓 기반 스 캔 로그 인

최근 회사 에 또 새로운 자바 프로젝트 가 하나 있다.
스 캔 로그 인 관련.이전 항목 은 ajax 폴 링 방식 을 사 용 했 습 니 다.너무 낮은 것 같 아 요.
그래서 이번 에는 웹 소켓 으로 이 루어 졌 습 니 다.
네.잔말 말고!시작 합 시다!!
우선 시계 한 장 이 필요 합 니 다.
이 시 계 는 무엇 을 하 는 것 입 니까?누가 스 캔 했 는 지 기록 하 는 거 야.누가 로그 인 했 어?
User_토 큰 시계
필드 는 다음 과 같 습 니 다:
1.uid:유일 성 확보 에 사용
2,userId:누가 로그 인
3,loginTime:로그 인 시간
4.createTime:생 성 시간 은 만 료 여 부 를 판단 하 는 데 사 용 됩 니 다.
5.state:QR 코드 의 실효 여부 0 유효 1 실효
2.캐릭터 는 어떤 것들 이 있 나 요?
우 리 는 아직 분석 이 필요 하 다.스 캔 로그 인 이라는 업무 논리 에는 어떤 역할 이 있 습 니까?
1.안 드 로 이 드 엔 드 or 위 챗 웹 엔 드:스 캔
2.PC 쪽:쓸 림.로그 인
3.서버:전 체 를 통제 하고 인 터 페 이 스 를 제공 합 니 다.
3.인 터 페 이 스 는 어떤 것 이 필요 합 니까?
배역 이 생기다.너 허벅지 로 도 인터페이스 생각 나 지?!
그래서 우리 의 인 터 페 이 스 는 두 개!
1.QR 코드 인터페이스 생 성:QR 코드 생 성.QR 코드 에는 UUID 가 있 습 니 다.
2.신분 확인 인터페이스:신분 확인 및 QR 코드 만 료 여부 판단 등
절차
그 말 이 뭐 였 더 라?코끼리 를 냉장고 에 넣 으 려 면 모두 몇 걸음 으로 나 누 어야 합 니까?
1.PC 엔 드 오픈.QR 코드 인 터 페 이 스 를 만 들 고 서버 와 링크 를 만 듭 니 다.링크 는 uid 로 연결 합 니 다.
2.위 챗 웹 에서 스 캔 을 진행 합 니 다.QR 코드 의 uid 를 가 져 옵 니 다.
3.위 챗 웹 에서 uid 를 받 은 후.로그 인 여 부 를 표시 합 니 다.확인 을 클릭 한 후 신분 인 터 페 이 스 를 호출 합 니 다.
4.신분 확인 인터페이스 통과 후.서버 에서 PC 측 에 메 시 지 를 보내다.로그 인 완료.링크 가 끊 겼 습 니 다. 
됐어!분석 끝 났 습 니 다.생각 하고 있 을 거 야.아직 끝나 지도 않 았 는데.비비 말고빨리 코드 붙 여.
작가:시청자 여러분.어떻게 생각 하 는 지 가르쳐 주 는 거 야?
그러면 코드 를 붙 여 보도 록 하 겠 습 니 다!보시 면서 도 스스로 생각 하 셨 으 면 좋 겠 습 니 다. 
5.미 친 듯 이 코드 붙 이기
우선 QR 코드 코드 를 가 져 와 야 하 는 거 죠? 붙이다

//       、  Token
    @RequestMapping(value = "/getLoginQr" ,method = RequestMethod.GET)
    public void createCodeImg(HttpServletRequest request, HttpServletResponse response){
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
 
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
 
        try {
            //             UUID         
            String uuid = userService.createQrImg();
            response.setHeader("uuid", uuid);
            //          hutool  QrCodeUtil 
            //   :http://hutool.mydoc.io/
            QrCodeUtil.generate(uuid, 300, 300, "jpg",response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
QR 코드 를 가 져 오 는 인터페이스 가 생 겼 습 니 다.상대 적 인 전단 호출 이 필요 합 니 다. 
************************************************************************
지식 점:그림 흐름 을 동적 으로 불 러 오고 header 의 인 자 를 추출 합 니 다.
여 기 는 xmlhttp 를 사용 하여 처리 합 니 다.
왜?
백 엔 드 가 하나의 흐름 으로 되 돌아 오기 때문이다.
그렇게 흐 르 는데QR 코드 에 있 는 uid 를 설치 한 것 입 니 다.이 uid 는 세 션 의 식별 자로 사 용 됩 니 다.
그럼 전단 도 받 아야 지.백 엔 드 와 웹 소켓 링크 를 진행 합 니 다.
이렇게 누가 스 캔 하고서버 에서 만 웹 소켓 방식 으로 전단 을 알 릴 수 있 습 니 다.누 군가 스 캔 에 성 공 했 습 니 다.너 는 너의 업 무 를 해라.자줏빛.
그래서 요청 에 헤더 에 설 치 된 uid 를 가 져 오기 위해 xmlhttp 를 통 해 처리 합 니 다.
************************************************************************

 <div class="qrCodeImg-box" id="qrImgDiv"></div>

$(document).ready(function(){
    initQrImg();
});
  
 function initQrImg(){
            $("#qrImgDiv").empty();
 
            var xmlhttp;
            xmlhttp=new XMLHttpRequest();
            xmlhttp.open("GET",getQrPath,true);
            xmlhttp.responseType = "blob";
            xmlhttp.onload = function(){
                console.log(this);
                uuid = this.getResponseHeader("uuid");
 
                if (this.status == 200) {
                    var blob = this.response;
                    var img = document.createElement("img");
                    img.className = 'qrCodeBox-img';
                    img.onload = function(e) {
                        window.URL.revokeObjectURL(img.src);
                    };
                    img.src = window.URL.createObjectURL(blob);
                    document.getElementById("qrImgDiv").appendChild(img);
 
                    initWebSocket();
                }
            }
            xmlhttp.send();
        }
  
       var path = "://localhost:8085";
       var getQrPath =  "http" + path + "/user/getLoginQr";
       var wsPath =     "ws" + path + "/websocket/";

 
       function initWebSocket(){
 
           if(typeof(WebSocket) == "undefined") {
               console.log("        WebSocket");
           }else{
               console.log("       WebSocket");
               //   WebSocket  ,                    
               //   socket = new WebSocket("ws://localhost:8083/checkcentersys/websocket/20");
               var wsPathStr = wsPath+uuid;
               socket = new WebSocket(wsPathStr);
               //    
               socket.onopen = function() {
                   console.log("Socket    ");
                   //socket.send("          " + location.href + new Date());
               };
               //      
               socket.onmessage = function(msg) {
                   console.log(msg.data);
                   var data = JSON.parse(msg.data);
                   if(data.code == 200){
                       alert("    !");
                       //             。      
                       window.sessionStorage.uuid = uuid;
                       window.sessionStorage.userId = data.userId;
                       window.sessionStorage.projId = data.projId;
 
                       window.location.href = "pages/upload.html"
                   }else{
                       //     ,    、    、     
                       socket.close();
                       initQrImg();
                   }
                   //                    
               };
               //    
               socket.onclose = function() {
                   console.log("Socket   ");
               };
               //       
               socket.onerror = function() {
                   alert("Socket     ");
                   //          
               }
           }
       }
됐어.위 에 서 는 웹 소켓 을 어떻게 설정 하 는 지 에 대해 언급 하 였 다.다음은 말씀 드릴 게 요. 
springBoot 에서 웹 소켓 을 어떻게 조작 합 니까? 
1.pom.xml 추가

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
2、Bean 1 개 추가   

   /**
     * WebSocket   
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
3.WebSocketServer 정의

package com.stylefeng.guns.rest.modular.inve.websocket;
 
/**
 * Created by jiangjiacheng on 2019/6/4.
 */
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
 
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
 
@ServerEndpoint("/websocket/{sid}")
@Component
public class WebSocketServer {
 
    static Log log=LogFactory.get(WebSocketServer.class);
 
    //    ,           。            。
    private static int onlineCount = 0;
 
    //concurrent      Set,            MyWebSocket  。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
 
    //           ,              
    private Session session;
 
    //  sid
    private String sid="";
 
    /**
     *            */
    @OnOpen
    public void onOpen(Session session,@PathParam("sid") String sid) {
        this.session = session;
        webSocketSet.add(this);     //  set 
        addOnlineCount();           //    1
        log.info("        :"+sid+",       " + getOnlineCount());
        this.sid=sid;
        /*try {
            sendMessage("    ");
        } catch (IOException e) {
            log.error("websocket IO  ");
        }*/
    }
 
    /**
     *          
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  // set   
        subOnlineCount();           //    1
        log.info("      !       " + getOnlineCount());
    }
 
    /**
     *              
     *
     * @param message           */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("      "+sid+"   :"+message);
        //    
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("    ");
        error.printStackTrace();
    }
    /**
     *          
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }
 
 
    /**
     *        
     * */
    public static void sendInfo(String message,@PathParam("sid") String sid) throws IOException {
        log.info("       "+sid+",    :"+message);
        for (WebSocketServer item : webSocketSet) {
            try {
                //            sid , null     
                if(sid == null) {
                    item.sendMessage(message);
                }else if(item.sid.equals(sid)){
                    item.sendMessage(message);
                }
            } catch (IOException e) {
                continue;
            }
        }
    }
 
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
 
    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }
 
    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
}
이렇게 해서 웹 소켓 의 지 지 를 증가 시 켰 다.
그럼 아까 단계 로 돌아 가.  
1.먼저 PC 엔 드 호출 인터페이스 에서 QR 코드 를 보 여 주 었 습 니 다. 
2.QR 코드 의 http 요청 을 요청 합 니 다.uid 가 header 에 있 습 니 다.웹 소켓 의 표지 sid 로 uid 를 직접 가 져 와 연결 합 니 다. 
3.그리고 핸드폰 에서 카 메 라 를 사용 하여 QR 코드 의 uid 를 받 습 니 다.uid+userid 를 사용 하여 스 캔 성공 인 터 페 이 스 를 요청 합 니 다.
스 캔 성공 인터페이스
컨트롤 러 코드:

  /**
     *       :                
     * @param token
     * @param userId
     * @return
     */
    @RequestMapping(value = "/bindUserIdAndToken" ,method = RequestMethod.GET)
    @ResponseBody
    public Object bindUserIdAndToken(@RequestParam("token") String token ,
                                     @RequestParam("userId") Integer userId,
                                     @RequestParam(required = false,value = "projId") Integer projId){
 
        try {
            return new SuccessTip(userService.bindUserIdAndToken(userId,token,projId));
        } catch (Exception e) {
            e.printStackTrace();
            return new ErrorTip(500,e.getMessage());
        }
    }
서비스 코드

@Override
    public String bindUserIdAndToken(Integer userId, String token,Integer projId) throws Exception {
 
        QrLoginToken qrLoginToken = new QrLoginToken();
        qrLoginToken.setToken(token);
        qrLoginToken = qrLoginTokenMapper.selectOne(qrLoginToken);
 
        if(null == qrLoginToken){
            throw  new Exception("     !");
        }
 
        Date createDate = new Date(qrLoginToken.getCreateTime().getTime() + (1000 * 60 * Constant.LOGIN_VALIDATION_TIME));
        Date nowDate = new Date();
        if(nowDate.getTime() > createDate.getTime()){//          
 
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code",500);
            jsonObject.put("msg","     !");
            WebSocketServer.sendInfo(jsonObject.toJSONString(),token);
 
            throw  new Exception("     !");
        }
 
        qrLoginToken.setLoginTime(new Date());
        qrLoginToken.setUserId(userId);
 
        int i = qrLoginTokenMapper.updateById(qrLoginToken);
 
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code",200);
        jsonObject.put("msg","ok");
        jsonObject.put("userId",userId);
        if(ToolUtil.isNotEmpty(projId)){
            jsonObject.put("projId",projId);
        }
        WebSocketServer.sendInfo(jsonObject.toJSONString(),token);
 
        if(i > 0 ){
            return null;
        }else{
            throw  new Exception("     !");
        }
    }
논 리 는 토 큰 이 맞 는 지 아 닌 지 판단 하 는 거 예요.
맞 으 면시간 이 만 료 되 었 습 니까?기한 이 지나 지 않 으 면 업무 논리 조작 을 합 니 다.

//       
WebSocketServer.sendInfo(jsonObject.toJSONString(),token);
전단 에 로그 인 이 성공 했다 는 것 을 알 리 는 것 입 니 다.그리고 그 에 게 업무 에 필요 한 내용 을 주 었 다. 
그리고 전단 코드 가 받 았 습 니 다.업무 논리 조작 만 하면 돼. 
springBoot 가 웹 소켓 을 기반 으로 스 캔 로그 인 을 실현 하 는 것 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 springBoot 스 캔 로그 인 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

좋은 웹페이지 즐겨찾기