我的想法是,當客戶端主程序加載一個新的 PassiveAddin 時,可以在某個菜單的子Items上添加一項,當雙擊這個子菜單項時,則彈出該客戶端插件提供的“業務操作窗體”。這只是使用客戶端插件的可行方式之一,你完全可以根據你的應用來決定使用形式。 IPassiveAddin 接口定義如下:
2 /// IPassiveAddin用于客戶端的插件。通常一個PassiveAddin對應著一個服務端的功能插件FunAddin
3 /// zhuweisky2006.03.13
4 /// </summary>
5 public interface IPassiveAddin:IAddin
6 {
7 TypeAddinFormType{ get ;} // AddinFormType必須實現IAddinForm接口
8 }
9
10 public interface IPassiveAddinForm
11 {
12 // PassiveAddin通過IServerAgent發送請求并獲取結果
13 void Initialize(IServerAgentserverAgent, string userID);
14 }
IPassiveAddin 直接從 IAddin 繼承,僅僅增加了一個屬性 AddinFormType ,這個屬性就是前面說的客戶端插件提供的“業務操作窗體”。“業務操作窗體”必須從 IPassiveAddinForm 接口繼承。
“業務操作窗體”只有通過暴露的 Initialize 方法獲取 IServerAgent 引用后,才能發送請求獲取結果。 Initialize 方法的第二個參數說明當前時哪個用戶在操作,這樣客戶端插件在構建請求消息時,需要將 userID 填充到請求消息的消息頭中去,這樣服務器才會知道這個消息的來源。
下面的代碼說明了客戶端主程序是如何加載 IPassiveAddin 的:
2 {
3 this .lIToolStripMenuItem_addin.DropDownItems.Clear();
4
5 string directory = System.IO.Directory.GetParent(System.Windows.Forms.Application.ExecutablePath).FullName;
6 this .addinManagement.LoadAllAddins(directory, true );
7
8 foreach (IAddinaddin in this .addinManagement.AddinList)
9 {
10 IPassiveAddinpassiveAddin = addin as IPassiveAddin;
11 if (passiveAddin != null )
12 {
13 ToolStripItemitem = new ToolStripMenuItem(passiveAddin.ServiceName, null , new EventHandler( this .OnAddinMenuClicked));
14 item.Tag = passiveAddin;
15 this .lIToolStripMenuItem_addin.DropDownItems.Add(item);
16 }
17 }
18 }
19
20 private void OnAddinMenuClicked( object sender,EventArgse)
21 {
22 try
23 {
24 ToolStripItemitem = (ToolStripItem)sender;
25 IPassiveAddinpassiveAddin = (IPassiveAddin)item.Tag;
26 FormaddinForm = (Form)Activator.CreateInstance(passiveAddin.AddinFormType);
27 ((IPassiveAddinForm)addinForm).Initialize( this .tcpServerAgent, this .currentUserID);
28 addinForm.Show();
29 }
30 catch (Exceptionee)
31 {
32 ee = ee;
33 }
34 }
上述的介紹沒有什么難點,仔細體會一下都能明白,就不多說了。這里我給出一個測試用的功能插件和對應的客戶端插件示例。 示例的功能插件用于從 http://www.webservicex.net/globalweather.asmx 通過 WebService 獲取城市的天氣信息,而客戶端插件則用于為用戶提供這項服務。
先看服務端功能插件實現:

主要是 DealRequestMessage 方法 的實現,代碼非常簡單,通過WebService獲取指定城市的天氣情況,將返回的XML解析封裝成IContract,然后返回給客戶端。
接下來看客戶端插件的實現,分為兩步:
首先是“業務操作窗體”界面設計
。
該窗體要從IPassiveAddinForm接口繼承。當點擊按鈕時,處理代碼為:

<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> privatevoidbutton1_Click(objectsender,System.EventArgse)
{
stringcityName=ESFramework.Common.ChsToSpellConverter.Convert(this.comboBox1.SelectedItem.ToString());
WeatherReqContractbody=newWeatherReqContract(this.contractHelper);
body.cityName=cityName;
MessageHeaderheader=newMessageHeader(this.contractHelper);
header.TypeKey=int.Parse(this.textBox_asCityCode.Text.Trim());
header.ServiceKey=987;
header.UserID=this.curUserID;
header.UserIDLen=this.contractHelper.GetBytesFromStr(this.curUserID).Length;
header.MessageBodyLength=body.GetStreamLength();
ESFramework.Network.Messagemsg=newESFramework.Network.Message(header,body);
NetMessageresMsg=this.theAgent.CommitRequest(msg,DataPriority.Common,true);
if(resMsg.Header.Result!=ServiceResultType.ServiceSucceed)
{
MessageBox.Show("沒有發現對應的服務~!");
return;
}
WeatherPredictionContractresContract=newWeatherPredictionContract(this.contractHelper);
resContract.FillMyself(resMsg.Body,resMsg.BodyOffset);
this.groupBox1.Text="服務結果--"+this.comboBox1.SelectedItem.ToString();
this.label_pressure.Text=resContract.Pressure;
this.label_temp.Text=resContract.Temprature;
this.label_vis.Text=resContract.Visbility;
this.label_wind.Text=resContract.Wind;
this.label_time.Text=resContract.PreTime;
}
注意,theAgent成員即是通過Initialize傳入的IServerAgent引用!
接著是 IPassiveAddin 實現:

需要格外注意要實現AddinFormType屬性,就是前面實現的“業務窗體”類型。
下圖是功能服務器加載功能插件的截圖:
下圖是客戶端加載客戶插件后的截圖:
下圖是客戶端插件提供服務的截圖:
經過上述的介紹,讀者應該對開發服務端的功能插件和客戶端插件有些了解了。快結束的時候,再為下篇blog開個頭。當我們開發了客戶端插件和服務端插件后,做調試是一項非常麻煩的工作,因為不僅要啟動應用服務器,還要啟動客戶端主程序、功能服務器才行。為了簡化這個過程,我實現了一個Bridge應用程序,只需要加載一pair插件(服務端插件和對應的客戶插件),即可進行兩個插件的調試,而不用在啟動客戶端、AS、FS了。
感謝關注!
上一篇:
ESFramework介紹之(7)-- 服務器代理IServerAgent
轉到:
ESFramework 可復用的通信框架(序)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
