2014-12-22 2 views
5

Я работаю с Java, и я делаю игру. В этой игре реальное время - очень важная часть. По этой причине я пытаюсь получить реальное время, используя Ntp.Как получить реальное время для игры

Что я нашел в Интернете, это код.

import java.net.InetAddress; 
import java.util.Date; 
import org.apache.commons.net.ntp.NTPUDPClient; 
import org.apache.commons.net.ntp.TimeInfo; 

public class test{ 
    public static void main(String args[]) throws Exception{ 
     String TIME_SERVER = "time-a.nist.gov"; 
     NTPUDPClient timeClient = new NTPUDPClient(); 
     InetAddress inetAddress = InetAddress.getByName(TIME_SERVER); 
     TimeInfo timeInfo = timeClient.getTime(inetAddress); 

     long returnTime = timeInfo.getReturnTime(); 
     Date time = new Date(returnTime); 

     System.out.println("Time from " + TIME_SERVER + ": " + time); 
    } 
} 

Моя проблема заключается в том, что с использованием этого система все еще получает System.currentMillis(); потому что он на самом деле печатает вам время, когда ваш локальный компьютер получил сообщение о времени. По этой причине, если игрок изменит свое рабочее время на будущее, время игры также изменится.

Если кто-то может помочь, чтобы иметь реальное время, я был бы очень благодарен. P.S. У меня нет сервера, моя игра будет играть на Kongregate, и данные будут на компьютере игроков.

Заранее спасибо.

+2

запустить собственные часы внутри. сравните время, которое вы ДОЛЖНЫ получать vs. время, которое вы на самом деле получили, и если есть огромная разница, позвоните в shenaningans. –

+1

'getReturnTime' не дает вам времени на сервере, которое дает вам * время, в которое был отправлен пакет сообщений на локальном компьютере. * (Согласно javadoc). –

+0

Это методы 'getDelay()' и 'getOffset()'? – Arkadiy

ответ

2

Попробуйте это:

String TIME_SERVER = "time-a.nist.gov"; 
TimeTCPClient client = new TimeTCPClient(); 

try { 
    client.connect(TIME_SERVER); 
    System.out.println(client.getDate()); 
} finally { 
    client.disconnect(); 
} 
+0

это дает мне это сообщение. Метод connect (String) не определен для типа NTPUDPClient. – Athorivos

+0

Извините, вы используете другой тип клиента ... проверьте мое редактирование! ;) –

+1

Сказать спасибо слишком мало :) он отлично работает! – Athorivos

4

Просто найдите время через NTP в начале вашей программы, а затем используйте System.nanoTime(), чтобы получить относительное время после этого. Он полностью монотомичен и не будет изменен через установку системного времени.

1

Согласно NTPUDPClient Javadoc:

Чтобы использовать класс, просто открыть локальный сокет датаграмм с открытым и вызвать getTime() для получения времени. Затем вызовите близко, чтобы закрыть соединение правильно. Последовательные вызовы getTime разрешены без повторного установления соединения.

Вы пропускаете вызов open() в коде (технически close() как хорошо, но это не причина вашей проблемы).

Кроме того, в ваших требованиях вы указываете, что вам нужно в реальном времени (и не то время, которое может установить местный клиент). Эта величина не должна быть получена напрямую, а в качестве смещения, необходимого для соответствия местному времени серверному (удаленному) времени, полученному методом getOffset().

Если получение реального времени является обычной процедурой, вы можете использовать только NTP один раз в начале и использовать полученное смещение для исправления системного времени в будущем, уменьшая задержку при получении реального времени.

Такой процесс может быть описан в классе, как, например:

public class TimeKeeper{ 
    // Constant: Time Server 
    private final String TIME_SERVER = "time-a.nist.gov"; 

    // Last time the time offset was retrieved via NTP 
    private long last_offset_time = -1; 

    // The real time, calculated from offsets, of when the last resync happened 
    private long retrieve_time; 

    private synchronized void resync(){ 
     NTPUDPClient timeClient = new NTPUDPClient(); 
     InetAddress inetAddress = InetAddress.getByName(TIME_SERVER); 
     TimeInfo timeInfo = null; 

     try{ 
      timeClient.open(); 
      timeInfo = timeClient.getTime(inetAddress); 
     }catch(IOException ex){ 
      return; 
     }finally{ 
      timeClient.close(); 
     } 

     // Real time calculated from the offset time and the current system time. 
     retrieve_time = System.currentTimeMillis() + timeInfo.getOffset(); 
     last_offset_time = System.nanoTime(); 
    } 

    public long getRealTimeInMillis(){ 
     // Possible to set some resync criteria here 
     if(last_offset_time == -1){ 
      resync(); 

      // Handle exception whilst retrieving time here 
     } 

     // Returns the system time, corrected with the offset 
     return retrieve_time + Math.round((System.nanoTime() - last_offset_time)/1000.0) 
    } 
} 
Смежные вопросы