123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
-
- using CommonLang;
- using System;
- using System.IO;
- using System.Collections.Generic;
- using CommonAI.Zone.ZoneEditor;
- using CommonLang.Log;
- using CommonAI.Zone.Attributes;
- using CommonAI;
- using CommonAI.ZoneClient;
- using System.Threading;
- namespace Pomelo.DotNetClient.NetClient
- {
- public interface INetClient
- {
- EditorTemplates DataRoot { get; }
- void SendBattleMessage(CommonAI.Zone.Action action);
- }
- public abstract class BaseNetClient<GATE, GAME, BATTLE> : IDisposable, INetClient
- where GATE : PomeloClient
- where GAME : PomeloClient
- where BATTLE : BaseBattleClient
- {
- public GATE GateSocket { get; private set; }
- public GAME GameSocket { get; private set; }
- public BATTLE BattleClient { get; protected set; }
- public CommonAI.ZoneClient.ZoneActor BattleActor { get { if (BattleClient != null) { return BattleClient.Actor; } return null; } }
- public abstract EditorTemplates DataRoot { get; }
- protected readonly Logger log;
- protected readonly List<object> mUnhandledList = new List<object>();
- protected BATTLE NextBattleClient;
- protected SynchronizedBattleCodec mBattleCodec;
- //协同类任务列表//
- private readonly SyncMessageQueue<Action> mTasks = new SyncMessageQueue<Action>();
- public BaseNetClient(GATE gate, GAME game)
- {
- this.log = LoggerFactory.GetLogger(GetType().Name);
- this.GateSocket = gate;
- this.GameSocket = game;
- this.GameSocket.NetWorkHandlePushImmediately += notify_OnBattleMessageReceivedImmediately;
- //this.QueueTask(InitCodec);
- InitCodec();
- }
- public void InitCodec()
- {
- if (this.DataRoot != null && this.DataRoot.Templates != null)
- {
- this.mBattleCodec = new SynchronizedBattleCodec(this.DataRoot.Templates);
- }
- }
- //-------------------------------------------------------------------------------------------------
- #region _主动调用_
- /// <summary>
- /// 提交一个任务让主线程处理,协同程序
- /// </summary>
- /// <param name="action"></param>
- public void QueueTask(Action action)
- {
- mTasks.Enqueue(action);
- }
- public void UpdateSocket(float delTime)
- {
- mTasks.ProcessMessages((act) => { act.Invoke(); });
- this.GateSocket.update(delTime);
- this.GameSocket.update(delTime);
- }
- public void DoUpdateSend()
- {
- this.GateSocket.DoSendUpdate();
- this.GameSocket.DoSendUpdate();
- }
- public void UpdateBattleClient(int intervalMS)
- {
- if (BattleClient != null)
- {
- BattleClient.BeginUpdate(intervalMS);
- BattleClient.Update();
- }
- }
- public void CreateNextBattleClient()
- {
- this.NextBattleClient = CreateBattle();
- }
- public void Disconnect()
- {
- log.Debug("====socket ==BaseNetClient== Disconnect");
- try
- {
- ClearBattle();
- }
- catch (Exception err)
- {
- log.Error(err.Message, err);
- }
- if (this.GateSocket.IsConnected)
- {
- try
- {
- this.GateSocket.disconnect();
- }
- catch (Exception err)
- {
- log.Error(err.Message, err);
- }
- }
- if (this.GameSocket.IsConnected)
- {
- try
- {
- this.GameSocket.disconnect();
- }
- catch (Exception err)
- {
- log.Error(err.Message, err);
- }
- }
- }
- public void Dispose()
- {
- this.mOnBeginEnterScene = null;
- this.mOnEnterScene = null;
- this.mOnLeaveScene = null;
- this.mOnBattlePlayerReady = null;
- this.Disconnect();
- try
- {
- this.GateSocket.Dispose();
- }
- catch (Exception err)
- {
- log.Error(err.Message, err);
- }
- try
- {
- this.GameSocket.Dispose();
- }
- catch (Exception err)
- {
- log.Error(err.Message, err);
- }
- }
- #endregion
- //-------------------------------------------------------------------------------------------------
- #region _Events_
- private Action<BATTLE> mOnBeginEnterScene;
- private Action<BATTLE> mOnEnterScene;
- private Action<BATTLE> mOnLeaveScene;
- private Action<CommonAI.ZoneClient.ZoneLayer, CommonAI.ZoneClient.ZoneActor> mOnBattlePlayerReady;
- [EventTriggerDescAttribute("BattleClient已创建,一般用于开始加载场景操作,场景加载完毕,调用GameSocket.Invoke_ChangeScene")]
- public event Action<BATTLE> OnBeginEnterScene { add { mOnBeginEnterScene += value; } remove { mOnBeginEnterScene -= value; } }
- [EventTriggerDescAttribute("当单位已经进入场景时触发【角色已经进入战斗服】")]
- public event Action<BATTLE> OnEnterScene { add { mOnEnterScene += value; } remove { mOnEnterScene -= value; } }
- [EventTriggerDescAttribute("当单离开场景时触发【收到PlayerLeaveScene】")]
- public event Action<BATTLE> OnLeaveScene { add { mOnLeaveScene += value; } remove { mOnLeaveScene -= value; } }
- [EventTriggerDescAttribute("玩家单位已准备完毕【确保战斗服和游戏服可操作】")]
- public event Action<CommonAI.ZoneClient.ZoneLayer, CommonAI.ZoneClient.ZoneActor> OnBattlePlayerReady { add { mOnBattlePlayerReady += value; } remove { mOnBattlePlayerReady -= value; } }
- #endregion
- //-------------------------------------------------------------------------------------------------
- #region _Request Http_
- /// <summary>
- /// HTTP同步请求.
- /// </summary>
- /// <param name="url"></param>
- /// <param name="args"></param>
- /// <returns></returns>
- public string RequestHttpPost(string url, Dictionary<string, string> args)
- {
- string requestUrl = url + '?';
- foreach (KeyValuePair<string, string> arg in args)
- {
- requestUrl += arg.Key + '=' + arg.Value + '&';
- }
- requestUrl = requestUrl.Remove(requestUrl.Length - 1);
- System.Uri uri = new System.Uri(requestUrl);
- string result = CommonNetwork.Http.WebClient.Post(uri);
- return result;
- }
- /// <summary>
- /// HTTP异步请求.
- /// </summary>
- /// <param name="url"></param>
- /// <param name="args"></param>
- /// <param name="handler"></param>
- public void RequestHttpPostAsync(string url, Dictionary<string, string> args, CommonNetwork.Http.HttpPostHandler handler)
- {
- string requestUrl = url + '?';
- foreach (KeyValuePair<string, string> arg in args)
- {
- requestUrl += arg.Key + '=' + arg.Value + '&';
- }
- requestUrl = requestUrl.Remove(requestUrl.Length - 1);
- System.Uri uri = new System.Uri(requestUrl);
- CommonNetwork.Http.WebClient.PostAsync(uri, System.Text.Encoding.UTF8, (string result) =>
- {
- if (handler != null)
- {
- QueueTask(() =>
- {
- handler.Invoke(result);
- });
- }
- });
- }
- #endregion
- //-------------------------------------------------------------------------------------------------
- #region _BattleClient_
- public abstract BATTLE CreateBattle();
-
- public virtual void ClearBattle()
- {
- if (this.NextBattleClient != null)
- {
- this.NextBattleClient.Dispose();
- this.NextBattleClient = null;
- }
- mUnhandledList.Clear();
- }
- public abstract void SendBattleMessage(CommonAI.Zone.Action action);
- /// <summary>
- /// ChangeAreaPush 或 BindPlayer 后回调
- /// 进入战斗场景开始.
- /// </summary>
- public void BattleClientInitBegin()
- {
- if (this.BattleClient != null)
- {
- this.BattleClient.Dispose();
- this.BattleClient = null;
- }
- if (NextBattleClient == null)
- {
- BattleClient = this.CreateBattle();
- }
- else
- {
- BattleClient = NextBattleClient;
- }
- NextBattleClient = null;
- if (mUnhandledList.Count > 0)
- {
- foreach (var msg in mUnhandledList)
- {
- this.BattleClient.OnReceivedBattleMessage(msg as CommonLang.Protocol.IMessage);
- }
- mUnhandledList.Clear();
- }
- if (mOnBeginEnterScene != null)
- {
- mOnBeginEnterScene.Invoke(BattleClient);
- }
- }
- /// <summary>
- /// Request_EnterScene 回调
- /// 进入战斗场景完成.(客户端加载完成)
- /// </summary>
- public void BattleClientInitFinish()
- {
- if (BattleClient != null)
- {
- if (mOnEnterScene != null)
- {
- mOnEnterScene.Invoke(BattleClient);
- }
- BattleClient.QueueTask(BattlePlayerReady);
- }
- }
- private void BattlePlayerReady(CommonAIClient.Client.AbstractBattle battle)
- {
- if (!battle.Layer.IsDesposed)
- {
- if (battle.Actor != null)
- {
- if (mOnBattlePlayerReady != null)
- {
- mOnBattlePlayerReady.Invoke(battle.Layer, battle.Actor);
- }
- }
- else
- {
- BattleClient.QueueTask(BattlePlayerReady);
- }
- }
- }
- /// <summary>
- /// 战斗协议回调.(直接从网络线程回调)
- /// </summary>
- /// <param name="msg"></param>
- protected virtual bool notify_OnBattleMessageReceivedImmediately(string route, Stream msg)
- {
- //log.Debug("socket ===== notify_OnBattleMessageReceivedImmediately ThreadID: " + Thread.CurrentThread.ManagedThreadId);
- if (route == "area.playerPush.battleClearPush")
- {
- this.NextBattleClient = this.CreateBattle();
- if (mOnLeaveScene != null) { mOnLeaveScene.Invoke(BattleClient); }
- return true;
- }
- else if (route == "area.playerPush.battleEventPush")
- {
- object data;
- try
- {
- if (mBattleCodec == null)
- {
- log.Error("decode err: mBattleCodec is null");
- return false;
- }
- if (msg == null)
- {
- log.Error("decode err: msg is null!");
- return false;
- }
- if (mBattleCodec.doDecode(msg, out data))
- {
- if (data is PlayerLeaveScene)
- {
- //this.NextBattleClient = this.CreateBattle();
- //this.QueueTask(() => { if (mOnLeaveScene != null) { mOnLeaveScene.Invoke(BattleClient); } });
- }
- else
- {
- if (NextBattleClient != null || this.BattleClient == null)
- {
- mUnhandledList.Add(data);
- }
- else
- {
- this.BattleClient.OnReceivedBattleMessage(data as CommonLang.Protocol.IMessage);
- }
- }
- }
- else
- {
- log.Error("[doDecodeBin] error:" + msg.ToString());
- }
- }
- catch (Exception err)
- {
- log.Error("[doDecodeBin] error:" + err.Message, err);
- }
- return true;
- }
- return false;
- }
- #endregion
- }
- }
|