在客户端获取的当前时间和在服务端获取的当前时间往往会存在差异。有时我们需要知道在客户端创建数据时,相对于服务器的时间是多少。这是我们需要知道客户端和服务端获取当前时间的时间差,从而可以算出相对于服务器的时间。主要的过程分为:“在客户端启动时,请求服务器端,发送当前客户端时间T1”、“服务器端收到请求,返回T2和T3,T2表示获取到客户端请求的时间,T3表示响应客户端请求的时间”、“客户端收到服务器的响应后,记录当前时间T4”、“算出客户端和服务端的时间差TimeDifference”。
1、在客户端启动时,请求服务器端,发送当前客户端时间T1。
在客户端定义个long类型的变量,存储时间差,初始值为0:
/**
* 同步Ntp时,服务器与POS之间的时差
*/
public static long TimeDifference;
/**
* 同步APP的时间和服务器的时间
*/
private void syncTime() {
long timeStamp = new Date(System.currentTimeMillis() + NtpHttpBO.TimeDifference).getTime();
if (!ntpHttpBO.syncTime(timeStamp)) {
log.error("POS机启动时,同步服务器时间失败!");
Toast.makeText(this, "POS机启动时,同步服务器时间失败!", Toast.LENGTH_SHORT).show();
}
}
请求服务器时,将初始客户端的时间戳作为t1参数,传给服务器端:HTTP_Ntp_SyncTime = "ntp/syncEx.bx?t1=":
public boolean syncTime(long timeStamp) {
log.info("正在执行NtpHttpBO的syncTime,timeStamp=" + timeStamp);
Request req = new Request.Builder()
.url(Configuration.HTTP_IP + Ntp.HTTP_Ntp_SyncTime + timeStamp)
.addHeader(BaseHttpBO.COOKIE, GlobalController.getInstance().getSessionID())
.build();
HttpRequestUnit hru = new NtpSync();
hru.setRequest(req);
hru.setTimeout(TIME_OUT);
hru.setbPostEventToUI(true);
httpEvent.setEventProcessed(false);
httpEvent.setStatus(BaseEvent.EnumEventStatus.EES_Http_ToDo);
hru.setEvent(httpEvent);
NtpHttpBO.bForNtpOnly = true;
HttpRequestManager.getCache(HttpRequestManager.EnumDomainType.EDT_Communication).pushHttpRequest(hru);
log.info("正在请求服务器同步Ntp...");
return true;
}
2、服务器端收到请求,返回T2和T3,T2表示获取到客户端请求的时间,T3表示响应客户端请求的时间。
@RequestMapping(value = "/syncEx", produces = "plain/text; charset=UTF-8", method = RequestMethod.GET)
@ResponseBody
public String syncEx(@ModelAttribute("SpringWeb") Ntp ntp, ModelMap model, HttpSession session) {
if (!canCallCurrentAction(session, BaseAction.EnumUserScope.STAFF.getIndex())) {
logger.debug("无权访问本Action");
return null;
}
ntp.setT2(new Date().getTime());
Map<String, Object> params = new HashMap<String, Object>();
ntp.setT3(new Date().getTime());
params.put(BaseAction.KEY_Object, ntp);
params.put(BaseAction.JSON_ERROR_KEY, EnumErrorCode.EC_NoError.toString());
params.put(KEY_HTMLTable_Parameter_msg, "同步成功!");
return JSONObject.fromObject(params, JsonUtil.jsonConfig).toString();
}
3、客户端收到服务器的响应后,记录当前时间T4。
log.info(" Http onResponse,收到服务器的响应");
if (NtpHttpBO.bForNtpOnly) {// 在同步的时候设置POS接收到答复的时间,用于POS机与服务器同步时间
event.setData(new Date(System.currentTimeMillis() + NtpHttpBO.TimeDifference).getTime());
NtpHttpBO.bForNtpOnly = false;
}
存储到NTP对象的t4属性中:
long t4 = (long) getData(); // 在同步的时候设置POS接收到答复的时间,用于POS机与服务器时间同步,获取的是时间戳
log.info("ERT_NtpSync得到的对象是:" + ntp.toString());
ntp.setT4(t4);
setBaseModel1(ntp);
4、算出客户端和服务端的时间差TimeDifference。
Ntp ntp = (Ntp) event.getBaseModel1();
NtpHttpBO.TimeDifference = ((ntp.getT2() - ntp.getT1()) + (ntp.getT3() - ntp.getT4())) / 2;