三10、【C#.Net開發框架】WCFHosting服務主機的利用WCF服務通信和實現思路

 回《【開源】EFW框架系列文章索引》       html

 EFW框架源代碼下載V1.3:http://pan.baidu.com/s/1c0dADO0算法

 EFW框架實例源代碼下載:http://pan.baidu.com/s/1eQCc69G數據庫

 

       前言:之前的系統都是直接客戶端直連數據庫服務器,後來考慮到服務器的安全性、數據庫鏈接數的限制、分佈能力差等問題,特別是那幾年中間件、SOA、ESB等炒得比較火,爲了跟上時代腳本有必要開發一箇中間件,把後臺邏輯業務在中間件中運行。剛開始考慮過WebServices,可是須要部署在IIS中,還有性能問題都比較嚴重,試了一下效果不是很好,後來以爲WCF不錯,但一直沒有找到好的方式怎麼與現有的架構結合,若是把業務代碼全改寫成WCF服務方式提供給客戶端調用,感受工做量很大,光看着WCF那些配置文件就頭大,特別是破壞了現有程序架構,這樣使用WCF對現有框架也沒什麼意義。後來在完善Web版框架中從HttpHandlers中找到了思路,發現沒有必要把業務功能作成WCF服務,而WCF服務只是用來實現客戶端與後臺業務的通信,這樣中間件只須要一個WCF服務用來鏈接客戶端控制器與服務端控制器,把Winform版控制器層也分拆成wcfclientController與wcfController。這樣原來的程序結構基本沒變,保證了Web版、Winform版、WCF版三種類型系統的程序架構,編碼風格等都一致,讓EFW框架全面支持多種系統開發;api

 

本文要點:緩存

1.WCFHosting服務主機介紹安全

2.WCFHosting服務主機實現服務器

3.WCFHosting服務主機必須解決的兩個問題網絡

4.總結架構

 

1.WCFHosting服務主機介紹

       WCFHosting程序只是一個WCF自託管宿主,固然你能夠修改此程序讓WCF服務託管在IIS或Windows Services中,WCFHosting程序只有三個核心功能:WCFHandlerService服務用來實現客戶端與服務端通信,RemoteLoader用來實現訪問對應的服務端控制器程序,Router服務用來實現中間件的鏈接路由和負載均衡。負載均衡

 

 

源代碼項目解決方案目錄:

WCFHosting程序界面

 

配置文件說明,包括客戶端的App.Config和服務端的App.Config兩個配置文件

1)客戶端的App.Config

主要是ClientType參數和WCF_endpoint參數的設置,ClientType必須設置爲WCFClient,WCF_endpoint設置爲WCF地址;

 

2)服務端的App.Config

 

2.WCFHosting服務主機實現

1)FrmHosting.cs界面,啓動、中止WCF服務

       啓動的時候能夠根據設置裏的配置開啓相應功能,好比:

顯示調試信息,那麼每一個客戶端每次與服務端交互的內容都會在日誌界面顯示出來

開啓WCF服務,若是此主機是做爲系統的中間件那麼必須勾上此處

開啓路由服務,若是此主機設置爲路由器那麼必須勾上此處

開啓心跳檢測,正式使用的系統必須勾上次處,若是是開發階段的時候能夠不勾,便於調試程序

2)WCFHandlerService服務,客戶端經過調用此wcf服務鏈接、執行、斷開與中間件通信

       WCFHandlerService服務的IapiWCFHandlerService契約使用了CallbackContract回調操做,這樣實現了客戶端與服務端之間雙向通信,服務端能夠主動向客戶端發送數據,這是Web程序沒有的功能,Web程序只能經過定時訪問來實現此功能。

WCFHandlerService服務對象有5個核心方法,

CreateDomain:打開客戶端(EFWWin.exe程序)會調用此方法在服務端建立在線用戶

ProcessRequest:客戶端調用此方法訪問服務端控制器代碼

UnDomain:客戶端(EFWWin.exe程序)退出前調用此方法清除服務端在線用戶

Heartbeat:客戶端像心跳同樣,調用此方法定時向服務端發送在線狀態

SendBroadcast:服務端向客戶端發送消息

3)Loader對象,管理每一個鏈接的客戶端,並經過反射調用wcf控制器

4)BaseWCFClientController客戶端控制器基類

5)BaseWCFController服務端控制器基類

6)JsonWCFController客戶端與服務端數據交換基於Json字符串格式

7)Router服務,中間件路由功能及負載均衡實現

3.WCFHosting服務主機必須解決的兩個問題

問題一:因爲網絡中斷問題等問題引發通信錯誤,再恢復以後必須能夠繼續使用,不須要關閉系統從新登陸系統;再就是wcf服務器主機必須反饋此客戶機是斷開狀態;

問題二:因爲WCF主機異常奔潰,再重啓後能從新接管之前鏈接到此主機的全部客戶端鏈接;不須要客戶端退出系統從新啓動;

 

解決問題的辦法:

問題一,增長心跳機制,讓客戶端定時向wcf主機發送一條消息,若是超時沒有接收到就證實客戶端斷開了鏈接;解決網絡中斷客戶端自動重連服務端,首先客戶端設置爲取消服務器憑據認證,再就是客戶端調用重連方法;

<netTcpBinding>
        <binding name="netTcpExpenseService_ForSupplier" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
            hostNameComparisonMode="StrongWildcard" listenBacklog="10"
            maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10"
            maxReceivedMessageSize="2147483647">
      <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
          maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00"
          enabled="false" />
      <security mode="None">
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
        <message clientCredentialType="Windows" />
      </security>
    </binding>
    </netTcpBinding>
/// <summary>
        /// 從新鏈接wcf服務
        /// </summary>
        /// <param name="mainfrm"></param>
        public static void ReConnectionWCFService(IClientService mainfrm)
        {
            try
            {
                NetTcpBinding binding = new NetTcpBinding("NetTcpBinding_WCFHandlerService");
                //binding.OpenTimeout = TimeSpan.FromSeconds(10);
                //binding.TransferMode = TransferMode.Buffered;
                DuplexChannelFactory<IapiWCFHandlerService> mChannelFactory = new DuplexChannelFactory<IapiWCFHandlerService>(mainfrm, binding, System.Configuration.ConfigurationSettings.AppSettings["WCF_endpoint"]);
                IapiWCFHandlerService wcfHandlerService = mChannelFactory.CreateChannel();

                using (var scope = new OperationContextScope(wcfHandlerService as IContextChannel))
                {
                    var router = System.ServiceModel.Channels.MessageHeader.CreateHeader("routerID", myNamespace, AppGlobal.cache.GetData("routerID").ToString());
                    OperationContext.Current.OutgoingMessageHeaders.Add(router);
                    wcfHandlerService.Heartbeat(AppGlobal.cache.GetData("WCFClientID").ToString());
                }

                if (AppGlobal.cache.Contains("WCFService")) AppGlobal.cache.Remove("WCFService");
                AppGlobal.cache.Add("WCFService", wcfHandlerService);

                //開啓發送心跳
                //if (timer == null)
                //    StartSendWCFHeartbeat();
                //else
                //    timer.Start();
            }
            catch { }
        }

 

問題二,必須解決中間件可以把緩存的客戶端信息進行持久化,從新啓動中間件又能加載非正常退出的客戶端信息;

 

4.總結

       WCF中間件基本功能都已具有,實現了客戶端與服務端的通信,實現服務端分佈式部署與負載均衡。但中間件仍是很是簡陋的,如持久化客戶端鏈接數據、更加靈活的負載均衡算法等還有許多功能須要不斷完善。中間件路由與負載均衡的實現下一章詳細講解。

相關文章
相關標籤/搜索