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.