254 lines
9.4 KiB
C#
254 lines
9.4 KiB
C#
using MongoDB.Bson;
|
|
using MongoDB.Driver;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace LolDataRequestLib
|
|
{
|
|
/// <summary>
|
|
/// 실시간으로 업데이트를 해야하는 데이터들의 추상팩토리클래스.
|
|
/// </summary>
|
|
internal abstract class ARequestData
|
|
{
|
|
|
|
/// <summary>
|
|
/// DB Access 클라이언트.
|
|
/// </summary>
|
|
protected MongoClient mDBClient = new MongoClient(DBDefine.MONGODB주소);
|
|
|
|
/// <summary>
|
|
/// DB데이터베이스.
|
|
/// </summary>
|
|
protected IMongoDatabase eventDataBase = null;
|
|
|
|
/// <summary>
|
|
/// 가장 최근에 업데이트했던 데이터의 인덱스.
|
|
/// 같은 데이터를 계속 업데이트 하는 것을 막는다.
|
|
/// </summary>
|
|
protected int mLastDataSequanceIndex = 0;
|
|
|
|
|
|
/// <summary>
|
|
/// 데이터를 가져올 DB 컬렉션(테이블) 이름
|
|
/// </summary>
|
|
protected string mCollectionName = "";
|
|
|
|
/// <summary>
|
|
/// db에서 가져와서 manager에 업데이트하기위해 가공된 BsonValue
|
|
/// </summary>
|
|
protected BsonValue mUpdatedBsonValue = null;
|
|
|
|
/// <summary>
|
|
/// 인스턴스를 생산하기위해 요청된 데이터타입.
|
|
/// </summary>
|
|
protected DBDefine.RequestDataType mRequestType = DBDefine.RequestDataType.BAN_AND_PICK;
|
|
|
|
/// <summary>
|
|
/// 팩토리 Create메서드
|
|
/// </summary>
|
|
/// <param name="recvRequestType"></param>
|
|
/// <returns></returns>
|
|
internal static ARequestData createRequestFactory(DBDefine.RequestDataType recvRequestType)
|
|
{
|
|
|
|
ARequestData bufInstance = null;
|
|
|
|
try
|
|
{
|
|
|
|
switch (recvRequestType)
|
|
{
|
|
case DBDefine.RequestDataType.BAN_AND_PICK:
|
|
bufInstance = new BanPickRequest();
|
|
bufInstance.mCollectionName = "champ_select";
|
|
break;
|
|
case DBDefine.RequestDataType.GAME_STATUS:
|
|
bufInstance = new GameStatusRequest();
|
|
bufInstance.mCollectionName = "stats_update";
|
|
break;
|
|
case DBDefine.RequestDataType.OBJECT_EVENT:
|
|
bufInstance = new ObjectDataRequest();
|
|
bufInstance.mCollectionName = "epic_monster_kill";
|
|
break;
|
|
case DBDefine.RequestDataType.STRUCT_EVENT:
|
|
bufInstance = new StructDataRequest();
|
|
bufInstance.mCollectionName = "building_destroyed";
|
|
break;
|
|
case DBDefine.RequestDataType.DRAGON_RESPAWN:
|
|
bufInstance = new DragonRequest();
|
|
bufInstance.mCollectionName = "queued_dragon_info";
|
|
break;
|
|
case DBDefine.RequestDataType.ATAKHAN_RESPAWN:
|
|
bufInstance = new AtakhanRequest();
|
|
bufInstance.mCollectionName = "queued_epic_monster_info";
|
|
break;
|
|
case DBDefine.RequestDataType.STRUCT_GOLD_EVENT:
|
|
bufInstance = new StructGoldDataRequest();
|
|
bufInstance.mCollectionName = "building_gold_grant";
|
|
break;
|
|
}
|
|
|
|
//조회를 위한 RequestType등록.
|
|
bufInstance.mRequestType = recvRequestType;
|
|
|
|
//데이터베이스(Schema)선택
|
|
bufInstance.eventDataBase = bufInstance.mDBClient.GetDatabase("datalol");
|
|
|
|
//ThreadPool에 업데이트워크를 등록
|
|
ThreadPool.QueueUserWorkItem(o => { bufInstance.UpdateWorker(); });
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
Console.WriteLine(ex.ToString());
|
|
}
|
|
|
|
return bufInstance;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 인스턴스의 DB주소를 변경
|
|
/// 20210614 현재 사용하지 않는다.
|
|
/// Mongodb의 커넥션 인스턴스가 Mariadb와 달라서 비슷하게 접근했다가 Connection이 Disconnect되는 현상이 계속 발생했다.
|
|
/// </summary>
|
|
internal void resetDBAddress()
|
|
{
|
|
mDBClient = new MongoClient(DBDefine.MONGODB주소);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 업데이트 인덱스를 초기화한다.
|
|
/// 20210608 첫용이 업데이트 되지 않는 버그를 수정하면서 추가.
|
|
/// </summary>
|
|
internal void initIndex()
|
|
{
|
|
this.mLastDataSequanceIndex = 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 인스턴스내에 데이터를 업데이트 하는 워커메서드.
|
|
/// 해당메서드를 스레드풀에 넣고 반복문을 통해 계속 업데이트한다.
|
|
/// </summary>
|
|
internal void UpdateWorker()
|
|
{
|
|
|
|
while (DataManager.getInstance().IsupdateWorkersWork)
|
|
{
|
|
try
|
|
{
|
|
//DB에서 데이터를 가져온다.
|
|
this.requestDataMongoDB();
|
|
|
|
|
|
//조회되는 데이터가 없을경우 테이블을 비운다.
|
|
if (mUpdatedBsonValue == null)
|
|
{
|
|
this.exchangeTable();
|
|
}
|
|
//조회되는 데이터가 기존 데이터와 INDEX가 같지 않을경우 데이터를 업데이트한다.
|
|
else if (mUpdatedBsonValue["sequenceIndex"].ToInt32() != this.mLastDataSequanceIndex)
|
|
{
|
|
this.exchangeTable();
|
|
this.mLastDataSequanceIndex = mUpdatedBsonValue["sequenceIndex"].ToInt32();
|
|
}
|
|
|
|
//조회 후 인터벌 시간동안 슬립.
|
|
Thread.Sleep(DataManager.getInstance().리퀘스트인터벌밀리초);
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//DataManager.getInstance().mCallback.errorReceivedByWorker(요청데이터, ex.ToString());
|
|
//break;
|
|
#if(DEBUG)
|
|
{
|
|
Console.WriteLine(ex.ToString());
|
|
}
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// DB에서 데이터를 요청하는 메서드.
|
|
/// </summary>
|
|
protected virtual void requestDataMongoDB()
|
|
{
|
|
try
|
|
{
|
|
//var filter = Builders<BsonDocument>.Filter.Eq("RequestGameID", DataManager.getInstance().mPlatformGameID);
|
|
|
|
var projection = Builders<BsonDocument>.Projection
|
|
.Exclude("_id")
|
|
.Include("eventDocument");
|
|
|
|
List<BsonDocument> documents = eventDataBase.GetCollection<BsonDocument>(this.mCollectionName)
|
|
.Find(new BsonDocument())//.Find(filter)
|
|
.SortByDescending(x => x["sequenceIndex"])
|
|
.Project(projection)
|
|
.Limit(1)
|
|
.ToList();
|
|
|
|
|
|
if (documents.Count != 0)
|
|
{
|
|
mUpdatedBsonValue = documents.Last()["eventDocument"];
|
|
}
|
|
else
|
|
{
|
|
mUpdatedBsonValue = null;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
void exchangeTable()
|
|
{
|
|
try
|
|
{
|
|
Dictionary<int, BsonValue> bufHash = null;
|
|
|
|
switch (this.mRequestType)
|
|
{
|
|
case DBDefine.RequestDataType.BAN_AND_PICK:
|
|
DataManager.getInstance().밴픽데이터 = this.mUpdatedBsonValue;
|
|
break;
|
|
case DBDefine.RequestDataType.GAME_STATUS:
|
|
DataManager.getInstance().경기데이터 = this.mUpdatedBsonValue;
|
|
//DataManager.getInstance().경기시간 = this.mUpdatedBsonValue["gameTime"].ToInt32() / 1000;
|
|
//Console.WriteLine("gametime : " + this.mUpdatedBsonValue["gameTime"].ToInt32() / 1000);
|
|
break;
|
|
case DBDefine.RequestDataType.OBJECT_EVENT:
|
|
DataManager.getInstance().오브젝트데이터 = this.mUpdatedBsonValue;
|
|
break;
|
|
case DBDefine.RequestDataType.STRUCT_EVENT:
|
|
DataManager.getInstance().건물데이터 = this.mUpdatedBsonValue;
|
|
break;
|
|
case DBDefine.RequestDataType.DRAGON_RESPAWN:
|
|
DataManager.getInstance().드래곤리스폰 = this.mUpdatedBsonValue;
|
|
break;
|
|
case DBDefine.RequestDataType.STRUCT_GOLD_EVENT:
|
|
DataManager.getInstance().타워골드데이터 = this.mUpdatedBsonValue;
|
|
break;
|
|
//case DBDefine.RequestDataType.ATAKHAN_RESPAWN:
|
|
// DataManager.getInstance().아타칸리스폰 = this.mUpdatedBsonValue;
|
|
// break;
|
|
}
|
|
}
|
|
catch(Exception ex) { }
|
|
}
|
|
|
|
}
|
|
}
|