2014-12-22 6 views
5

Ich arbeite mit Java und ich mache ein Spiel. In diesem Spiel ist die Echtzeit sehr wichtig. Aus diesem Grund versuche ich die Echtzeit mit Ntp zu bekommen.Wie bekomme ich Echtzeit für ein Spiel

Was ich im Web gefunden habe, ist dieser Code.

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); 
    } 
} 

Mein Problem ist, dass diese verwendet wird, wird das System immer noch die System.currentMillis bekommen(); weil es tatsächlich die Zeit ausdruckt, zu der Ihr lokaler Computer die Zeitnachricht erhalten hat. Aus diesem Grund ändert sich die Spielzeit, wenn der Spieler seine Desktop-Zeit in die Zukunft ändert.

Wenn jemand helfen könnte, um die Echtzeit zu haben, wäre ich sehr dankbar. P.S. Ich habe keinen Server, mein Spiel wird auf Kongregate spielen und die Daten werden auf dem Computer des Spielers sein.

Vielen Dank im Voraus.

+2

intern Ihre eigene Uhr laufen. vergleiche die Zeiten, in denen du vs. die Zeiten, die du tatsächlich hast, und wenn es einen großen Unterschied gibt, rufe Shenaningans an. –

+1

'getReturnTime' gibt Ihnen nicht die Zeit des Servers, den es Ihnen gibt * die Zeit, zu der das Nachrichtenpaket von der lokalen Maschine empfangen wurde. * (Gemäß dem Javadoc). –

+0

Ist das was die 'getDelay()' und 'getOffset()' Methoden sind? – Arkadiy

Antwort

2

Versuchen Sie folgendes:

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

gibt mir diese Nachricht. Die Methode connect (String) ist für den Typ NTPUDPClient nicht definiert. – Athorivos

+0

Entschuldigung, Sie verwenden einen anderen Client ... check my edit! ;) –

+1

Danke sagen ist zu wenig :) es funktioniert perfekt! – Athorivos

4

Erhalten Sie einfach die Zeit einmal über NTP am Anfang Ihres Programms und verwenden Sie dann System.nanoTime(), um die relative Zeit danach zu erhalten. Es ist komplett monotomisch und wird nicht über die Einstellung der Systemzeit geändert.

1

Gemäß der NTPUDPClient javadoc:

Um die Klasse zu verwenden, öffnen Sie lediglich eine lokale Datagramm-Socket mit offenen und rufen getTime() die Zeit abzurufen. Rufen Sie dann close auf, um die Verbindung ordnungsgemäß zu schließen. Aufeinanderfolgende Aufrufe von getTime sind zulässig, ohne dass eine Verbindung wiederhergestellt werden muss.

Sie einen Anruf an open() im Code fehlt (technisch close() auch, aber das ist nicht der Grund für das Problem).

In Ihren Anforderungen geben Sie an, dass Sie die Echtzeit benötigen (und nicht die Zeit, die der lokale Client einstellen kann). Diese Menge sollte nicht direkt erhalten werden, sondern als ein Offset, der erforderlich ist, um die lokale Zeit an die Serverzeit (entfernt) anzupassen, die durch die Methode getOffset() erhalten wird.

Wenn die Echtzeiterfassung ein übliches Verfahren ist, möchten Sie vielleicht NTP nur einmal beim Start verwenden und den ermittelten Offset verwenden, um die Systemzeit in der Zukunft zu korrigieren und die Latenz beim Abrufen von Echtzeit zu reduzieren.

Ein solches Verfahren kann in einer Klasse als solche beschrieben werden:

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) 
    } 
} 
Verwandte Themen