/// <summary> /// Processes to be carried out when a new SignalR connection has exposed.. /// </summary> /// <returns></returns> public async override Task OnConnectedAsync() { var identity = Context.User.Identity; //Check if the client authenticated.. if (identity.IsAuthenticated) { await Groups.AddToGroupAsync(Context.ConnectionId, identity.Name).ConfigureAwait(false); } else { Context.Abort(); } var ui = Context.UserIdentifier; var dt = DBlite.GetData($"SELECT Forecast.Id, Forecast.CityId, Location.CityName, Forecast.DailyMinTemperature, Forecast.DailyMaxTemperature, Forecast.WeeklyMinTemperature, Forecast.WeeklyMaxTemperature, Forecast.TS, Forecast.QueryElapsedMilliseconds AS ForecastQueryElapsedMilliseconds, Location.QueryElapsedMilliseconds AS LocationQueryElapsedMilliseconds FROM Forecast INNER JOIN Location ON Location.Id = Forecast.CityId WHERE Forecast.TS = @TS;", new ArrayList { new SQLiteParameter("@TS", DateTime.Now.Date.ToEpoch()) }); if (dt != null && dt.Rows.Count > 0) { var dailyQueries = new List <WeatherForecastModel>(); foreach (DataRow dr in dt.Rows) { dailyQueries.Add(new WeatherForecastModel { CityId = dr["CityId"].Obj2Int32(), CityName = dr["CityName"].Obj2String(), TS = dr["TS"].Obj2Int64(), DailyMinTemperature = dr["DailyMinTemperature"].Obj2Int32(), DailyMaxTemperature = dr["DailyMaxTemperature"].Obj2Int32(), WeeklyMinTemperature = dr["WeeklyMinTemperature"].Obj2Int32(), WeeklyMaxTemperature = dr["WeeklyMaxTemperature"].Obj2Int32(), ForecastQueryElapsedMilliseconds = dr["ForecastQueryElapsedMilliseconds"].Obj2Int64(), LocationQueryElapsedMilliseconds = dr["LocationQueryElapsedMilliseconds"].Obj2Int64(), }); } await Clients.User(ui).SendAsync("CurrentDayForecastQueries", dailyQueries); } await base.OnConnectedAsync(); }
static string _ForecastWSURL = "";//"https://api.darksky.net/forecast/[TOKEN]/[LATITUDE],[LONGITUDE]?lang=tr&units=si&exclude=minutely,hourly,alerts,flags"; /// <summary> /// Location service initialization /// </summary> /// <param name="wsToken">Forecast service token</param> internal static void Init(string wsToken = null) { _ForecastWSURL = $"https://api.darksky.net/forecast/{(wsToken ?? "f3146e0fc78b4930d41a60703c08e2ae")}/[LATITUDE],[LONGITUDE]?lang=tr&units=si&exclude=minutely,hourly,alerts,flags"; try { var res = DBlite.ExecuteSQL("CREATE TABLE IF NOT EXISTS Forecast (Id INTEGER PRIMARY KEY AUTOINCREMENT, CityId INTEGER, DailyMinTemperature TEXT, DailyMaxTemperature TEXT, WeeklyMinTemperature TEXT, WeeklyMaxTemperature TEXT, TS INTEGER, QueryElapsedMilliseconds INTEGER); CREATE INDEX IF NOT EXISTS ndx_TS ON Forecast(TS); CREATE UNIQUE INDEX IF NOT EXISTS ndx_CityId_TS ON Forecast(CityId,TS);"); if (res == -1) { Log.Error("Forecast table create error"); } } catch (Exception ex) { Log.Error("Forecast table create error", ex.ToString()); return; } }
static string _LocationWSURL = "";//"https://eu1.locationiq.com/v1/search.php?key=[TOKEN]&q=[LOCATION]&format=json"; /// <summary> /// Location service initialization /// </summary> /// <param name="wsToken">Location service token</param> internal static void Init(string wsToken = null) { _LocationWSURL = $"https://eu1.locationiq.com/v1/search.php?key={(wsToken ?? "a1779b7817b3b2")}&q=[LOCATION]&format=json"; try { var res = DBlite.ExecuteSQL("CREATE TABLE IF NOT EXISTS Location (Id INTEGER PRIMARY KEY AUTOINCREMENT, CityName TEXT, Latitude TEXT, Longitude TEXT, QueryElapsedMilliseconds INTEGER); CREATE UNIQUE INDEX IF NOT EXISTS ndx_CityName ON Location(CityName);"); if (res == -1) { Log.Error("Location table create error"); } } catch (Exception ex) { Log.Error("Location table create error", ex.ToString()); return; } }
/// <summary> /// Fetches forecast info by city name from related remote api /// </summary> /// <param name="cityId">City Id</param> /// <param name="latitude">City coordinates latitude value</param> /// <param name="longitude">City coordinates longitude value</param> /// <returns>ForecastModel</returns> internal static WeatherForecastModel FetchForecastInfo(int cityId, string latitude, string longitude) { WeatherForecastModel weatherForecast = null; var currrentTSHour = Convert.ToInt64((Math.Floor((decimal)(DateTime.Now.ToEpoch()) / 3600) * 3600)); if (!methodRequests.ContainsKey(currrentTSHour)) // eger guncel saat dict icinde yoksa ekleme ve onceki saatle islem yapma bolumu { methodRequests[currrentTSHour] = new ConcurrentDictionary <int, WeatherForecastModel>(); } if (methodRequests[currrentTSHour].ContainsKey(cityId)) { return(methodRequests[currrentTSHour].Where(r => r.Key == cityId).Select(r => r.Value).FirstOrDefault()); } Stopwatch sw = Stopwatch.StartNew(); try { using (var httpClient = new HttpClient()) { using (var response = httpClient.GetAsync(_ForecastWSURL.Replace("[LATITUDE]", latitude ?? "41.0096334").Replace("[LONGITUDE]", longitude ?? "28.9651646")).Result) { using (var content = response.Content) { //get the json result from location api var result = content.ReadAsStringAsync().Result; var forecastModel = Deserialize.FromJson(result); if (forecastModel != null) { var curDayForecast = forecastModel.Daily.Data.OrderBy(r => r.Time).FirstOrDefault(); var ts = curDayForecast.Time; var dailyMinTemperature = (int)Math.Round(curDayForecast.TemperatureMin, 0); var dailyMaxTemperature = (int)Math.Round(curDayForecast.TemperatureMax, 0); var weeklyMinTemperature = (int)Math.Round(forecastModel.Daily.Data.OrderBy(r => r.TemperatureMin).FirstOrDefault().TemperatureMin, 0); var weeklyMaxTemperature = (int)Math.Round(forecastModel.Daily.Data.OrderByDescending(r => r.TemperatureMax).FirstOrDefault().TemperatureMax, 0); sw.Stop(); weatherForecast = new WeatherForecastModel { CityId = cityId, TS = ts, DailyMinTemperature = dailyMinTemperature, DailyMaxTemperature = dailyMaxTemperature, WeeklyMinTemperature = weeklyMinTemperature, WeeklyMaxTemperature = weeklyMaxTemperature, ForecastQueryElapsedMilliseconds = sw.ElapsedMilliseconds, }; //max 50 records if (methodRequests.Count >= 50) { methodRequests[currrentTSHour] = new ConcurrentDictionary <int, WeatherForecastModel>(); } //if cityId does not exist if (!methodRequests[currrentTSHour].ContainsKey(cityId)) { methodRequests[currrentTSHour].TryAdd(cityId, weatherForecast); } //This is more simple to check if the record is available or not then if record not available save etc.. var res = DBlite.ExecuteSQL($"INSERT OR IGNORE INTO Forecast (CityId, DailyMinTemperature, DailyMaxTemperature, WeeklyMinTemperature, WeeklyMaxTemperature, TS, QueryElapsedMilliseconds) VALUES (@CityId, @DailyMinTemperature, @DailyMaxTemperature, @WeeklyMinTemperature, @WeeklyMaxTemperature, @TS, @QueryElapsedMilliseconds);", new ArrayList { new SQLiteParameter("@CityId", cityId), new SQLiteParameter("@DailyMinTemperature", dailyMinTemperature.Obj2String()), new SQLiteParameter("@DailyMaxTemperature", dailyMaxTemperature.Obj2String()), new SQLiteParameter("@WeeklyMinTemperature", weeklyMinTemperature.Obj2String()), new SQLiteParameter("@WeeklyMaxTemperature", weeklyMaxTemperature.Obj2String()), new SQLiteParameter("@TS", ts), new SQLiteParameter("@QueryElapsedMilliseconds", weatherForecast.ForecastQueryElapsedMilliseconds) }); if (res == -1) { Log.Error("Forecast table insert error"); } else { var dt = DBlite.GetData($"SELECT Forecast.Id, Forecast.CityId, Location.CityName, Forecast.DailyMinTemperature, Forecast.DailyMaxTemperature, Forecast.WeeklyMinTemperature, Forecast.WeeklyMaxTemperature, Forecast.TS, Forecast.QueryElapsedMilliseconds AS ForecastQueryElapsedMilliseconds, Location.QueryElapsedMilliseconds AS LocationQueryElapsedMilliseconds FROM Forecast INNER JOIN Location ON Location.Id = Forecast.CityId WHERE Forecast.CityId = @CityId AND Forecast.TS = @TS;", new ArrayList { new SQLiteParameter("@CityId", cityId), new SQLiteParameter("@TS", ts), }); if (dt != null && dt.Rows.Count > 0) { var dr = dt.Rows[0]; weatherForecast = new WeatherForecastModel { CityId = dr["CityId"].Obj2Int32(), TS = dr["TS"].Obj2Int64(), DailyMinTemperature = dr["DailyMinTemperature"].Obj2Int32(), DailyMaxTemperature = dr["DailyMaxTemperature"].Obj2Int32(), WeeklyMinTemperature = dr["WeeklyMinTemperature"].Obj2Int32(), WeeklyMaxTemperature = dr["WeeklyMaxTemperature"].Obj2Int32(), ForecastQueryElapsedMilliseconds = dr["ForecastQueryElapsedMilliseconds"].Obj2Int64(), LocationQueryElapsedMilliseconds = dr["LocationQueryElapsedMilliseconds"].Obj2Int64(), }; } } } } } } } catch (Exception ex) { Log.Error("ForecastService : " + ex.ToString()); } return(weatherForecast); }
/// <summary> /// Fetches location info by city name from related remote api /// </summary> /// <param name="cityName">City Name</param> /// <returns>LocationModel</returns> internal static LocationModel FetchLocationInfo(string cityName) { cityName = RemoveDiacritics(cityName.ToLower()); LocationModel locationModel = null; var currrentTSHour = Convert.ToInt64((Math.Floor((decimal)(DateTime.Now.ToEpoch()) / 3600) * 3600)); if (!methodRequests.ContainsKey(currrentTSHour)) // eger guncel saat dict icinde yoksa ekleme ve onceki saatle islem yapma bolumu { methodRequests[currrentTSHour] = new ConcurrentDictionary <string, LocationModel>(); } if (methodRequests[currrentTSHour].ContainsKey(cityName)) { return(methodRequests[currrentTSHour].Where(r => r.Key == cityName).Select(r => r.Value).FirstOrDefault()); } Stopwatch sw = Stopwatch.StartNew(); try { using (var httpClient = new HttpClient()) { using (var response = httpClient.GetAsync(_LocationWSURL.Replace("[LOCATION]", cityName ?? "istanbul")).Result) { using (var content = response.Content) { //get the json result from location api var result = content.ReadAsStringAsync().Result; locationModel = Deserialize.FromJson(result).FirstOrDefault(); sw.Stop(); if (locationModel != null) { //TO DO : consider same spelled different places.. //This is more simple to check if the record is available or not then if record not available save etc.. var res = DBlite.ExecuteSQL($"INSERT OR IGNORE INTO Location (CityName, Latitude, Longitude, QueryElapsedMilliseconds) VALUES (@CityName, @Latitude, @Longitude, @QueryElapsedMilliseconds);", new ArrayList { new SQLiteParameter("@CityName", cityName), new SQLiteParameter("@Latitude", locationModel.Lat), new SQLiteParameter("@Longitude", locationModel.Lon), new SQLiteParameter("@QueryElapsedMilliseconds", sw.ElapsedMilliseconds) }); if (res == -1) { Log.Error("Location table insert error"); } else { var dt = DBlite.GetData($"SELECT Id, Latitude, Longitude, QueryElapsedMilliseconds FROM Location WHERE CityName = @CityName;", new ArrayList { new SQLiteParameter("@CityName", cityName) }); if (dt != null && dt.Rows.Count > 0) { var dr = dt.Rows[0]; locationModel = new LocationModel { CityId = dr["Id"].Obj2Int32(), CityName = cityName, Lat = dr["Latitude"].Obj2String(), Lon = dr["Longitude"].Obj2String(), QueryElapsedMilliseconds = dr["QueryElapsedMilliseconds"].Obj2Int64(), }; //max 50 records if (methodRequests.Count >= 50) { methodRequests[currrentTSHour] = new ConcurrentDictionary <string, LocationModel>(); } //if cityId does not exist if (!methodRequests[currrentTSHour].ContainsKey(cityName)) { methodRequests[currrentTSHour].TryAdd(cityName, locationModel); } } } } } } } } catch (Exception ex) { Log.Error("LocationService : " + ex.ToString()); } return(locationModel); }