加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

ESFramework介绍之(8)-- 客户端插件IPassiveAddin

发布时间:2020-12-17 02:56:52 所属栏目:安全 来源:网络整理
导读:??? 前文已经提到了,在 IServerAgent 的基础上,客户端也可以采用插件的结构形式,客户端插件需要实现 IPassiveAddin 接口。 ???? 我的想法是,当客户端主程序加载一个新的 PassiveAddin 时,可以在某个菜单的子Items上添加一项,当双击这个子菜单项时,则
??? 前文已经提到了,在IServerAgent的基础上,客户端也可以采用插件的结构形式,客户端插件需要实现IPassiveAddin接口。
????我的想法是,当客户端主程序加载一个新的PassiveAddin时,可以在某个菜单的子Items上添加一项,当双击这个子菜单项时,则弹出该客户端插件提供的“业务操作窗体”。这只是使用客户端插件的可行方式之一,你完全可以根据你的应用来决定使用形式。IPassiveAddin接口定义如下:

?1???? /// ? <summary>
?2? ???? /// ?IPassiveAddin?用于客户端的插件。通常一个PassiveAddin对应着一个服务端的功能插件FunAddin
?3? ???? /// ?zhuweisky?2006.03.13
?4? ???? /// ? </summary>
?5? ???? public ? interface ?IPassiveAddin?:?IAddin
?6? ????{
?7? ????????Type?AddinFormType{ get ?;}? // AddinFormType必须实现IAddinForm接口
?8? ????}
?9?
10? ???? public ? interface ?IPassiveAddinForm
11? ????{
12? ???????? // PassiveAddin通过IServerAgent发送请求并获取结果
13? ???????? void ?Initialize(IServerAgent?serverAgent?, string ?userID)?;
14? ????}

??? IPassiveAddin直接从IAddin继承,仅仅增加了一个属性AddinFormType,这个属性就是前面说的客户端插件提供的“业务操作窗体”。“业务操作窗体”必须从IPassiveAddinForm接口继承。
??? “业务操作窗体”只有通过暴露的Initialize方法获取IServerAgent引用后,才能发送请求获取结果。Initialize方法的第二个参数说明当前时哪个用户在操作,这样客户端插件在构建请求消息时,需要将userID填充到请求消息的消息头中去,这样服务器才会知道这个消息的来源。

??? 下面的代码说明了客户端主程序是如何加载IPassiveAddin的:

?1? ????????? private ? void ?LoadPassiveAddins()
?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 ?(IAddin?addin? in ? this .addinManagement.AddinList)
?9? ????????????{
10? ????????????????IPassiveAddin?passiveAddin? = ?addin? as ?IPassiveAddin;
11? ???????????????? if ?(passiveAddin? != ? null )
12? ????????????????{
13? ????????????????????ToolStripItem?item? = ? 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,?EventArgs?e)
21? ????????{
22? ???????????? try
23? ????????????{
24? ????????????????ToolStripItem?item? = ?(ToolStripItem)sender;
25? ????????????????IPassiveAddin?passiveAddin? = ?(IPassiveAddin)item.Tag;
26? ????????????????Form?addinForm? = ?(Form)Activator.CreateInstance(passiveAddin.AddinFormType);
27? ????????????????((IPassiveAddinForm)addinForm).Initialize( this .tcpServerAgent?, this .currentUserID);
28? ????????????????addinForm.Show();
29? ????????????}
30? ???????????? catch ?(Exception?ee)
31? ????????????{
32? ????????????????ee? = ?ee;
33? ????????????}
34? ????????}

??? 上述的介绍没有什么难点,仔细体会一下都能明白,就不多说了。这里我给出一个测试用的功能插件和对应的客户端插件示例。示例的功能插件用于从http://www.webservicex.net/globalweather.asmx 通过WebService获取城市的天气信息,而客户端插件则用于为用户提供这项服务。

先看服务端功能插件实现:

WeatherPreAddin

主要是DealRequestMessage方法的实现,代码非常简单,通过WebService获取指定城市的天气情况,将返回的XML解析封装成IContract,然后返回给客户端。

接下来看客户端插件的实现,分为两步:首先是“业务操作窗体”界面设计


?该窗体要从IPassiveAddinForm接口继承。当点击按钮时,处理代码为:

button1_Click
??????? private?void?button1_Click(object?sender,?System.EventArgs?e)
????????{
????????????string?cityName?=?ESFramework.Common.ChsToSpellConverter.Convert(this.comboBox1.SelectedItem.ToString())?;
????????????WeatherReqContract?body?=?new?WeatherReqContract(this.contractHelper)?;
????????????body.cityName?=?cityName?;
????????????MessageHeader?header?=?new?MessageHeader(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.Message?msg?=?new?ESFramework.Network.Message(header?,body)?;
???????????? NetMessage?resMsg?=?this.theAgent.CommitRequest(msg?,DataPriority.Common?,true)?;
????????????if(resMsg.Header.Result?!=?ServiceResultType.ServiceSucceed)
????????????{
????????????????MessageBox.Show("没有发现对应的服务~!")?;
????????????????return?;
????????????}

????????????WeatherPredictionContract?resContract?=?new?WeatherPredictionContract(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实现:

WeatherPassiveAddin

??? 需要格外注意要实现AddinFormType属性,就是前面实现的“业务窗体”类型。?

下图是功能服务器加载功能插件的截图:

?

下图是客户端加载客户插件后的截图:

?

下图是客户端插件提供服务的截图:

?

???? 经过上述的介绍,读者应该对开发服务端的功能插件和客户端插件有些了解了。快结束的时候,再为下篇blog开个头。当我们开发了客户端插件和服务端插件后,做调试是一项非常麻烦的工作,因为不仅要启动应用服务器,还要启动客户端主程序、功能服务器才行。为了简化这个过程,我实现了一个Bridge应用程序,只需要加载一pair插件(服务端插件和对应的客户插件),即可进行两个插件的调试,而不用在启动客户端、AS、FS了。

??? 感谢关注!

上一篇:ESFramework介绍之(7)-- 服务器代理IServerAgent

转到??:ESFramework 可复用的通信框架(序)?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读