Java实现客户端与服务器端的时间同步

在客户端获取的当前时间和在服务端获取的当前时间往往会存在差异。有时我们需要知道在客户端创建数据时,相对于服务器的时间是多少。这是我们需要知道客户端和服务端获取当前时间的时间差,从而可以算出相对于服务器的时间。主要的过程分为:“在客户端启动时,请求服务器端,发送当前客户端时间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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值