65.9K
CodeProject 正在变化。 阅读更多。
Home

DCOM揭秘:DCOM教程,第5步

starIconstarIconstarIconstarIconstarIcon

5.00/5 (9投票s)

2000 年 8 月 7 日

CPOL
viewsIcon

292236

downloadIcon

2153

我们来看看连接点,并设置服务器端的连接点。我们还将完成SayHello()方法的实现。

引言

欢迎来到我们的DCOM教程第5步。在本系列中,我将通过一个直接的例子,为您提供一个全面的教程,揭开DCOM的神秘面纱,消除其带来的困扰和混淆。好吧,不能保证——但我会尽力而为。

如果您想跟随本教程,并在此过程中添加代码和使用Visual C++向导,那太棒了。事实上,我非常非常强烈地推荐您这样做,否则本教程将是浪费大量的电子墨水(?)。然而,我在编写本教程时,也完全按照教程进行操作,并像我告诉您应该做的那样开发代码和使用Visual C++向导。事实上,截图就是我开发每个步骤文件时截取的!要下载这些已经开发好的代码与您自己的代码进行比较,只需点击每个步骤顶部的“下载第 _n_ 步文件 - _n_ KB”链接。在本教程的问答页面上,还有一个包含所有步骤文件的档案。我仍然建议您与我们一起学习;这样,您可以在编码的同时学习。如果您在本教程过程中遇到任何问题,请随时

连接点揭秘

在我们开始本教程的第5步之前,让我们花点时间让我揭开连接点的神秘面纱。下面的图1展示了一个通用场景,这个场景对于COM、DCOM,甚至函数回调都适用,天哪。

A source and a sink.
图1。一个源和一个接收器。

这涉及到两个对象,一个“源”和一个“接收器”。把“源”想象成家里厨房水槽的水龙头。你转动把手,就会有东西流出来(希望能是水)。它流到哪里去了?如果没有堵塞,这些水就会流到底部,进入排水管(可以看作是“接收器”)。好的,所以东西是源流出,接收器。在上面的厨房水槽类比中,这是水。然而,我从未见过有计算机网络系统在电线中流淌水,所以很明显,DCOM中还有其他东西在起作用。

在 DCOM 中,网络上的某个地方有一个“客户端”,网络上的某个地方也有一个“服务器”。如果不使用连接点,信息流向只有一个方向:方法调用取代了水,客户端取代了水龙头,服务器取代了排水管。这大大简化了事情,但用户“转动把手”(例如,点击一个按钮),“东西”(即方法调用)“从”客户端“出来”。这些“出来的东西”然后使用 DCOM 在网络上“流动”。这些调用“流向”服务器,服务器然后收集它们,并充当“排水管”或我们的接收器。这是图 2,它几乎与图 1完全相同,但将客户端放在“源”的位置,将服务器放在“接收器”的位置,网络在两者之间

Our client and server as the source and the sink.
图2。我们的客户端和服务器作为源和接收器。

好的,现在我们有了像水一样流动的方法调用;太棒了。然而,当客户端调用方法时,服务器会做各种可能对客户端有趣的事情。所以服务器会到处触发事件。如果我们的客户端不关心服务器是否触发事件,它就会忽略它们。但是,如果它关心,它就会Advise()服务器。然后,图2的源-接收器关系可以反向思考

The reverse of Figure 2.
图3。图2的反向。

连接点在以下情况发生时发挥作用:

  1. 客户端是方法调用的
  2. 服务器接收(即作为接收器)方法调用。
  3. 一个“事件调用”从现在作为的服务器中发出。
  4. 客户端接收事件调用并执行某些操作。

如您所见,这是一个往返过程。方法调用客户端服务器,然后事件调用服务器客户端,如图4所示。

A round-trip.
图4。一次往返。

Advise()步骤在上面第1项之前完成,而Unadvise()步骤(客户端恢复冷漠状态)在第4项之后发生。客户端和服务器上的接触点以及发生的Advise()Unadvise()共同构成了……

一个连接点!

呼……多么大的启示……在我过于激动之前,让我们开始第5步吧……

第5步:将OnSayHello事件添加到事件源接口DHelloWorldEvents

我们开始吧,好吗?将事件添加到源非常非常简单。只需使用Visual C++向导即可!打开类视图,右键单击DHelloWorldEvents图标,然后单击“添加方法”。“向接口添加方法”对话框将出现。在“方法名称”框中键入OnSayHello,在“参数”框中键入[in] BSTR bstrHost,如下图图5所示。

Adding the OnSayHello event to the DHelloWorldEvents event interface.
图5。OnSayHello()事件添加到DHelloWorldEvents事件接口。

完成之后,点击“确定”。类视图应该如下图图6所示。现在点击“文件视图”,在源文件文件夹下找到HelloServ.idl文件。右键点击它,然后选择“编译”。在“输出”窗口中观察编译器的工作,并等待构建完成。

ClassView after adding the OnSayHello event.
图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

<< 返回 | 下一步 >>

问答

© . All rights reserved.