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


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

 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框架全面支持多種系統開發;

 

本文要點:

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中間件基本功能都已具備,實現了客戶端與服務端的通訊,實現服務端分布式部署與負載均衡。但中間件還是非常簡陋的,如持久化客戶端連接數據、更加靈活的負載均衡算法等還有許多功能需要不斷完善。中間件路由與負載均衡的實現下一章詳細講解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM