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

发布于 2024-08-05 18:18:03 字数 4209 浏览 3 评论 0原文

我们希望在同一台计算机上运行的两个 .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 页面。这个页面说:

无需在服务实现中实现 MetadataReference 合约。相反,请将 ServiceMetadataBehavior 添加到服务描述中。

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

有关在 WCF 中发布元数据的详细信息,请参阅发布元数据。< /p>

因为,对于此示例,我没有使用配置文件,而是选择转到 发布元数据链接。从那里我转到如何:使用代码发布服务的元数据 链接有一个很好的示例,我用它来修改我的服务应用程序代码。添加的代码位于第 15-20 行。

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

毕竟,生成的代码对我来说没有任何作用。首先,它重新创建了我的 IService 接口,但将我的所有 IMessage 转换为对象,并对其进行了稍微不同的装饰。如果使用他们的接口,那么它不仅会使用与我的服务实际实现的不同的 IService,而且该 IService 中的方法甚至不具有相同的签名!

抛开这一点,我认为我必须更改我的客户端才能使用新生成的对象中的对象,因此我更改了我的 客户端代码。

现在,当我尝试运行它时,我在第 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)因他的所有帮助而获得了赏金,尽管事实上这一切都是在我提供赏金之前。

We want to have two .NET apps running on the same machine communicate with each other. We want three projects. A library containing interfaces. A "server" app that implements the interfaces and "client" app that communicates with the server using the interfaces. We do not want the client to reference the server.
We have a test app that does this with remoting but recently discovered that remoting is being replaced with WCF. Since this is new development we feel we should use WCF but we haven't managed to make it work with WCF and were wondering if it is possible?


EDIT:

Sorry for my lack of detail above but I didn't have access to any code at the time. I am working with two other people on this project and haven't looked closely at their IPC stuff. I know that they are currently of the opinion that WCF cannot do what they want it to do and I am hoping to be able to show them that it can.

I've started looking at my coworkers attempts at this and will continue to update this post as I understand it.

Below is a simplified version of their test code for remoting. They want to be able to do this using WCF but so far have been unable to get it to work.

Both the ServiceApp and ClientApp assemblies reference the Lib assembly. They do not reference each other.

I will edit this again when I am better able to explain their attempt to replicate this behavior in WCF. At this point all I really know is that they are using NetNamedPipeBinding and are having trouble with the client app complaining that it cannot access the service assembly.


EDIT:

Below is a simplified version of the test code for WCF.

The following line from ClientProgram throws an exception:

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

Here is the exception:

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.

EDIT:

In trying to understand Steven's latest comment I googled IMetadataExchange which of course had as its first hit the MSDN Page. This page said:

There is no need to implement the MetadataReference contract in your service implementation. Instead, add the ServiceMetadataBehavior to the service description.

Or, when using configuration, set the contract attribute of the endpoint element to IMetadataExchange. For an example, see How to: Publish Metadata for a Service Using a Configuration File.

For details on publishing metadata in WCF see Publishing Metadata.

Because, for this example, I am not using configuration files but instead I choose to go to the Publishing Metadata link. From there I went to the How to: Publish Metadata for a Service Using Code link which had a nice example that I used to modify my service app code. The added code is on lines 15-20.

I was able to add the Service Reference after a little work. The service has to be running but if you run the service through Visual Studio then you don’t have the option to add the service reference. Also, I still don't understand how the "Discover Services in Solution" option is supposed to work. In the end I was able to add the reference by opening by bin/debug folder to manually run the service and then entering the URL I added to my service app. If this is the correct way it rather awkward.

After all of that the code generated doesn’t make any since to me. First off it recreates my IService interface but turns all my IMessages into objects and decorates it slightly differently. If their interface is used then not only will it be using a different IService then my service actually implements but the methods in this IService don't even have the same signatures!

Putting that aside I assumed I would have to change my client to use the objects from the newly generated object so I changed my client code.

Now when I attempt to run it I get the following error on line 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.

EDIT:

One day left for the bounty and no answers since I added the bounty. Is there anything I can clarify before the bounty time is up?


EDIT:

In the end we went with remoting because it doesn't look as if what we want to do is possible with WCF. Steven Sudit gets the bounty for all his help despite the fact that it was all before I offered the bounty.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

猫九 2024-08-12 18:18:03

WCF 是可行的方法,具体检查 Net Named Pipe 与 WCF 的绑定。这将允许同一台机器上非常快速的进程间通信。

如果您的生产部署目标是 Windows Server 2008,那么您可以利用 IIS 7 作为托管环境。请查看使用 WAS 将 WCF 服务扩展到 HTTP 之外

那里有很多 WCF 入门类型信息。查看:

如果您在入门时遇到问题,请发布任何具体错误或示例,您可以已经演示过了,我相信这里有人可以提供帮助!

WCF is the way to go, specifically check out the Net Named Pipe binding with WCF. This will allow very fast interprocess communication on the same machine.

If your targeting Windows Server 2008 for your production deployment then you can leverage IIS 7 as a hosting environment. Check out Extend Your WCF Services Beyond HTTP With WAS.

There is lots of WCF getting started type information out there. Check out:

If your having problems getting started, then post any specific errors, or examples, you might have demonstrating it and I'm sure someone here can help!

绝不放开 2024-08-12 18:18:03

两者都用过。

一定要选择WCF。

远程处理的文档记录很差并且很敏感。相比之下,WCF 就容易多了。不确定您遇到的问题,但 WCF 上有大量文档。

Used both.

Definitely go with WCF.

Remoting is badly documented and touchy. WCF is so much easier by comparison. Not sure the issues you're having but there's tons of docs on WCF out there.

予囚 2024-08-12 18:18:03

远程处理有一些用例,例如单个进程内应用程序域之间的通信。话虽如此,是的,WCF 是正确的选择。不过,从您所说的一些内容来看,我不确定您是否理解这是如何运作的。

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

Remoting has some use cases, such as communication among appdomains within a single process. Having said that, yes, WCF is the way to go. From some of the things you've said, though, I'm not sure if you understand how this is supposed to work.

The usual way to do things in WCF is to create a shared assembly consisting entirely of data transfer objects (all properties, no code) and interfaces. Both sides reference this assembly, but the client uses a service reference of the server. Does that help?

極樂鬼 2024-08-12 18:18:03

我刚刚将程序从远程处理切换到 WCF,并且遇到了一些过去在远程处理中无缝工作但在 wcf 中导致问题的问题:

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

我并不是说您应该使用远程处理,我只是说也有理由考虑远程处理。这绝对是设置和开始工作更简单的一种。

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

I just switched a program over from remoting to WCF and I have come across a bunch of things that used to work seamlessly in remoting but that causes problems in wcf:

  • The CallContext class is gone. I used that for passing some information about e.g. the currently selected language and some info about the user. With WCF I had to create a MessageInspector to add headers with this info to every request.
  • The exceptions are no longer passed through unchanged. Instead you need to use the FaultException and FaultContracts.
  • The proxies don't seem to be as light weight. I need to dispose them instead of just leaving them to be garbage collected or else my service will hang. (Actually it isn't even as simple as calling Dispose to correctly terminate a proxy you need a fairly complex sequence of try, catch, finally that calls Close and Abort for different types of exceptions.) The need to close the proxies causes a bit of a problem where I want my IoC framework to manage the proxies.

I am not saying you should use Remoting, I'm just saying that there are reasons to consider Remoting as well. It is definitely the simpler one to set up and get to work.

I guess you could argue that I ran into some of these problems only because I wasn't using best practices in my Remoting program, though. :-P

执手闯天涯 2024-08-12 18:18:03

这里是使用 WCF 执行类似 Remoting 操作的一种模式:

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

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

Here one pattern to do Remoting-like things with WCF:

  • 3 projects: server, client, shared.dll
  • server and client both reference shared.dll
  • put the service interface with [ServiceContract] into shared.dll
  • put service implementation class into the server
  • don't use interfaces for your data types
  • create bare-bones DataContract types with only the logic you want shared between client and server (e.g. validation)
  • put your DataContract data types into shared.dll
  • Don't use NetDataContractSerializer (like you seem to be doing in your code)

There are variations on this theme of course. E.g. instead of the shared dll you can share code files between server and client projects with #if for different compilation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文