Net.Sz.CFramework 是我本身的底層庫,是通過驗證的底層庫。html
socket tcp協議,
socket http協議線程池,
線程模型,
任務模型,
定時器模型,
日誌模塊
腳本模塊
一些輔助類
這裏是華麗麗的分割線java
1 // 摘要: 2 // 獲取當前時間和 1970-01-01 00:00:00 的時間差 3 // 爲了和java一導致用的是 UTC 時間 4 public static long CurrentTimeMillis(); 5 // 6 // 摘要: 7 // 獲取當前時間所表示的毫秒數 8 public static long CurrentTimeMillis(DateTime dt); 9 public static long CurrentTimeMillis_Java(); 10 // 11 // 摘要: 12 // 獲取當前時間所表示的毫秒數 13 public static long CurrentTimeMillis_Java(DateTime dt); 14 // 15 // 摘要: 16 // 將毫秒數轉化成當前時間 17 public static DateTime DateNow(long milliseconds); 18 public static DateTime DateNow_Java(long milliseconds); 19 // 20 // 摘要: 21 // yyyy-MM-dd HH:mm:ss:fff: 22 // 23 // 參數: 24 // d: 25 public static string NowString(DateTime d);
後面java函數是輸出和java一直的時間函數
1 // 2 // 摘要: 3 // 驗證活動是否結束 驗證時間:[*][*][20/22][*][10:00-11:59/16:00-17:59] 4 // 第一個是年,,第二個是月,第三個是日期,第四個是星期,第五個是時間, 5 // 每個參數,"-" 表示 到 如:「2015-2017」表示 2015 到 2017, "/" 表示 或者 如: 「2015/2017」表示2015 6 // 或者 2017 7 public static bool VerifyConfigEndTimeStr(DateTime date, string timeStr); 8 9 // 10 // 摘要: 11 // 獲取活動結束時間倒計時 驗證時間:[*][*][20/22][*][10:00-11:59/16:00-17:59] 12 // 第一個是年,,第二個是月,第三個是日期,第四個是星期,第五個是時間, 13 // 每個參數,"-" 表示 到 如:「2015-2017」表示 2015 到 2017, "/" 表示 或者 如: 「2015/2017」表示2015 14 // 或者 2017 15 // 返回值 -1 表示永久過時,0 表示在時間規則內,大於 0 表示倒計時 16 public static long VerifyDateEndTime(string timeStr); 17 18 // 19 // 摘要: 20 // 獲取開始倒計時 驗證時間:[*][*][20/22][*][10:00-11:59/16:00-17:59] 21 // 第一個是年,,第二個是月,第三個是日期,第四個是星期,第五個是時間, 22 // 每個參數,"-" 表示 到 如:「2015-2017」表示 2015 到 2017, "/" 表示 或者 如: 「2015/2017」表示2015 23 // 或者 2017 24 // 返回值 -1 表示永久過時,0 表示在時間規則內,大於 0 表示倒計時 25 public static long VerifyDateTime(string timeStr);
時間匹配函數,看到這裏後,請不要給我提quartz 由於我只會回答你不一樣的需求,不一樣的環境會有不一樣的使用狀況
位運算輔助函數程序員
1 Net.Sz.CFramework.Struct.EnumStatus status2 = new Net.Sz.CFramework.Struct.EnumStatus(1 << 1, 1 << 0);
使用方式和詳解請看 狀態機數組
本日誌組建支持大約輸出日誌信息的文件名函數名和行號
方法是異步處理的支持寫入文件,文件寫入格式是天天一個文件。
1 //是否顯示控制檯打印 2 Net.Sz.CFramework.Log.Logger.LOGCONSOLE = true; 3 //只支持三種格式。控制檯輸出,info級別和error級別 4 Net.Sz.CFramework.Log.Logger.LOGLEVEL = Net.Sz.CFramework.Log.ENUM_LOGLEVEL.DEBUG; 5 6 Net.Sz.CFramework.Log.Logger.Debug("{0}->{1}", 55, "test"); 7 Net.Sz.CFramework.Log.Logger.Info("{0}->{1}", 55, "test"); 8 Net.Sz.CFramework.Log.Logger.Error("{0}->{1}", 55, "test"); 9 10 //只顯示info 11 Net.Sz.CFramework.Log.Logger.LOGLEVEL = Net.Sz.CFramework.Log.ENUM_LOGLEVEL.INFO; 12 13 Net.Sz.CFramework.Log.Logger.Debug("{0}->{1}", 55, "test"); 14 Net.Sz.CFramework.Log.Logger.Info("{0}->{1}", 55, "test"); 15 Net.Sz.CFramework.Log.Logger.Error("{0}->{1}", 55, "test");
大約信息以下緩存
[2016-03-30 15:03:13:9706: Debug:CApp1.Program, Main, 26] 55->test [2016-03-30 15:03:14:0496: Info :CApp1.Program, Main, 27] 55->test [2016-03-30 15:03:14:0536: Error:CApp1.Program, Main, 30] 55->test [2016-03-30 15:03:14:0536: Info :CApp1.Program, Main, 34] 55->test [2016-03-30 15:03:14:0536: Error:CApp1.Program, Main, 36] 55->test
這裏包含了線程模型,任務模型和定時器任務模型
1 //是以一個線程執行任務的線程模型 2 long t1 = Net.Sz.CFramework.Threading.ThreadPool.GetThreadModel("test", 1); 3 4 //是以十個線程執行任務的線程模型 5 long t10 = Net.Sz.CFramework.Threading.ThreadPool.GetThreadModel("test", 10); 6 7 //建立一個簡單任務 8 Net.Sz.CFramework.Threading.ThreadPool.AddTask(t1, new Net.Sz.CFramework.Threading.TaskModel_Action(() => 9 { 10 Net.Sz.CFramework.Log.Logger.Debug("TaskModel_Action 簡單任務"); 11 12 })); 13 14 //建立一個簡單的定時器任務,建立一個執行3次,每一個2秒執行一次的任務 15 Net.Sz.CFramework.Threading.ThreadPool.AddTimerTask(t1, new Net.Sz.CFramework.Threading.TimerTask_Action(3, 2000, () => 16 { 17 Net.Sz.CFramework.Log.Logger.Debug("TimerTask_Action 簡單任務"); 18 19 }));
輸出服務器
1 [2016-03-30 15:16:43:2129: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < 全局線程線程 > 2 [2016-03-30 15:16:43:3249: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread線程_1 > 3 [2016-03-30 15:16:43:3299: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread線程_2 > 4 [2016-03-30 15:16:43:3439: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] Back Thread 接手定時器任務 Net.Sz.CFramework.Threading.Timer.GlobTimerEvent 5 [2016-03-30 15:16:43:3589: Info :Net.Sz.CFramework.Threading.TimerThread, .ctor, 47] 初始化 < timer 線程 > 6 [2016-03-30 15:16:43:3719: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < test線程 > 7 [2016-03-30 15:16:43:3849: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test線程_1 > 8 [2016-03-30 15:16:43:3899: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test線程_2 > 9 [2016-03-30 15:16:43:4059: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test線程_3 > 10 [2016-03-30 15:16:43:4099: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test線程_4 > 11 [2016-03-30 15:16:43:4159: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test線程_5 > 12 [2016-03-30 15:16:43:4249: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test線程_6 > 13 [2016-03-30 15:16:43:4359: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test線程_7 > 14 [2016-03-30 15:16:43:4399: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test線程_8 > 15 [2016-03-30 15:16:43:4469: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test線程_9 > 16 [2016-03-30 15:16:43:4559: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test線程_10 > 17 [2016-03-30 15:16:43:4649: Debug:CApp1.Program, <Main>b__0, 23] TaskModel_Action 簡單任務 18 [2016-03-30 15:16:43:4659: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] test 接手定時器任務 Net.Sz.CFramework.Threading.TimerTask_Action 19 [2016-03-30 15:16:43:4729: Debug:CApp1.Program, <Main>b__1, 30] TimerTask_Action 簡單任務 20 [2016-03-30 15:16:45:4820: Debug:CApp1.Program, <Main>b__1, 30] TimerTask_Action 簡單任務 21 [2016-03-30 15:16:47:4921: Debug:CApp1.Program, <Main>b__1, 30] TimerTask_Action 簡單任務
tcp監聽須要實現IIOSessionHandler接口session
1 // 摘要: 2 // http監聽處理 3 // @author 失足程序員 4 // @Blog http://www.cnblogs.com/ty408/ 5 // @mail 492794628@qq.com 6 // @phone 13882122019 7 public interface IIOSessionHandler 8 { 9 // 摘要: 10 // 新建連接 11 // 12 // 參數: 13 // session: 14 void channelActive(IOSession session); 15 // 16 // 摘要: 17 // 連接閒置狀態 18 // 19 // 參數: 20 // session: 21 void channelInactive(IOSession session); 22 // 23 // 摘要: 24 // 有消息,請注意消息是多線程處理的。也許你前一個消息沒有處理完成,後一個消息已經來了 25 // 26 // 參數: 27 // session: 28 // 29 // buffer: 30 void channelRead(IOSession session, byte[] buffer); 31 // 32 // 摘要: 33 // 連接斷開 34 // 35 // 參數: 36 // session: 37 void channelUnregistered(IOSession session, params string[] obj); 38 // 39 // 摘要: 40 // 連接發送異常 41 // 42 // 參數: 43 // session: 44 // 45 // ex: 46 void exceptionCaught(IOSession session, Exception ex); 47 }
1 //客戶端和服務器都須要這個處理接口實現 2 Net.Sz.CFramework.Netty.NettyPool.SessionHandler = new MySessionHandler(); 3 //建立對ip127.0.0.1端口9527的tcp監聽,使用一個線程處理這個監聽的io信息 4 Net.Sz.CFramework.Netty.NettyPool.AddTcpBind("127.0.0.1", 9527, 1); 5 //建立對服務器鏈接 6 Net.Sz.CFramework.Netty.Tcp.NettyClient client = new Net.Sz.CFramework.Netty.Tcp.NettyClient("127.0.0.1", 9527); 7 client.Connect();
須要特別注意public void channelRead(Net.Sz.CFramework.Netty.IOSession session, byte[] buffer)
這個函數收到的消息的字節數組是一個完整的獨立包
1 #pragma once 2 #include "stdafx.h" 3 #include "BufferReader.h" 4 #include "BufferWriter.h" 5 6 7 using namespace System; 8 9 namespace Net{ 10 namespace Sz{ 11 namespace CFramework{ 12 namespace Netty{ 13 namespace Buffer{ 14 15 using namespace System::IO; 16 using namespace System::Collections::Generic; 17 18 /// <summary> 19 /// 字節流書寫器 20 /// <para>@author 失足程序員</para> 21 /// <para>@Blog http://www.cnblogs.com/ty408/</para> 22 /// <para>@mail 492794628@qq.com</para> 23 /// <para>@phone 13882122019</para> 24 /// </summary> 25 ref class DefaultMarshalEndian 26 { 27 //用於存儲剩餘未解析的字節數 28 private: 29 List<Byte>^ _LBuff = gcnew List<Byte>(2); 30 31 //字節數常量一個消息id4個字節 32 const long ConstLenght = 8L; 33 const short ConstStart1 = 0xaa; 34 const short ConstStart2 = 0xbb; 35 36 public: 37 List<array<Byte>^>^ Decoder(array<Byte>^ buff) 38 { 39 if (this->_LBuff->Count > 0) 40 { 41 //拷貝以前遺留的字節 42 this->_LBuff->AddRange(buff); 43 buff = this->_LBuff->ToArray(); 44 this->_LBuff = gcnew List<Byte>(2); 45 } 46 List<array<Byte>^>^ list = gcnew List<array<Byte>^>(); 47 48 BufferReader^ buffers = gcnew BufferReader(buff); 49 50 try 51 { 52 array<Byte>^ _buff; 53 Label_0073: 54 55 //判斷本次解析的字節是否知足常量字節數 56 if ((buffers->BaseStream->Length - buffers->BaseStream->Position) < ConstLenght) 57 { 58 _buff = buffers->ReadBytes((int)(buffers->BaseStream->Length - buffers->BaseStream->Position)); 59 this->_LBuff->AddRange(_buff); 60 } 61 else 62 { 63 short tmpStart1 = buffers->ReadInt16(); 64 if (ConstStart1 == tmpStart1)//自定義頭相同 65 { 66 short tmpStart2 = buffers->ReadInt16(); 67 if (ConstStart2 == tmpStart2)//自定義頭相同 68 { 69 long offset = buffers->ReadInt32(); 70 //剩餘字節數大於本次須要讀取的字節數 71 if (offset <= (buffers->BaseStream->Length - buffers->BaseStream->Position)) 72 { 73 _buff = buffers->ReadBytes((int)(offset)); 74 list->Add(_buff); 75 goto Label_0073; 76 } 77 else 78 { 79 //剩餘字節數恰好小於本次讀取的字節數 存起來,等待接受剩餘字節數一塊兒解析 80 buffers->BaseStream->Seek(ConstLenght, System::IO::SeekOrigin::Current); 81 _buff = buffers->ReadBytes((int)(buffers->BaseStream->Length - buffers->BaseStream->Position)); 82 this->_LBuff->AddRange(_buff); 83 } 84 } 85 else 86 { 87 //往前推三個字節 88 buffers->BaseStream->Seek(-3, System::IO::SeekOrigin::Current); 89 goto Label_0073; 90 } 91 } 92 else 93 { 94 //往前推一個字節 95 buffers->BaseStream->Seek(-1, System::IO::SeekOrigin::Current); 96 goto Label_0073; 97 } 98 } 99 } 100 catch (Exception^){} 101 finally 102 { 103 buffers->Close(); 104 delete buffers; 105 } 106 return list; 107 } 108 109 void Encoder(array<Byte>^ msgBuffer, BufferWriter^ %outBuf) 110 { 111 outBuf->Write(ConstStart1); 112 outBuf->Write(ConstStart2); 113 if (msgBuffer != nullptr) 114 { 115 outBuf->Write((Int32)(msgBuffer->Length)); 116 outBuf->Write(msgBuffer); 117 } 118 else 119 { 120 outBuf->Write((Int32)0); 121 } 122 } 123 124 }; 125 } 126 } 127 } 128 } 129 }
解碼和編碼器多線程
1 [2016-03-30 15:28:55:5178: Info :Net.Sz.CFramework.Netty.Tcp.NettyServer, .ctor, 61] Start Listen Tcp Socket -> 127.0.0.1:9527 2 [2016-03-30 15:28:55:6028: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < 全局線程線程 > 3 [2016-03-30 15:28:55:6258: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread線程_1 > 4 [2016-03-30 15:28:55:6318: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread線程_2 > 5 [2016-03-30 15:28:55:6458: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] Back Thread 接手定時器任務 Net.Sz.CFramework.Threading.Timer.GlobTimerEvent 6 [2016-03-30 15:28:55:6648: Info :Net.Sz.CFramework.Threading.TimerThread, .ctor, 47] 初始化 < timer 線程 > 7 [2016-03-30 15:28:55:6798: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < Netty Session Pool Thread:127.0.0.1:9527線程 > 8 [2016-03-30 15:28:55:7078: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < Netty Session Pool Thread線程 > 9 [2016-03-30 15:28:55:7098: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] Netty Session Pool Thread 接手定時器任務 Net.Sz.CFramework.Netty.CheckIOSessionTimerTask 10 [2016-03-30 15:28:55:7188: Debug:Net.Sz.CFramework.Netty.Tcp.NettyClient, Connect, 48] Try Connect Tcp Socket Remote:127.0.0.1:9527 11 [2016-03-30 15:28:55:7388: Debug:Net.Sz.CFramework.Netty.Tcp.NettyClient, Connect, 51] Connect Tcp Socket Remote Socket RemoteEndPoint:127.0.0.1:9527 LocalEndPoint:127.0.0.1:17669 12 [2016-03-30 15:28:55:7468: Info :Net.Sz.CFramework.Netty.Tcp.NettyServer, AcceptAsync_Async, 43] Create Tcp Socket Remote Socket LocalEndPoint:127.0.0.1:9527 RemoteEndPoint:127.0.0.1:17669
須要實現併發
1 // 摘要: 2 // http監聽處理 3 // @author 失足程序員 4 // @Blog http://www.cnblogs.com/ty408/ 5 // @mail 492794628@qq.com 6 // @phone 13882122019 7 public interface IHttpHandler : IBaseScript 8 { 9 // 摘要: 10 // 併發處理的 11 // 12 // 參數: 13 // session: 14 // 鏈接對象 15 void Action(HttpSession session); 16 }
1 class Program 2 { 3 4 static void Main(string[] args) 5 { 6 //建立login目錄的監聽,處理程序是LoginHttpHandler,單線程處理請求 7 Net.Sz.CFramework.Netty.NettyPool.AddHttpBind("127.0.0.1", 9527, "login", new LoginHttpHandler(), 1); 8 Console.ReadLine(); 9 } 10 } 11 class LoginHttpHandler : Net.Sz.CFramework.Netty.Http.IHttpHandler 12 { 13 public void Action(Net.Sz.CFramework.Netty.Http.HttpSession session) 14 { 15 session.WriteSuccess(); 16 session.AddBody("Login OK"); 17 session.WriteFlush(); 18 } 19 }
使用腳步功能,C#的文件類,*.cs文件類
若是是實現IBaseScript能夠放到腳步管理器裏面進行查找
若是實現IInitBaseScript接口執行初始化函數;若是沒有隻實現IInitBaseScript不會放到腳步管理,
// 摘要: // 腳本基類 // @author 失足程序員 // @Blog http://www.cnblogs.com/ty408/ // @mail 492794628@qq.com // @phone 13882122019 public interface IBaseScript // 摘要: // 腳本基類 // 執行init初始化信息 // PS:實現這個接口不會放到腳步緩存集合中,若是須要請實現 IBaseScript // @author 失足程序員 // @Blog http://www.cnblogs.com/ty408/ // @mail 492794628@qq.com // @phone 13882122019 public interface IInitBaseScript { // 摘要: // 卸載腳本 void InitScript(); }
//傳入文件路徑,能夠是相對路徑也能夠是絕對路徑,後面能夠傳入須要引入的dll文件或者exe文件用於編譯和加載 ScriptManager.LoadCSharpFile(new String[] { "" }, "");
這裏以個人遊戲程序距離異步
public static List<string> LoadScript() { return ScriptManager.LoadCSharpFile(new string[] { "../../../../Net.Sz.Game.MMOGame.GameServer.Scripts/Src" }, "protobuf-net.dll", "EntityFramework.dll", "MySql.Data.dll", "Net.Sz.Framework.DB.dll", "MySql.Data.Entity.EF6.dll", "Net.Sz.Game.MMOGame.GameMessages.dll", "Net.Sz.Game.MMOGame.GameModel.dll" ); } public static Net.Sz.CFramework.Script.ScriptPool ScriptManager { get; private set; } /// <summary> /// /// </summary> public static void Start() { Net.Sz.CFramework.Struct.SzExtensions.Console_Show("Server", false, true); try { LoadScript(); } catch (Exception) { throw; } }
這是個人底層庫支持。望各位大仙多多指教!
對應提供下載.
java 版本的源碼下載