.NET Remoting:如何从远程对象访问服务器应用程序对象?
我正在编写一个 Windows 服务应用程序,将通过 .NET Remoting 访问该应用程序。 问题是我无法弄清楚如何从远程类访问服务对象。
例如,我有一个处理程序类:
class Service_console_handler
{
public int something_more = 20;
//some code...
TcpChannel serverChannel = new TcpChannel(9090);
ChannelServices.RegisterChannel(serverChannel);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(RemoteObject), "RemoteObject.rem",
WellKnownObjectMode.Singleton);
//from here on RemoteObject is accessible by clients.
//some more code doing something and preparing the data...
}
我有一个远程类:
public class RemoteObject : MarshalByRefObject
{
private int something = 10;
public int Get_something()
{
return something;
}
}
客户端可以毫无问题地访问 RemoteObect 中的数据。 但是我如何访问 Service_console_handler
对象(即从 something_more
检索有用的信息)?
抱歉提出了愚蠢的问题,并提前致谢。
I'm writing a windows service application, which will be accessed through .NET Remoting.
The problem is I can't figure out how to access service objects from remotable class.
For example, I've a handler class:
class Service_console_handler
{
public int something_more = 20;
//some code...
TcpChannel serverChannel = new TcpChannel(9090);
ChannelServices.RegisterChannel(serverChannel);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(RemoteObject), "RemoteObject.rem",
WellKnownObjectMode.Singleton);
//from here on RemoteObject is accessible by clients.
//some more code doing something and preparing the data...
}
And I've a remotable class:
public class RemoteObject : MarshalByRefObject
{
private int something = 10;
public int Get_something()
{
return something;
}
}
Clients can access data in RemoteObect with no problem. But how can I access Service_console_handler
object (i.e. to retrieve useful info from something_more
)?
Sorry for dumb questions and thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您想要的是通过
RemoteObject
实例以某种方式访问ServiceConsoleHandler
实例,该实例对客户端可见。为此,您需要考虑两件事:(1) 控制
RemoteObject
实例的对象构造并使其可访问;(2) 修改ServiceConsoleHandler
以便它可以远程访问。(1)
如果不需要考虑远程处理,如何在
ServiceConsoleHandler
中构造RemoteObject
实例?我想你会做这样的事情:
如果你能让客户端可以访问这个对象,那就太好了。 您可以使用 RemotingServices.Marshal 而不是 RemotingConfiguration.RegisterWellKnownServiceType 来执行此操作:
(2)
如果您现在执行代码并在客户端代码中访问
remoteObject.Server
,您将得到一些远程异常,因为ServiceConsoleHandler
类无法远程访问。 因此,您需要添加[Serializable]
属性:原因:应远程访问的类型需要编组为某种特殊的可传输表示形式。 这样它们就可以通过 TCP 端口被挤压并通过 TCP 协议进行传输。 基本数据类型可以由框架封送,因此您不需要考虑它们。 对于自定义类型,您需要说明如何执行此操作。 实现此目的的一种方法是从
MarshalByRefObject
进行子类化。 这正是您已经使用RemoteObject
所做的事情。 另一种方法是将自定义类标记为[Serialized]
,如上所示。就是这样。 现在您应该能够在客户端代码中访问服务器的字段。 请注意,您不需要现有代码来激活对象:
对我来说,.NET 远程处理充满了有趣的惊喜和不眠之夜。 为了解决这个问题,请让自己熟悉远程概念(从我的角度来看,这些概念的记录很少)。 深入研究序列化概念(
MarshalByRefObject
与[Serialized]
)。 如果您想用它编写生产代码,请考虑处理远程异常的好方法。 还要考虑多线程。 可能有多个客户端同时使用该远程对象。玩得开心!
What you want is somehow to access the instance of
ServiceConsoleHandler
via aRemoteObject
instance, which is visible for the client.For this you need to consider two things: (1) Get control over the object construction of the
RemoteObject
instance and make it accessible and (2) modifyServiceConsoleHandler
so it can be accessed remotely.(1)
How would you construct a
RemoteObject
instance inServiceConsoleHandler
, if you don’t need to consider remoting?I guess you would do something like this:
It would be nice if you could make this object accessible for the client. You can do this by using RemotingServices.Marshal instead of RemotingConfiguration.RegisterWellKnownServiceType:
(2)
If you execute the code right now and access the
remoteObject.Server
in the client code you would get some remoting exception, because the classServiceConsoleHandler
cannot be accessed remotely. Therefore you need the add the[Serializable]
attribute:Reason: Types which should be accessed remotely, need to be marshaled to some special transferrable representation. This way they can be squeezed through the TCP port and transferred via the TCP protocol. Basic data types can by marshaled by the framework, so you don't need to think about them. For custom types you will need to state, how to do this. One way to do this is by subclassing from
MarshalByRefObject
. That’s exactly what you have already done withRemoteObject
. Another way is to mark your custom classes as[Serializable]
as shown above.That’s it. Now you should be able to access the server’s field in the client code. Note that you don’t need your existing code for object activation:
For me .NET remoting is full of funny surprises and sleepless nights. To counter this, make yourself familiar with the remoting concepts (which are from my point of view poorly documented). Dig into the serialization concept (
MarshalByRefObject
vs.[Serializable]
). If you want to make a production code out of it, think a very good ways to handle remoting exceptions. Also consider multithreading. There could be more than one client using this remote object at once.Have fun!
谢谢你! 我非常感谢您回答的彻底性和清晰度。
最奇怪的是我什至不知道你可以发布对象实例。 我研究了大约十几个简单的教程,建议将
RemotingConfiguration.RegisterWellKnownServiceType
作为进行远程处理的唯一方法。 愚蠢的我。现在远程处理对我来说看起来更有用。 我刚刚编写了一个快速测试应用程序并且它有效。 再次感谢。
Thank you! I very much appreciate thoroughness and clarity of you answer.
Most bizzare thing is that I didn't even know that you can publish object instance. About a dozen simple tutorials I studied proposed
RemotingConfiguration.RegisterWellKnownServiceType
as only method to do remoting. Stupid me.Now remoting looks much more useful to me. I just wrote a quick test application and it worked. Thanks again.