当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《.NETRemoting:如何从远程对象访问服务器应用程序对象?》经验,为你挑选了1个好方法。

我正在编写一个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)?

抱歉愚蠢的问题,并提前感谢.



1> Theo Lenndor..:

您想要的是以某种方式ServiceConsoleHandler通过RemoteObject实例访问实例,该实例对于客户端是可见的.

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

(1)

如果您不需要考虑远程处理,您将如何构建RemoteObject实例ServiceConsoleHandler

我想你会做这样的事情:

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远程处理充满了有趣的惊喜和不眠之夜.为了解决这个问题,请熟悉远程处理概念(从我的角度来看,这些概念很难记录).深入研究序列化概念(MarshalByRefObjectvs. [Serializable]).如果您想从中制作生产代码,请考虑一种处理远程异常的非常好的方法.还要考虑多线程.可能有多个客户端同时使用此远程对象.

玩得开心!

推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有