Light12306/TrainInfomationProviderService/StationInfo/StationManager.cs
2014-11-27 23:25:36 +08:00

219 lines
5.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.StationInfo.Entities;
namespace TrainInfomationProviderService.StationInfo
{
/// <summary>
/// </summary>
public class StationManager
{
private static readonly object _lockObject = new object();
private static StationManager _stationManager;
public static StationManager Instance
{
get
{
if (_stationManager == null)
{
lock (_lockObject)
{
if (_stationManager == null)
{
_stationManager = new StationManager();
}
}
}
return _stationManager;
}
}
/// <summary>
/// 创建 <see cref="StationManager" /> 的新实例(StationManager)
/// </summary>
public StationManager()
{
Trace.TraceInformation("[STATION] 车站管理器对象已新建");
}
private string _dataFilePath;
/// <summary>
/// 仓库
/// </summary>
public StationStorage Storage
{
get
{
return _storage;
}
}
public void Init()
{
Trace.TraceInformation("[STATION] 正在初始化");
_dataFilePath = PathUtility.Combine(RunTimeContext.DataStorageRoot, "stations.json");
Trace.TraceInformation("[STATION] 目标缓存文件路径:{0}", _dataFilePath);
//if (RunTimeContext.IsWeb)
//{
// Trace.TraceInformation("[STATION] WEB模式");
// InitWeb();
//}
//else
//{
Trace.TraceInformation("[STATION] 服务模式");
InitService();
//}
}
#region web环境
///// <summary>
///// web环境初始化
///// </summary>
//void InitWeb()
//{
// Trace.TraceInformation("[STATION] 初始化WEB模式");
// LoadCache();
//}
//void LoadCache()
//{
// Trace.TraceInformation("[STATION] 正在检查缓存刷新");
// _storage = null;
// if (File.Exists(_dataFilePath))
// {
// Trace.TraceInformation("[STATION] 正在加载缓存");
// _storage = JsonConvert.DeserializeObject<StationStorage>(File.ReadAllText(_dataFilePath));
// Trace.TraceInformation("[STATION] 缓存加载完成");
// }
// if (Storage != null)
// {
// Trace.TraceInformation("[STATION] 正在加入HttpRuntime缓存");
// HostingEnvironment.Cache.Add("_12306stations", Storage, new CacheDependency(_dataFilePath),
// Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.High,
// (_1, _2, _3) =>
// {
// Trace.TraceInformation("[STATION] HttpRuntime缓存已被清除原因{0},正在重新加载", _3);
// LoadCache();
// });
// Trace.TraceInformation("[STATION] HttpRuntime缓存加入完成");
// }
//}
#endregion
#region
private Timer _checkStationTimer;
private StationStorage _storage;
/// <summary>
/// 服务模式初始化
/// </summary>
void InitService()
{
if (_dataFilePath.AsFileInfo().Exists)
{
Trace.TraceInformation("[STATION] 正在加载文件缓存数据");
_storage = JsonConvert.DeserializeObject<StationStorage>(File.ReadAllText(_dataFilePath));
Trace.TraceInformation("[STATION] 文件缓存数据加载完成");
}
var lastestVersion = GetLatestVersionFromWeb();
var needUpdate = _storage == null || _storage.Version < lastestVersion;
Trace.TraceInformation("[STATION] 最新版本:{0}", lastestVersion);
if (needUpdate)
{
Trace.TraceInformation("[STATION] 正在刷新缓存");
RefreshStationInfo(lastestVersion);
SameStationManager.AutoRefreshFromSource();
Trace.TraceInformation("[STATION] 缓存数据已刷新");
}
_checkStationTimer = new Timer(_ => CheckStationVersion(), null, new TimeSpan(0, 30, 0), Timeout.InfiniteTimeSpan);
}
void RefreshStationInfo(int version)
{
Trace.TraceInformation("[STATION] 正在获得最新车站信息");
var html = new HttpClient().Create(HttpMethod.Get, "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js", null, null, "").Send();
if (!html.IsValid())
{
Trace.TraceError("[STATION] 车站信息获得失败。错误:{0}", html.Exception);
return;
}
Trace.TraceInformation("[STATION] 正在分析车站信息");
var mcs = Regex.Matches(html.Result, @"@([^\|]+)\|([^\|]+)\|([^\|]+)\|([^\|]+)\|([^\|]+)\|(\d+)");
var result = new List<StationDetailInfo>(mcs.Count);
foreach (Match mc in mcs)
{
var s = new StationDetailInfo()
{
Code = mc.GetGroupValue(3),
Name = mc.GetGroupValue(2),
Py = mc.GetGroupValue(5),
PyFull = mc.GetGroupValue(4),
Sort = mc.GetGroupValue(6).ToInt32()
};
result.Add(s);
}
_storage = new StationStorage(version, result);
Trace.TraceInformation("[STATION] 车站信息分析完成,{0} 车站。正在缓存车站信息", result.Count);
//save
File.WriteAllText(_dataFilePath, JsonConvert.SerializeObject(Storage));
Trace.TraceInformation("[STATION] 车站信息缓存完成。目标文件 {0}", _dataFilePath);
}
void CheckStationVersion()
{
var lastestVersion = GetLatestVersionFromWeb();
if (Storage == null || Storage.Version < lastestVersion)
{
RefreshStationInfo(lastestVersion);
}
_checkStationTimer.Change(new TimeSpan(0, 30, 0), Timeout.InfiniteTimeSpan);
}
/// <summary>
/// 从网络加载最新的版本号
/// </summary>
/// <returns></returns>
public int GetLatestVersionFromWeb()
{
var ctx = new HttpClient().Create<string>(HttpMethod.Get, "https://kyfw.12306.cn/otn/leftTicket/init", "https://kyfw.12306.cn/otn/leftTicket/init").Send();
if (!ctx.IsValid())
return 0;
var version = (int)(Regex.Match(ctx.Result, @"station_name\.js\?station_version=([\d\.]+)").GetGroupValue(1).ToSingle() * 100000);
return version;
}
#endregion
}
}