using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Web.Caching; using System.Web.Hosting; using FSLib.Network.Http; using Newtonsoft.Json; using TrainInfomationProviderService.TrainInfo.Entities; namespace TrainInfomationProviderService.TrainInfo { public class TrainInfoManager { private static readonly object _lockObject = new object(); private static TrainInfoManager _stationManager; public static TrainInfoManager Instance { get { if (_stationManager == null) { lock (_lockObject) { if (_stationManager == null) { _stationManager = new TrainInfoManager(); } } } return _stationManager; } } /// /// 创建 的新实例(StationManager) /// protected TrainInfoManager() { Trace.TraceInformation("[TAININFOMANGER] 车站管理器对象已新建"); } private string _dataFilePath; /// /// 仓库 /// public IndexStorage Storage { get { if (RunTimeContext.IsWeb) { return HostingEnvironment.Cache["_12306trains"] as IndexStorage; } return _storage; } } public void Init() { Trace.TraceInformation("[TAININFOMANGER] 正在初始化"); _dataFilePath = PathUtility.Combine(RunTimeContext.DataStorageRoot, "trains.json"); Trace.TraceInformation("[TAININFOMANGER] 目标缓存文件路径:{0}", _dataFilePath); if (RunTimeContext.IsWeb) { Trace.TraceInformation("[TAININFOMANGER] WEB模式"); InitWeb(); } else { Trace.TraceInformation("[TAININFOMANGER] 服务模式"); InitService(); } } #region web环境 /// /// web环境初始化 /// void InitWeb() { Trace.TraceInformation("[TAININFOMANGER] 初始化WEB模式"); LoadCache(); } void LoadCache() { Trace.TraceInformation("[TAININFOMANGER] 正在检查缓存刷新"); _storage = null; if (File.Exists(_dataFilePath)) { Trace.TraceInformation("[TAININFOMANGER] 正在加载缓存"); _storage = JsonConvert.DeserializeObject(File.ReadAllText(_dataFilePath)); Trace.TraceInformation("[TAININFOMANGER] 缓存加载完成"); } if (Storage != null) { Trace.TraceInformation("[TAININFOMANGER] 正在加入HttpRuntime缓存"); HostingEnvironment.Cache.Add("_12306trains", Storage, new CacheDependency(_dataFilePath), Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.High, (_1, _2, _3) => { Trace.TraceInformation("[TAININFOMANGER] HttpRuntime缓存已被清除,原因:{0},正在重新加载", _3); LoadCache(); }); Trace.TraceInformation("[TAININFOMANGER] HttpRuntime缓存加入完成"); } } #endregion #region 服务模式 private Timer _checkStationTimer; private IndexStorage _storage; #if DEBUG private bool _ininitalized = true; #else private bool _ininitalized = false; #endif /// /// 服务模式初始化 /// void InitService() { if (_dataFilePath.AsFileInfo().Exists) { Trace.TraceInformation("[TAININFOMANGER] 正在加载文件缓存数据"); _storage = JsonConvert.DeserializeObject(File.ReadAllText(_dataFilePath)); Trace.TraceInformation("[TAININFOMANGER] 文件缓存数据加载完成"); } else { _storage = new IndexStorage(); } var lastestVersion = GetLatestVersionFromWeb(); var needUpdate = _storage == null || _storage.Version < lastestVersion; Trace.TraceInformation("[TAININFOMANGER] 最新版本:{0}", lastestVersion); if (needUpdate || !_ininitalized) { Trace.TraceInformation("[TAININFOMANGER] 正在刷新缓存"); RefreshTrainInfo(lastestVersion); Trace.TraceInformation("[TAININFOMANGER] 缓存数据已刷新"); } _ininitalized = true; _checkStationTimer = new Timer(_ => CheckTrainVersion(), null, new TimeSpan(0, 30, 0), Timeout.InfiniteTimeSpan); } void RefreshTrainInfo(int version) { Trace.TraceInformation("[TAININFOMANGER] 正在刷新车次信息"); var loader = new WebDataProvider(); try { Storage.Version = version; loader.LoadTrainInfo(Storage); } catch (Exception ex) { Trace.TraceError("TAININFOMANGER] 车次信息更新出错:{0}", ex); } //Storage = new TrainInfoStorage(); Trace.TraceInformation("[TAININFOMANGER] 车次信息分析完成,车站。正在缓存车站信息"); //save File.WriteAllText(_dataFilePath, JsonConvert.SerializeObject(Storage)); Trace.TraceInformation("[TAININFOMANGER] 车站信息缓存完成。目标文件 {0}", _dataFilePath); } void CheckTrainVersion() { var lastestVersion = GetLatestVersionFromWeb(); if (Storage == null || Storage.Version < lastestVersion) { RefreshTrainInfo(lastestVersion); } _checkStationTimer.Change(new TimeSpan(0, 30, 0), Timeout.InfiniteTimeSpan); } /// /// 从网络加载最新的版本号 /// /// public int GetLatestVersionFromWeb() { var ctx = new HttpClient().Create(HttpMethod.Get, "https://kyfw.12306.cn/otn/queryTrainInfo/init", "https://kyfw.12306.cn/otn/queryTrainInfo/init").Send(); if (!ctx.IsValid()) return 0; var version = (int)(Regex.Match(ctx.Result, @"train_list\.js\?scriptVersion=([\d\.]+)").GetGroupValue(1).ToSingle() * 100000); return version; } #endregion } }