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

时间:2009-09-20 23:08:47

标签: c# .net wcf remoting

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


编辑:

很抱歉我上面没有详细说明,但我当时无法访问任何代码。我正和另外两个人一起参与这个项目,并没有密切关注他们的IPC内容。我知道他们目前认为WCF无法做他们想做的事情,我希望能够向他们展示它可以做到的。

我已经开始关注我的同事尝试,并会按照我的理解继续更新这篇文章。

以下是用于远程处理的测试代码的简化版本。他们希望能够使用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。这个页面说:

  

您无需在服务实现中实现MetadataReference合约。而是将ServiceMetadataBehavior添加到服务描述中。

     

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

     

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

因为,对于此示例,我不使用配置文件,而是选择转到Publishing Metadata链接。从那里我去了How to: Publish Metadata for a Service Using Code链接,这个链接有一个很好的例子,我用来修改我的service app code。添加的代码在第15-20行。

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

在完成所有这些之后code generated对我来说没有任何结果。首先,它重新创建我的IService接口,但将我的所有IMessages转换为对象并以稍微不同的方式装饰它。如果使用它们的接口,那么它不仅会使用不同的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。 Steven Sudit获得了所有帮助的赏金,尽管在我提供赏金之前就已经完成了这一切。

5 个答案:

答案 0 :(得分:18)

WCF是要走的路,特别是检查与WCF的Net Named Pipe绑定。这将允许在同一台机器上进行非常快速的进程间通信。

如果您的生产部署针对Windows Server 2008,那么您可以利用IIS 7作为托管环境。查看Extend Your WCF Services Beyond HTTP With WAS

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

如果你有问题入门,然后发布任何特定错误或示例,你可能已经证明了这一点,我相信这里有人可以提供帮助!

答案 1 :(得分:4)

两者同时使用。

绝对适合WCF。

Remoting记录错误且敏感。相比之下,WCF更容易。不确定你遇到的问题,但那里有大量关于WCF的文档。

答案 2 :(得分:3)

远程处理有一些用例,例如单个进程内appdomains之间的通信。话虽如此,是的,WCF是要走的路。但是,从你所说的一些事情来看,我不确定你是否理解这应该如何运作。

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

答案 3 :(得分:3)

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

  • CallContext类消失了。我用它来传递一些有关例如当前选择的语言和有关用户的一些信息。使用WCF,我必须创建一个MessageInspector,将带有此信息的标头添加到每个请求中。
  • 例外情况不再保持不变。相反,您需要使用FaultException和FaultContracts。
  • 代理似乎不那么轻。我需要处理它们而不是让它们被垃圾收集,否则我的服务就会挂起。 (实际上它甚至不像调用Dispose正确终止代理一样简单,你需要一个相当复杂的try,catch序列,最后调用Close和Abort来处理不同类型的异常。)关闭代理需要一点点我希望我的IoC框架能够管理代理的问题。

我不是说你应该使用Remoting,我只是说有理由考虑Remoting。这绝对是设置和开始工作的简单方法。

我想你可能会说我遇到了一些问题只是因为我没有在我的Remoting程序中使用最佳实践。 :-P

答案 4 :(得分:1)

这里有一个模式可以用WCF做类似Remoting的事情:

  • 3个项目:server,client,shared.dll
  • 服务器和客户端都引用shared.dll
  • 将带有[ServiceContract]的服务接口放入shared.dll
  • 将服务实现类放入服务器
  • 不要使用数据类型的接口
  • 创建只有您希望在客户端和服务器之间共享的逻辑的简单DataContract类型(例如验证)
  • 将您的DataContract数据类型放入shared.dll
  • 请勿使用NetDataContractSerializer(就像您在代码中所做的那样)

当然,这个主题有各种变化。例如。您可以使用#if在不同的编译中共享服务器和客户端项目之间的代码文件,而不是共享的dll。