AgileEAS.NET SOA 中間件平臺是一款基於基於敏捷並行開發思想和Microsoft .Net構件(組件)開發技術而構建的一個快速開發應用平臺。用於幫助中小型軟件企業創建一條適合市場快速變化的開發團隊,以達到節省開發成本、縮短開發時間,快速適應市場變化的目的。git
AgileEAS.NET SOA中間件平臺提供了敏捷快速開發軟件工程的最佳實踐,經過提供大量的基礎支撐功能如IOC、ORM、SOA、分佈式體系及敏捷併發開發方法所支撐的插件開發體系,以及提供了大量的實體、數據模型設計生成工具、代碼生成工具,用於幫助中小軟件開發商快速成長。程序員
AgileEAS.NET平臺充分把握目前軟件行業快速發展的新趨勢,基於敏捷並行開發、快速適應市場這樣淳樸的軟件工程實踐,採用業界普遍使用的Microsoft .Net構件(組件)開發技術實踐了這種開發思想,幫助軟件企業實現「敏捷變化、快速適合」的目標,從而幫助軟件企業在激烈的市場競爭中贏得先機並得到更高的回報。github
在AgileEAS.NET SOA 中間件平臺在大量客戶的使用過程之中,有的客戶提出了一些基於「消息推」、和應用系統事件通知的需求,好比在「醫院信息系統」、「電子病歷系統‘、」區域公共衛平生臺「、等系統之中就提供了這樣的需求,好比當大夫爲病人開立了醫囑以後、須要在相關護理人員即時提示,以前你們都使用數據庫刷新,數據庫的壓力都比較大,因此迫切的提出了這樣的需求。數據庫
另一個緣由是AgileEAS.NET SOA 中間件平臺以前一直使用WCF、WS、Romotinig通訊作爲SOA分佈式架構的通訊基礎,咱們在考慮WS、WCF的某些協議並不能提供給咱們很是高效的通訊,因此咱們也須要有一套直接基於Socket/TCP的通訊體系用於支撐咱們的SOA分佈式服務業務體系。服務器
AgileEAS.NET SOA中間件須要的Socket/Tcp框架嚴格意思是須要的基於Socket的通訊消息中件間,其所提供的功能本質是對消息的處理,因此其所提供的API有三大類、Socket框架自己、消息框架及消息處理框架,如下是AgileEAS.NET SOA中間件的Socket/Tcp的應用框架結構:網絡
各上圖咱們能夠看到AgileEAS.NET SOA中間件須要的Socket/Tcp框架實現了這麼一件有意思的事,把原生的Socekt基於數據流的流式通訊模式轉換爲基於消息的消息通訊模式,讓開發人員多複雜的系統Socket通訊和數據流處理之中解放出來,轉而關心高層通訊消息的設計和消息處理的業務設計與實現。架構
AgileEAS.NET SOA中間件須要的Socket/Tcp框架嚴格意思是須要的基於Socket的通訊消息中件間,其所提供的功能本質是對消息的處理,因此其所提供的API有三大類、Socket框架自己、消息框架及消息處理框架,如下是AgileEAS.NET SOA中間件的Socket/Tcp的應用框架結構:併發
其中ISocketCient接口爲客戶段功能封裝,其定義大致以下:app
1: /// <summary>
2: /// Tcp客戶端接口。
3: /// </summary>
4: public interface ISocketClient : ISocketEngine
5: {
6: /// <summary>
7: /// 客戶端狀態。
8: /// </summary>
9: ClientState ClientState
10: {
11: get;
12: }
13:
14: /// <summary>
15: /// 鏈接Tcp服務器。
16: /// </summary>
17: bool Connect();
18:
19: /// <summary>
20: /// 關閉與服務器的鏈接。
21: /// </summary>
22: void Close();
23:
24: /// <summary>
25: /// 發送消息。
26: /// </summary>
27: /// <param name="message">消息。</param>
28: void Send(IMessage message);
29:
30: /// <summary>
31: /// 調用消息,用於服務器/客戶端應用中的請示==》響應消息的應用。
32: /// </summary>
33: /// <param name="request">請示消息。</param>
34: /// <returns>服務器返回的響應消息。</returns>
35: IMessage Invoke(IMessage request);
36:
37: /// <summary>
38: /// 異步調用消息,用於服務器/客戶端應用中的請示==》響應消息的應用。
39: /// </summary>
40: /// <param name="request">請示消息。</param>
41: /// <returns>包含響應消息的異步任務。</returns>
42: NetInvokeTask BeginInvoke(IMessage request);
43:
44: /// <summary>
45: /// 服務器發生錯誤時觸發。
46: /// </summary>
47: event ErrorEventHandler Error;
48:
49: /// <summary>
50: /// 鏈接服務器後觸發。
51: /// </summary>
52: event EventHandler Connected;
53:
54: /// <summary>
55: /// 斷開服務器鏈接後觸發。
56: /// </summary>
57: event EventHandler Closed;
58: }
其是最重要方法爲void Send(IMessage message)方法,即發送一個消息到服務器,這個方法也是對使用者開放的最重要方法,在這裏發送的不是字節流,而是一個實現了IMessage接口的消息對象,當服戶段接收到IMessage對象以後會調用與其對應的消息處理器(IMessageHandler)對象進行消息處理,反之客戶段收到IMessage也會調用與其相關的消息處理器(IMessageHandler)對象進行處理。框架
ISocketServer、ISocketServerBase接口:
1: /// <summary>
2: /// Socket服務器基類接口。
3: /// </summary>
4: public interface ISocketServerBase : ISocketEngine
5: {
6: /// <summary>
7: /// 客戶端會話集合。
8: /// </summary>
9: IList<NetSession> Sessions
10: {
11: get;
12: }
13:
14: /// <summary>
15: /// 註冊了一個新會話後發生。
16: /// </summary>
17: event NetSessionEventHandler SessionStarted;
18:
19: /// <summary>
20: /// 某一個會話結束後發生。
21: /// </summary>
22: event NetSessionEventHandler SessionAbandoned;
23:
24: /// <summary>
25: /// 發送消息。
26: /// </summary>
27: /// <param name="target">消息接收方ID(會話ID)。</param>
28: /// <param name="message">消息。</param>
29: void Send(Guid target, IMessage message);
30:
31: /// <summary>
32: /// 發送網絡消息。
33: /// </summary>
34: /// <param name="target">消息接收方ID(會話ID)。</param>
35: /// <param name="netMessage">網絡消息。</param>
36: void Send(Guid target, NetMessage netMessage);
37:
38: /// <summary>
39: /// 發送網絡報文(僅網關模式有效)。
40: /// </summary>
41: /// <param name="target">消息接收方ID(會話ID)。</param>
42: /// <param name="netPacket">網絡報文。</param>
43: void Send(Guid target, NetPacket netPacket);
44:
45: /// <summary>
46: /// 發送網絡數據(僅網關模式有效)。
47: /// </summary>
48: /// <param name="target">消息接收方ID(會話ID)。</param>
49: /// <param name="buffer">網絡數據。</param>
50: void Send(Guid target, byte[] buffer);
51: }
1: /// <summary>
2: /// Socket服務器接口。
3: /// </summary>
4: public interface ISocketServer : ISocketServerBase
5: {
6: /// <summary>
7: /// 客戶端鏈接數。
8: /// </summary>
9: int ClientCount
10: {
11: get;
12: }
13:
14: /// <summary>
15: /// 服務器狀態。
16: /// </summary>
17: ServerState ServerState
18: {
19: get;
20: }
21:
22: /// <summary>
23: /// 開始Tcp服務器。
24: /// </summary>
25: void StartServer();
26:
27: /// <summary>
28: /// 中止Tcp服務器。
29: /// </summary>
30: void StopServer();
31:
32: /// <summary>
33: /// 關閉指定客戶的鏈接。
34: /// </summary>
35: /// <param name="client">客戶Guid。</param>
36: void AbandonSession(System.Guid client);
37:
38: /// <summary>
39: /// 服務器發生錯誤時觸發。
40: /// </summary>
41: event ServerErrorEventHandler ServerError;
42:
43: /// <summary>
44: /// 服務器啓動後觸發。
45: /// </summary>
46: event System.EventHandler ServerStarted;
47:
48: /// <summary>
49: /// 服務器中止後觸發。
50: /// </summary>
51: event System.EventHandler ServerStopped;
52: }
這兩個接口定義了SocketServer的一些行爲和屬性,其中最重要的方法仍是void Send(Guid target, IMessage message),實現向某個特定客戶段鏈接發送應用消息,別外定義了一個IList<NetSession> Sessions屬性,表示目前鏈接到此SocketServer的全部客戶端會話信息。
NetSession表示服務器的一個客戶段鏈接會話,包括鏈接上下文信息和鏈接的Socket通訊對象,當某個SocketClient發送給SocketServer的信息都會被與其應對的NetSession進行處理,NetSession定義兩個重要的方法public void Reply(uint requestID, IMessage message)和public void Abandon(),其中Reply表示向客戶端回覆一個消息,Abandon表示服務器強制停止此會話。
在整個Socket/tcp框架之中進行通訊的最基本單元都是IMessage,那麼SocketClient、SocketServer接收到IMessage如何處理呢,答案是由與之配對的IMessageHandler進行處理,因此SocketClient、SocketServer都實現了一個基礎接口ISocketEngine:
1: /// <summary>
2: /// Socket引擎,Socket網絡通訊基礎類。
3: /// </summary>
4: public interface ISocketEngine : IDisposable
5: {
6: /// <summary>
7: /// 通訊引擎的全局惟一標識符號。
8: /// </summary>
9: System.Guid Guid
10: {
11: get;
12: }
13:
14: /// <summary>
15: /// IP地址和端口號。
16: /// </summary>
17: IPEndPoint IPEndPoint
18: {
19: get;
20: set;
21: }
22:
23: /// <summary>
24: /// IP地址。
25: /// </summary>
26: string IPAddress
27: {
28: get;
29: set;
30: }
31:
32: /// <summary>
33: /// 端口號。
34: /// </summary>
35: int Port
36: {
37: get;
38: set;
39: }
40:
41: /// <summary>
42: /// 報文最大長度。
43: /// </summary>
44: int MessageMaxSize
45: {
46: get;
47: }
48:
49: /// <summary>
50: /// 註冊消息處理器。
51: /// </summary>
52: /// <typeparam name="T">消息類型。</typeparam>
53: /// <param name="hander">消息處理器。</param>
54: void AddHander<T>(IMessageHandler<T> hander) where T : IMessage;
55:
56: /// <summary>
57: /// 經過Socket發送數據以後觸發。
58: /// </summary>
59: event SocketDataHandler SocketDataSend;
60:
61: /// <summary>
62: /// 經過Socket接收數據以後觸發。
63: /// </summary>
64: event SocketDataHandler SocketDataReceived;
65:
66: /// <summary>
67: /// 發送報文完成以後觸發。
68: /// </summary>
69: event PacketHandler PacketSend;
70:
71: /// <summary>
72: /// 報文接收完成以後觸發。
73: /// </summary>
74: event PacketHandler PacketReceived;
75:
76: /// <summary>
77: /// 載送完一個NetMessage以後觸發。
78: /// </summary>
79: event NetMessageHandler NetMessageSend;
80:
81: /// <summary>
82: /// 接收完一個NetMessage以後觸發。
83: /// </summary>
84: event NetMessageHandler NetMessageReceived;
85:
86: /// <summary>
87: /// 消息發送完成以後觸發。
88: /// </summary>
89: event MessageHandler MessageSend;
90:
91: /// <summary>
92: /// 接收消息完成以後觸發。
93: /// </summary>
94: event MessageHandler MessageReceived;
95: }
其中方法void AddHander<T>(IMessageHandler<T> hander) where T : IMessage實現對消息處理器的註冊,以便收到IMessage以後選擇合適的處理器進行處理。
從以上的介紹咱們能夠明確的知道AgileEAS.NET SOA中間件Socket/Tcp框架是的一個基於消息對象的消息通訊框架,那麼其最核心的業務就是定義消息及消息的處理思路,咱們稱之爲消息及消息處理器結構:
其中IMessage接口爲Socket/Tcp框架中最重要的接口,全部高層的應用消息都須要實現本接口:
1: /// <summary>
2: /// 消息接口定義。
3: /// </summary>
4: /// <remarks>
5: /// 這裏所說的消息是指業務處理的最小單元,而不是傳輸於網絡之間的網絡消息。
6: /// </remarks>
7: public interface IMessage
8: {
9: /// <summary>
10: /// 從指定的 MessageReader加載消息對象。
11: /// </summary>
12: /// <param name="reader">消息讀取器。</param>
13: void Load(BufferReader reader);
14:
15: /// <summary>
16: /// 將消息對象保存到指定的MessageWriter。
17: /// </summary>
18: /// <param name="writer">消息編寫器。</param>
19: void WriteTo(BufferWriter writer);
20: }
其中Load和WriteTo實現IMessage消息對象實例與字節流之間進行相互轉換,Load消息用於從字節流之中讀取並實例化消息、WriteTo把消息轉換爲流寫入消息流之中,在應用開發過程之中必須實現這兩個方法而且在消息類上打上MessageAttribute標記:
1: /// <summary>
2: /// 消息ID屬性。
3: /// </summary>
4: /// <remarks>
5: /// 標記網絡消息,肯定其惟一的ID。
6: /// </remarks>
7: [AttributeUsage(AttributeTargets.Class)]
8: public class MessageAttribute : Attribute
9: {
10: /// <summary>
11: /// 初始化MessageAttribute對象實例。
12: /// </summary>
13: /// <param name="messageID">消息ID。</param>
14: public MessageAttribute(string messageID)
15: :this(messageID,string.Empty)
16: {
17:
18: }
19:
20: /// <summary>
21: /// 初始化MessageAttribute對象實例。
22: /// </summary>
23: /// <param name="messageID">消息ID。</param>
24: /// <param name="description">消息說明。</param>
25: public MessageAttribute(string messageID, string description)
26: {
27: this.MessageID = new Guid(messageID);
28: this.Description = description;
29: }
30:
31: /// <summary>
32: /// 消息ID。
33: /// </summary>
34: public Guid MessageID
35: {
36: get;
37: set;
38: }
39:
40: /// <summary>
41: /// 消息說明。
42: /// </summary>
43: public string Description
44: {
45: get;
46: set;
47: }
48: }
MessageAttribute標記用於向已實現IMessage接口的具體消息的消息ID與消息說明,即向Socket通訊框架聲音本消息的惟一性之用,其中MessageID爲一個GUID對象,GUID對象理論上是惟一的,咱們能夠表示消息的惟一性,如下是一個具體的消息例子:
1: /// <summary>
2: /// 用戶登陸消息。
3: /// </summary>
4: [Message("F42433DF-2D4D-4514-9523-2FE911E63CAA", "登陸消息")]
5: [Serializable]
6: public class LoginMessage : IMessage
7: {
8: /// <summary>
9: /// 用戶名。
10: /// </summary>
11: public string LoginID
12: {
13: get;
14: set;
15: }
16:
17: /// <summary>
18: /// 密碼。
19: /// </summary>
20: public string PassWord
21: {
22: get;
23: set;
24: }
25:
26: #region IMessage 成員
27:
28: /// <summary>
29: ///
30: /// </summary>
31: /// <param name="reader"></param>
32: public void Load(EAS.IO.BufferReader reader)
33: {
34: LoginID = reader.ReadString();
35: PassWord = reader.ReadString();
36: }
37:
38: /// <summary>
39: ///
40: /// </summary>
41: /// <param name="writer"></param>
42: public void WriteTo(EAS.IO.BufferWriter writer)
43: {
44: writer.Write(LoginID);
45: writer.Write(PassWord);
46: }
47:
48: #endregion
49: }
以上是一個具體消息的例子,其代表消息ID爲「F42433DF-2D4D-4514-9523-2FE911E63CAA」,其做用是登陸消息,用於實現相似登陸業務。
AgileEAS.NET SOA中間件Socket/Tcp框架是一個可靠的消息中間件,在設計過程之初就選擇了完成端口模型進行開發,以保證服務的高併發和吞吐量,在底層消息通訊上,咱們選擇了不超過8K的可變大小通訊報文,好比當一個高層的IMeesage只有512字節內容的時候,會取轉成一個一個遠小於8K的報文進行發送,若是一個高層IMeesage爲66K時,會被分解成爲9條消息報文進行通訊,前8條消息報文長度爲8K,最後一條不知足8K,接收文收到這9條報文後組合並轉換爲IMeesage對象以後交由消息處理器IMeeesgaHandler進行處理。
在進行消息報文收發過程之中,通過長期測試、驗證、設計和選擇了高性能的防粘包設計,避免應用開發者頭疼的消息粘包問題。
AgileEAS.NET SOA中間件Socket/Tcp框架包含在AgileEAS.NET SOA中間件平臺之中,具體定義在EAS.MicroKernel.dll程序集之中,要使用AgileEAS.NET SOA中間件Socket/Tcp框架進行基於Socket的通訊開發,請經過AgilleEAS.NET SOA 中站件平臺官方網站的最新下載頁面下載。
爲了完善、改進和推廣AgileEAS.NET而成立了敏捷軟件工程實驗室,是一家研究、推廣和發展新技術,並致力於提供具備自主知識產權的業務基礎平臺軟件,以及基於業務基礎平臺了開發的管理軟件的專業軟件提供商。主要業務是爲客戶提供軟件企業研發管理解決方案、企業管理軟件開發,以及相關的技術支持,管理及技術諮詢與培訓業務。
AgileEAS.NET平臺自2004年秋呱呱落地一來,我就一直在逐步完善和改進,也被應用於保險、醫療、電子商務、房地產、鐵路、教育等多個應用,但一直都是以我我的在推廣,2010年由於我辭職休息,我就想到把AgileEAS.NET推向市場,讓更多的人使用。
個人技術團隊成員都是合做多年的老朋友,由於這個平臺是免費的,因此也沒有什麼收入,都是由程序員的那種理想與信念堅持,在此我感謝一塊兒奮鬥的朋友。
AgileEAS.NET網站:http://www.agileeas.net
官方博客:http://eastjade.cnblogs.com
github:https://github.com/agilelab/eas
QQ:47920381
AgileEAS.NET QQ羣:
113723486(AgileEAS SOA 平臺)/上限1000人
199463175(AgileEAS SOA 交流)/上限1000人
120661978(AgileEAS.NET 平臺交流)/上限1000人
212867943(AgileEAS.NET研究)/上限500人
147168308(AgileEAS.NET應用)/上限500人
172060626(深度AgileEAS.NET平臺)/上限500人
116773358(AgileEAS.NET 平臺)/上限500人
125643764(AgileEAS.NET探討)/上限500人
193486983(AgileEAS.NET 平臺)/上限500人
郵件:james@agilelab.cn,mail.james@qq.com,
電話:18629261335。