Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

The deep/Listener interface implements long polling requests

@PostMapping("/listener")
public void listener(HttpSerlvetRequest request,HttpSerlvetRespnse response) throw SerlvetException,IOException{
    request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED".true);
    String probeModify=request.getParameter("Listening-Configs");
    if(StringUtils.isBlank(probeModify)){
        throw new IllegalArgmentException("invalid probeModify");
    }
    probeModify=URLDecoder.decode(probeModify,Constants.ENCODE);
    Map<String,String> clientMd5Map;
    try{}catch(Throwable e){
        throw new IllegalArgumentException("invalid probeModify");
        
    }
    inner.doPollingConfig(request,response,clientMd5Map,probeModify.length());
}
Copy the code

DoPollingConfig method is a long polling processing interface, part of the core code is as follows:

public String doPollingConfig(HttpServletRequest request,HttpServletResponse response,Map<String,String> clientMd5Map,int probeRequestSize) throws IOException{
    // Long polling starts
    if(LongPollingService.isSupportLongPolling(request)){
        longPollingService.addPollingClient(request,response,clientMd5Map,probeRequestSize);
        returnHttpServletResponse. SC_OK + ""; }// Short polling logic
    List<String> changedGroups=Md5Util.compareMd5(request,response,clientMd5Map);
   // Short polling result
    
    String oldResult = Md5Util.compareMd5OldResult(changedGroups);
    String newResult=Md5Util.compareMd5ResultString(changedGroups);
}
Copy the code

Determine whether the request is polling long, and if so, call addLongPollingClient.

  • Get the client request timeout, subtract 500ms and assign timeout
  • Check isFixedPolling. If isFixedPolling is true, the scheduled task will be executed 30 seconds later; otherwise, the scheduled task will be executed 29.5 seconds later
  • Md5 is used to compare the data with that on the server. If the data is modified, the Md5 is returned.
  • Scheduler. execute executes the ClientLongPolling thread
public void addLongPollingClient(HttpServletRequest request,HttpServletResponse response,Map<String,String> clientMd5Map,int probeRequestSize){
    // Get the request timeout set by the client
    String str=request.getHeader(LongPollingService.LONG_POLLING_HEADER);
    String noHangUpFlag=request.getHeader(LongPollingService.LONG_POLLING_NO_HANG_UP_HEADER);
	String appName = request.getHeader(RequestUtil.CLIENT_APPNAME_HEADER);
    String tag=request.getHeader("Vipserver-Tag");
    int delayTime=SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME,500);
    // return the response 500ms earlier to avoid client timeout
    long timeout = Math.max(10000, Long parseLong (STR) - delayTime);if(isFixedPolling()){
        timeout = Math.max(10000,getFixedPollingInterval());
    }else{
        long start=Sysetm.currentTimeMills();
        List<String> changeGroups=MD5Util.compareMd5(request,response,clientMd5Map);
    	if(changeGroups.size()>0){
            generateResponse(request,response,changedGroups);
            return;
        }else if(noHangUpFlag ! =null && noHangUpFlag.equalsIgnore(TRUE_STR)){
            return;
        }
    }
    String IP=RequestUtil.getRemoteIp(request);
    // called by an HTTP thread, otherwise the container will send a response immediately after leaving
    final AsyncContext asyncContext=request.startAsync();
    / / AsyncContext setTimeOut () timeout, controlled by themselves
    asyncContext.setTimeOut(0L);
    
    scheduler.excute(
    new ClientLongPolling(asyncContext,clientMd5Map,ip,probeRequestSize,timeout,appName,tag));
}
Copy the code

According to the addLongPollingClient method, its function is to wrap the client’s long polling request into ClientPolling and deliver it to the scheduler for execution.