代码之家  ›  专栏  ›  技术社区  ›  drs9222

使用接口远程处理或WCF进行新的开发(在同一台计算机上的两个.NET应用程序之间)?

  •  11
  • drs9222  · 技术社区  · 16 年前

    我们希望在同一台计算机上运行两个.NET应用程序,以便彼此通信。我们要三个项目。包含接口的库。实现接口的“服务器”应用程序和使用接口与服务器通信的“客户端”应用程序。我们不希望客户端引用服务器。
    我们有一个测试应用程序可以对远程处理进行测试,但是最近发现远程处理正在被WCF所取代。由于这是一个新的开发,我们认为我们应该使用WCF,但我们还没有设法使它与WCF一起工作,我们想知道这是否可能?


    编辑:

    很抱歉我没有上面的详细信息,但当时我无法访问任何代码。我和另外两个人在这个项目上工作,没有仔细研究他们的IPC资料。我知道,他们目前认为,世界自然基金会不能做他们想做的事情,我希望能够向他们证明,它可以。

    我已经开始关注我的同事们在这方面的尝试,并将继续更新我理解的这篇文章。

    下面是用于远程处理的测试代码的简化版本。他们希望能够使用WCF来完成这项工作,但到目前为止还不能让它工作。

    serviceapp和clientapp程序集都引用lib程序集。它们不相互引用。

    当我能够更好地解释他们在WCF中复制此行为的尝试时,我将再次编辑此内容。此时,我真正知道的是,他们使用的是netnamedpipebinding,并且客户机应用程序有问题,抱怨它无法访问服务程序集。


    编辑:

    下面是WCF测试代码的简化版本。

    来自clientProgram的以下行引发异常:

    IMessage msg2 = service.CreateMessage("Hello World");
    

    例外情况如下:

    Could not load file or assembly 'ServiceApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

    编辑:

    为了理解史蒂文的最新评论,我在谷歌上搜索了iMetaDataExchange,它当然是第一个点击 MSDN Page . 这页说:

    在服务实现中不需要实现元数据引用契约。相反,将ServiceMetadataBehavior添加到服务描述中。

    或者,在使用配置时,将endpoint元素的contract属性设置为IMetadataExchange。有关示例,请参见如何:使用配置文件发布服务的元数据。

    有关在WCF中发布元数据的详细信息,请参阅 Publishing Metadata .

    因为在本例中,我不使用配置文件,而是选择转到 发布元数据 链接。从那里我去了 How to: Publish Metadata for a Service Using Code 链接有一个很好的例子,我用它来修改我的 service app code . 添加的代码在第15-20行。

    我在做了一点工作之后就可以添加服务引用了。必须运行该服务,但如果您通过Visual Studio运行该服务,则您没有添加服务引用的选项。此外,我仍然不理解“在解决方案中发现服务”选项应该如何工作。最后,我可以通过打开bin/debug文件夹手动运行服务,然后输入我添加到我的服务应用程序的URL来添加引用。如果这是正确的方式,那就相当尴尬。

    在所有这些之后 code generated 从那以后我就什么都不做了。首先,它重新创建了我的iService接口,但将所有IMessage转换为对象,并对其进行稍微不同的修饰。如果使用了它们的接口,那么它不仅会使用不同的IService,而且我的服务实际上实现了,但是这个IService中的方法甚至没有相同的签名!

    撇开这一点不谈,我假设必须更改客户机才能使用新生成的对象中的对象,因此我更改了 client code .

    现在,当我尝试运行它时,我在第4行得到以下错误:

    The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:msg. The InnerException message was 'XML 'Element' 'http://tempuri.org/:msg' does not contain expected attribute 'http://schemas.microsoft.com/2003/10/Serialization/:Type'. The deserializer has no knowledge of which type to deserialize. Check that the type being serialized has the same contract as the type being deserialized.'.  Please see InnerException for more details.

    编辑:

    有一天,我得到了赏金,但自从我加了赏金之后,就没有答案了。在赏金时间到之前我有什么可以澄清的吗?


    编辑:

    最后,我们进行了远程处理,因为看起来似乎我们想要做的事情在WCF中是不可能的。史蒂文·苏迪特得到了他所有帮助的赏金,尽管在我提供赏金之前就已经得到了。

    5 回复  |  直到 15 年前
        1
  •  3
  •   Steven Sudit    16 年前

    远程处理有一些用例,例如单个进程中AppDomain之间的通信。说了这句话,是的,世界自然基金会是前进的道路。不过,从你所说的一些事情来看,我不确定你是否理解这是如何工作的。

    在WCF中,通常的方法是创建一个完全由数据传输对象(所有属性,没有代码)和接口组成的共享程序集。双方都引用此程序集,但客户端使用服务器的服务引用。这有帮助吗?

        2
  •  18
  •   Zach Bonham    16 年前

    WCF是一种方法,专门检查与WCF的网络命名管道绑定。这将允许在同一台机器上进行非常快速的进程间通信。

    如果您将Windows Server 2008作为生产部署的目标,则可以利用IIS 7作为宿主环境。退房 Extend Your WCF Services Beyond HTTP With WAS .

    有很多WCF入门类型信息。退房:

    如果您在开始时遇到问题,那么请发布任何特定的错误或示例,您可能已经演示过了,我相信这里的某人可以提供帮助!

        3
  •  4
  •   Will    16 年前

    两者都用。

    当然要和WCF一起去。

    远程处理记录得很糟糕,而且很敏感。相比之下,WCF要容易得多。不知道你有什么问题,但是有很多关于WCF的文档。

        4
  •  3
  •   Johan Levin    16 年前

    我刚将一个程序从远程处理切换到了WCF,我遇到了许多以前在远程处理中无缝工作但在WCF中导致问题的事情:

    • CallContext类已不存在。我用它传递一些信息,例如当前选定的语言和用户的一些信息。使用wcf,我必须创建一个messageinspector来向每个请求添加包含此信息的头。
    • 异常不再以不变的方式传递。相反,您需要使用faultexception和faultcontracts。
    • 代理人似乎没有那么轻。我需要把它们处理掉,而不是让它们被垃圾收集,否则我的服务就会挂起。(实际上,调用Dispose来正确终止代理并不简单,您需要一个相当复杂的Try、Catch、Finally序列,针对不同类型的异常调用Close和Abort。)关闭代理的需要导致了一个问题,我希望我的IOC框架管理代理。

    我不是说你应该远程处理,我只是说有理由考虑远程处理。这绝对是一个简单的设置和开始工作。

    我想你可能会说我遇到了这些问题,只是因为我没有在远程处理程序中使用最佳实践。-P

        5
  •  1
  •   Eugene Osovetsky    15 年前

    这里有一个使用wcf进行远程处理的模式:

    • 3个项目:服务器、客户端、共享.dll
    • 服务器和客户端都引用shared.dll
    • 将带有[servicecontract]的服务接口放入shared.dll
    • 将服务实现类放入服务器
    • 不要为数据类型使用接口
    • 仅使用希望在客户端和服务器之间共享的逻辑(例如验证)创建裸机数据合同类型
    • 将DataContract数据类型放入shared.dll
    • 不要使用NetDataContractSerializer(就像在代码中一样)

    当然,这个主题也有变化。例如,对于不同的编译,您可以与if共享服务器和客户机项目之间的代码文件,而不是共享的dll。

    推荐文章