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