在.NET远程处理中,RemotingConfiguration.RegisterWellKnownServiceType和RemotingServices.Marshal之间有什么区别?
在.NET远程处理中,RemotingConfiguration.RegisterWellKnownServiceType和RemotingServices.Marshal之间有什么区别?
我想要做的是在 Windows 服务中创建一个对象,然后将其作为远程对象放入,并让 Windows 服务和客户端都对远程对象进行操作。
我认为下面的代码可以完成此任务。
FooRemoting foo = new FooRemoting();
RemotingConfiguration.RegisterWellKnownServiceType(typeof(FooRemoting), serverName, WellKnownObjectMode.Singleton);
RemotingServices.Marshal(foo);
In .NET remoting what is the difference between RemotingConfiguration.RegisterWellKnownServiceType and RemotingServices.Marshal?
What I want to do is create an object in a Windows Service, then put it in as a remoting object and have the Windows Service and the Client both act on the remoting object.
I thought the below code would accomplish this.
FooRemoting foo = new FooRemoting();
RemotingConfiguration.RegisterWellKnownServiceType(typeof(FooRemoting), serverName, WellKnownObjectMode.Singleton);
RemotingServices.Marshal(foo);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这就是我发现的。
RegisterWellKnownServiceType 将创建该对象并使其成为任何使用该对象的客户端的单例,但不会创建服务器的引用。 在客户端请求该对象之前,不会创建该对象,并且相同的对象可用于任何其他客户端。
Marshal 将注册一个由服务器创建的对象,在本例中是一个 Windows 服务。 然后服务器将引用该对象,并且客户端将使用相同的对象。
我的问题是使用 Marshal 注册远程对象。 随着时间的推移,远程对象将消失供客户端使用,即不再位于远程对象上。 该服务仍将保留其参考。
然后我尝试了 RegisterWellKnownServiceType,客户端不断获得正确的引用,但是我无法让服务引用同一对象。
解决方案是覆盖远程对象(在本例中为 FooRemoting)。 如果我覆盖 InitializeLifetimeService 并返回 null,客户端将永远不会失去连接,并且服务将,
保持连接。
为了保留服务创建的对象并让客户端使用相同的对象,您必须使用
并重写 InitializeLifetimeService 以返回 null。
This is what I found.
RegisterWellKnownServiceType will create the object and make it a Singleton to any client that consumes it, but a reference by the server is not created. The object is not created until a client ask for it, and the same object is used for any other clients.
Marshal will register an object that has been created by the server, in this case a windows service. Then server will then have reference to the object and the clients will consume the same object.
My issue was using the Marshal to register the remoting object. Over time the remoting object will disappear for clients to consume, i.e. no longer on the remoting object. The service would still keep its reference.
Then I tried the RegisterWellKnownServiceType and the clients keep getting the correct reference, however I could not get the service to have a reference to the same object.
The solution is overriding the remoting object in this case FooRemoting. If I overrode the InitializeLifetimeService and returned null, the client would never lose connection, and the service will,
keep the connection.
In order to keep the object created by the service and have the client to use the same object you must use
and override InitializeLifetimeService to return null.
可以通过远程处理公开具有参数构造函数的 MarshalByRefObjects,并且该类的用户可以仅处理其接口。
我创建了一个小型概念验证项目。 它有 3 个项目:服务器、客户端和核心。 服务器和客户端都引用Core,但不互相引用。
在核心中,我们定义一个服务接口:
服务器定义具体的实现,客户端没有引用:
需要注意的重要一点是它有一个带有参数的构造函数,它是一个MarshalByRefObject,它实现了核心项目中的接口。
服务器项目是一个控制台应用程序,它设置一个远程处理通道(在本例中任意通过 HTTP),创建服务,并将其注册到远程处理:
上面的代码已注册 URL http://localhost:8234/CountingService.rem 保存实例化的服务,该服务将从 5 开始计数。
客户端(也是一个控制台应用程序)可以获取引用,使用接口类:
当服务器和客户端运行时,它打印从 6 到 10 的值。
总结:客户端只知道接口; 实现构造函数可以有参数; 实例化可以由您自己的代码而不是.NET 来控制。 在处理远程对象的基于构造函数的依赖注入时非常有用。
It is possible to expose MarshalByRefObjects which have parameterful constructors over remoting, and it's possible for users of the class to only deal with its interface.
I have created a small proof of concept project. It has 3 projects: Server, Client, and Core. Server and Client both reference Core but do not reference each other.
In core, we define a service interface:
The server defines the concrete implementation, which the client doesn't have a reference to:
The important bits to note are that it has a constructor with a parameter, it is a MarshalByRefObject, and it implements the interface in the core project.
The server project is a console app which sets up a remoting channel (arbitrarily over HTTP for this example), creates the service, and registers it with remoting:
The above code has registered the URL http://localhost:8234/CountingService.rem which holds the instantiated service, which will start counting from 5.
The client, also a console app, can then get a reference, using the interface class:
When the server and client are run, it prints values from 6 to 10.
Summary: client knows only about the interface; implementation constructor can have parameters; instantiation can be controlled by your own code rather than by .NET. Very useful when dealing with constructor-based dependency injection with remoting objects.
我用 RemotingServices.Marshal 做了一项实验,就像
托管在 Windows Exe 中的远程组件一样。 Exe代码
现在在客户端代码中
它将弹出消息为0而不是100。如果您在RemoteClass的构造函数中放置断点,您将看到
我认为 RemotingServices.Marshal 与单实例无关。 即使您仅使用 RemotingConfiguration.Configure 并重写 InitializeLifetimeService 以使其返回 null,也足以托管远程组件。
I did one experiment with RemotingServices.Marshal like this
Remotable component hosted in a Windows Exe. Exe code is
Now in the client side code
It will popup the message as 0 not 100. If you put a breakpoint in the constructor of RemoteClass, you will see that the constructor is getting called 2 times
I think RemotingServices.Marshal has nothing to do with the single instance. Even if you use just RemotingConfiguration.Configure and override the InitializeLifetimeService so that it will return null, will be sufficient to host a remotable component.