繁体   English   中英

.NET Remoting:如何从远程对象访问服务器应用程序对象?

[英].NET Remoting: how to access server application objects from remotable object?

我正在编写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检索有用的信息)?

抱歉,您的问题无聊,谢谢。

您需要通过某种方式通过客户端可见的RemoteObject实例访问ServiceConsoleHandler实例。

为此,您需要考虑两件事:(1)控制RemoteObject实例的对象构造并使其可访问;(2)修改ServiceConsoleHandler以便可以对其进行远程访问。

(1)

如果不需要考虑远程处理,如何在ServiceConsoleHandler构造一个RemoteObject实例?

我想你会做这样的事情:

class ServiceConsoleHandler
{
   …
   RemoteObject remoteObject = new RemoteObject();
   // now assume that you also already have
   // modified the RemoteObject class so it can hold
   // a reference to your server:
   remoteObject.Server = this;
   …
}

如果您可以使客户端可以访问此对象,那就太好了。 您可以使用RemotingServices.Marshal而不是RemotingConfiguration.RegisterWellKnownServiceType来做到这一点:

class ServiceConsoleHandler
{
     …
     TcpServerChannel channel = new TcpServerChannel(9090);
     ChannelServices.RegisterChannel(channel, true);
     RemoteObject remoteObject = new RemoteObject();
     remoteObject.Server = this;
     RemotingServices.Marshal(remoteObject, "RemoteObject.rem");
     …
}

(2)

如果您现在执行代码并在客户端代码中访问remoteObject.Server ,则将得到一些远程处理异常,因为无法远程访问ServiceConsoleHandler类。 因此,您需要添加[Serializable]属性:

[Serializable]
class ServiceConsoleHandler
{ … }

原因:应将应远程访问的类型编组为某些特殊的可传输表示形式。 这样,它们可以通过TCP端口进行压缩并通过TCP协议进行传输。 基本数据类型可以被框架封送,因此您无需考虑它们。 对于自定义类型,您将需要说明如何执行此操作。 一种实现方法是从MarshalByRefObject子类化。 这就是您已经使用RemoteObject完成的工作。 另一种方法是将自定义类标记为[Serializable]如上所示。

而已。 现在,您应该能够访问客户端代码中的服务器字段。 请注意,您不需要现有的代码即可激活对象:

        TcpClientChannel channel = new TcpClientChannel();
        ChannelServices.RegisterChannel(channel, true);

        RemoteObject remoteObject = (RemoteObject)Activator.GetObject(
            typeof(RemoteObject), "tcp://localhost:9090/RemoteObject.rem");

        Console.WriteLine(remoteObject.Server.SomethingMore);

对我来说,.NET远程处理充满有趣的惊喜和不眠之夜。 为了解决这个问题,请使自己熟悉远程处理概念(从我的角度来看,文献记载不充分)。 研究序列化概念( MarshalByRefObject[Serializable] )。 如果要使用它制作生产代码,请考虑一种处理远程处理异常的好方法。 还考虑多线程。 一次可能有多个客户端使用此远程对象。

玩得开心!

谢谢! 我非常感谢您回答的透彻和清晰。

最可笑的是,我什至不知道您可以发布对象实例。 我研究了大约十二个简单的教程,提出了RemotingConfiguration.RegisterWellKnownServiceType作为唯一的远程处理方法。 愚蠢的我。

现在,远程处理对我来说更有用。 我刚刚编写了一个快速测试应用程序,它起作用了。 再次感谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM