DCOM揭秘:DCOM教程,第5步





5.00/5 (9投票s)
我们来看看连接点,并设置服务器端的连接点。我们还将完成SayHello()方法的实现。
引言
欢迎来到我们的DCOM教程第5步。在本系列中,我将通过一个直接的例子,为您提供一个全面的教程,揭开DCOM的神秘面纱,消除其带来的困扰和混淆。好吧,不能保证——但我会尽力而为。
如果您想跟随本教程,并在此过程中添加代码和使用Visual C++向导,那太棒了。事实上,我非常非常强烈地推荐您这样做,否则本教程将是浪费大量的电子墨水(?)。然而,我在编写本教程时,也完全按照教程进行操作,并像我告诉您应该做的那样开发代码和使用Visual C++向导。事实上,截图就是我开发每个步骤文件时截取的!要下载这些已经开发好的代码与您自己的代码进行比较,只需点击每个步骤顶部的“下载第 _n_ 步文件 - _n_ KB”链接。在本教程的问答页面上,还有一个包含所有步骤文件的档案。我仍然建议您与我们一起学习;这样,您可以在编码的同时学习。如果您在本教程过程中遇到任何问题,请随时
- 发送电子邮件给我:brian@harttechservices.com。
- 在此页面底部的留言板上发帖。
- 查看本教程的问题和解答页面。
连接点揭秘
在我们开始本教程的第5步之前,让我们花点时间让我揭开连接点的神秘面纱。下面的图1展示了一个通用场景,这个场景对于COM、DCOM,甚至函数回调都适用,天哪。
图1。一个源和一个接收器。
这涉及到两个对象,一个“源”和一个“接收器”。把“源”想象成家里厨房水槽的水龙头。你转动把手,就会有东西流出来(希望能是水)。它流到哪里去了?如果没有堵塞,这些水就会流到底部,进入排水管(可以看作是“接收器”)。好的,所以东西是从源流出,到接收器。在上面的厨房水槽类比中,这是水。然而,我从未见过有计算机网络系统在电线中流淌水,所以很明显,DCOM中还有其他东西在起作用。
在 DCOM 中,网络上的某个地方有一个“客户端”,网络上的某个地方也有一个“服务器”。如果不使用连接点,信息流向只有一个方向:方法调用取代了水,客户端取代了水龙头,服务器取代了排水管。这大大简化了事情,但用户“转动把手”(例如,点击一个按钮),“东西”(即方法调用)“从”客户端“出来”。这些“出来的东西”然后使用 DCOM 在网络上“流动”。这些调用“流向”服务器,服务器然后收集它们,并充当“排水管”或我们的接收器。这是图 2,它几乎与图 1完全相同,但将客户端放在“源”的位置,将服务器放在“接收器”的位置,网络在两者之间
图2。我们的客户端和服务器作为源和接收器。
好的,现在我们有了像水一样流动的方法调用;太棒了。然而,当客户端调用方法时,服务器会做各种可能对客户端有趣的事情。所以服务器会到处触发事件。如果我们的客户端不关心服务器是否触发事件,它就会忽略它们。但是,如果它关心,它就会Advise()
服务器。然后,图2的源-接收器关系可以反向思考
图3。图2的反向。
连接点在以下情况发生时发挥作用:
- 客户端是方法调用的源,
- 服务器接收(即作为接收器)方法调用。
- 一个“事件调用”从现在作为源的服务器中发出。
- 客户端接收事件调用并执行某些操作。
如您所见,这是一个往返过程。方法调用从客户端到服务器,然后事件调用从服务器到客户端,如图4所示。
图4。一次往返。
Advise()
步骤在上面第1项之前完成,而Unadvise()
步骤(客户端恢复冷漠状态)在第4项之后发生。客户端和服务器上的接触点以及发生的Advise()
和Unadvise()
共同构成了……
呼……多么大的启示……在我过于激动之前,让我们开始第5步吧……
第5步:将OnSayHello事件添加到事件源接口DHelloWorldEvents
我们开始吧,好吗?将事件添加到源非常非常简单。只需使用Visual C++向导即可!打开类视图,右键单击DHelloWorldEvents
图标,然后单击“添加方法”。“向接口添加方法”对话框将出现。在“方法名称”框中键入OnSayHello
,在“参数”框中键入[in] BSTR bstrHost
,如下图图5所示。
图5。将OnSayHello()
事件添加到DHelloWorldEvents
事件接口。
完成之后,点击“确定”。类视图应该如下图图6所示。现在点击“文件视图”,在源文件文件夹下找到HelloServ.idl
文件。右键点击它,然后选择“编译”。在“输出”窗口中观察编译器的工作,并等待构建完成。
图6。添加OnSayHello
事件后的类视图。
构建完成后,单击“类视图”。右键单击CHelloWorld
类,然后单击“实现连接点”。将出现“实现连接点”对话框。如果您还没有按照我的指示编译IDL文件,Visual C++会提示您这样做。下面的图7向您展示了如何选择使服务器能够触发其OnSayHello
事件
图7。指定我们希望为DHelloWorldEvents
事件接口实现连接点。
当所有内容都与图7所示一致时,单击“确定”。Visual C++ IDE现在将生成您连接点所需的所有服务器端代码。每次更改DHelloWorldEvents
事件接口中的事件时,您都需要执行以下步骤:(1)编译IDL,(2)右键单击CHelloWorld
并选择“实现连接点”,(3)选中DHelloWorldEvents
旁边的复选框,以及(4)单击“确定”。
后记
我们必须处理的第5步的最后一部分是触发事件。记住,我们在IDL文件中将OnSayHello()
事件声明为
HRESULT OnSayHello(BSTR bstrHost);清单1。
OnSayHello()
事件的声明。要从任何CHelloWorld
成员函数触发事件,只需调用Fire_OnSayHello()
。它是“实现连接点”对话框刚刚为我们添加的一个新基类CProxyDHelloWorldEvents< >
的成员函数。为此,让我们向CHelloWorld::SayHello()
函数添加代码,以向客户端触发事件
STDMETHODIMP CHelloWorld::SayHello() { USES_CONVERSION; // Get the network name of this computer TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1]; DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1; if (!GetComputerName(szComputerName, &dwSize)) return E_FAIL; // failed to get the name of this computer // Say Hello to the client Fire_OnSayHello(T2OLE(szComputerName)); return S_OK; }清单2。要添加到完成
CHelloWorld::SayHello()
成员函数的代码。就是这样!我们完成了第5步。点击“下一步”进入第6步,或者如果您正在浏览教程,点击“返回”回到第4步。如果您有任何问题,请尝试点击“问答”页面查看相关内容,如果您仍然遇到问题,请发送电子邮件至brian@harttechservices.com。