Search Unity

Retrieve Date and Time from the Internet

Discussion in 'Multiplayer' started by skeptika, Nov 15, 2016.

  1. skeptika

    skeptika

    Joined:
    Dec 31, 2011
    Posts:
    108
    As a way to prevent cheating, I wanted to pull the current Date and Time from the net. So I tried this, and it works just fine in editor. However, when I deploy to WebGL, it gets nothing back in response. The code executes, but returns netTime as a null string. Again, in editor, it works exactly as intended and returns the date/time as a string. WebGL fails. Any ideas why? My understanding is that UnityWebRequest should be working with WebGL per the documentation (I'm using 5.5, it says implemented by 5.3)?

    Code (csharp):
    1.  
    2. public IEnumerator GetInternetTime()
    3. {
    4.     UnityWebRequest myHttpWebRequest = UnityWebRequest.Get("http://www.microsoft.com");
    5.     yield return myHttpWebRequest.Send();
    6.  
    7.     string netTime = myHttpWebRequest.GetResponseHeader("date");
    8.     Debug.Log(netTime + " was response");
    9. }
    netTime returns a nice long string with the date/time in editor, returns nothing though when deployed to WebGL? Am I missing something?
     
    Last edited: Nov 15, 2016
    fahimkamal63 likes this.
  2. LukeDawn

    LukeDawn

    Joined:
    Nov 10, 2016
    Posts:
    404
    Maybe microsoft's server doesn't like the webplayer's user-agent string? Or are there other restrictions on what a webplayer can do?
     
  3. skeptika

    skeptika

    Joined:
    Dec 31, 2011
    Posts:
    108
    Tried multiple sites (besides MS), they all work locally, none work in WebGL. My guess atm is it works locally b/c there is no cross-domain issue (CORS), but once in browser, it's hitting a CORS issue. I'm trying a CORS proxy to see if that fixes it.
     
  4. skeptika

    skeptika

    Joined:
    Dec 31, 2011
    Posts:
    108
    Nope, even when I use a CORS proxy, it gets rid of the error returned, but I'm still getting absolutely nothing back. Sigh. Any ideas network knowledgeable folks? I'm amenable to alternate solutions if there's a slicker way to get date/time from the net?
     
  5. LukeDawn

    LukeDawn

    Joined:
    Nov 10, 2016
    Posts:
    404
  6. skeptika

    skeptika

    Joined:
    Dec 31, 2011
    Posts:
    108
    Yah it's not CORS, I used https://crossorigin.me to see if that was the problem. It doesn't solve it, I'm getting absolutely nothing back in WebGL, although it seems to work in editor and PC platform...

    I double checked I'm not getting any error with myHttpWebRequest.error is .isError. No error, just null coming back on WebGL. :(

    I even tried using the legacy WWW, and the exact same result. Null.

    Code (csharp):
    1.  
    2. WWW www = new WWW("http://www.whattimeisit.com/");
    3. yield return www;
    4. www.text
    www.text works fine in editor, properly grabs websites text, but in WebGL, nothing but null. True for WWW, true for UnityWebRequest. I'm out of ideas :(
     
    Last edited: Nov 15, 2016
  7. LukeDawn

    LukeDawn

    Joined:
    Nov 10, 2016
    Posts:
    404
  8. skeptika

    skeptika

    Joined:
    Dec 31, 2011
    Posts:
    108
    I actually couldn't get his NTP script to work at all. Even then, the issue isn't that above method doesn't work, it does! It just doesn't work on WebGL!

    That said, I finally got it to return me SOME text using WWW, so I'll just go down that road and see if I can find a website without ridiculous text for me to parse :) Really should work with UnityWebRequest though...

    Oh thank god someone made a reasonable website: http://www.timeapi.org/utc/now

    That's a string I can work with!
     
    Last edited: Nov 15, 2016
  9. Leaton

    Leaton

    Joined:
    Jun 21, 2013
    Posts:
    4
    I had a similar issue and I figured it out then wrote a small guide http://leatonm.net/unity3d-internet-time-and-date-guide-stop-time-cheat/
     
  10. Deleted User

    Deleted User

    Guest

    Code (CSharp):
    1. public static DateTime GetNetTime()
    2. {
    3.     var myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.microsoft.com");
    4.     var response = myHttpWebRequest.GetResponse();
    5.     string todaysDates = response.Headers["date"];
    6.     return DateTime.ParseExact(todaysDates,
    7.                                "ddd, dd MMM yyyy HH:mm:ss 'GMT'",
    8.                                CultureInfo.InvariantCulture.DateTimeFormat,
    9.                                DateTimeStyles.AssumeUniversal);
    10. }
     
    Last edited by a moderator: Jul 19, 2020
  11. Shafiur_RUL

    Shafiur_RUL

    Joined:
    Jan 23, 2019
    Posts:
    1
    This occur issues on android build. works perfectly on editor. any ideas?
     
    trunghieu974 likes this.
  12. JSTTSJ

    JSTTSJ

    Joined:
    Jan 8, 2019
    Posts:
    3

    You helped me so much. To anyone who comes along, this helped a lot, and it might help you to.

    I had to add some using tags though, namely:
    using System;
    using System.Globalization;
    using System.Net;
     
  13. cgkaransahu

    cgkaransahu

    Joined:
    Jan 8, 2020
    Posts:
    5
  14. zexzill

    zexzill

    Joined:
    Mar 6, 2019
    Posts:
    3
    This works for me :) and just add some try catch and everything is done.. thanks :)
     
  15. unknownsk

    unknownsk

    Joined:
    Jan 16, 2020
    Posts:
    36
    does not works on webgl sadly
     
  16. trunghieu974

    trunghieu974

    Joined:
    Jun 19, 2015
    Posts:
    25
    i have same problem when using it on android. The scene is stuck, but no error log appear. Does anyone know the reason?
     
  17. Talrhyon

    Talrhyon

    Joined:
    Jun 8, 2019
    Posts:
    18
    Same problem here, when i try to get the date my scene freeze some sec (something like 40sec). I put a try / catch and it always goes in catch (i have internet)
     
  18. GiyomuGames

    GiyomuGames

    Joined:
    Jan 12, 2015
    Posts:
    80
    Based on the information gathered here and there I wrote this static class that retrieves the internet time asynchronously (no scene freeze).

    Call TimeManager.InitializeTime() at the start of your game and handle errors as you want. Then use TimeManager.UtcNow to get the current UTC time. If you want the local time add DateTimeStyles.AssumeUniversal as the last argument of DateTime.ParseExact (and modify the _utcStartTime name and initial value).

    Note that this is not a great solution if you need the time for the internet very early in your code because we don't know when the async method will finish. You could add some bool flag to know if the time was retrieved or not (or if something went wrong) to get around this issue though.

    Code (CSharp):
    1. using System;
    2. using System.Globalization;
    3. using System.IO;
    4. using System.Net.Sockets;
    5. using System.Threading.Tasks;
    6. using UnityEngine;
    7.  
    8. public static class TimeManager
    9. {
    10.     private static DateTime _utcStartTime = DateTime.UtcNow;
    11.     public static DateTime UtcNow => _utcStartTime.AddSeconds(Time.realtimeSinceStartup);
    12.  
    13.     public static void InitializeTime()
    14.     {
    15.         GetUtcTimeAsync().WrapErrors();
    16.     }
    17.  
    18.     private static async Task GetUtcTimeAsync()
    19.     {
    20.         try
    21.         {
    22.             var client = new TcpClient();
    23.             await client.ConnectAsync("time.nist.gov", 13);
    24.             using var streamReader = new StreamReader(client.GetStream());
    25.             var response = await streamReader.ReadToEndAsync();
    26.             var utcDateTimeString = response.Substring(7, 17);
    27.             _utcStartTime = DateTime.ParseExact(utcDateTimeString, "yy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
    28.         }
    29.         catch
    30.         {
    31.             // Handle errors here
    32.         }
    33.     }
    34.  
    35.     private static async void WrapErrors(this Task task)
    36.     {
    37.         await task;
    38.     }
    39. }
     
    kdserra likes this.