C#用MarshalByRefObject实现远程访问遇到的问题,求高手!!!!(高分急救)

llsus 2013-11-20 10:13:13
服务端代码

//测试用的类
[Serializable]
public class c1
{ //获取本机时间
public string gettime()
{
return DateTime.Now.ToString();
}
}

//远程对象类
public class testRemoteServer : MarshalByRefObject
{
public string gettime()
{ //返回系统时间
return DateTime.Now.ToString();
}

public c1 TestC = new c1();
}




客户端代码

testRemoteServer tr= (testRemoteServer )System.Activator.GetObject(typeof(testRemoteServer ), "tcp://192.168.001.031:4001/testRemoteServer ");
MessageBox.Show("MarshalByRefObject的成员getTime返回:" +tr.gettime ()+"\r\nMarshalByRefObject的成员c1的方法gettime返回:" + tr.TestC.gettime ());



出现的问题:tr.gettime()返回的是服务器的时间
tr.Testc.gettime() 返回的是客户机时间

请教高手,这是什么原因?我需要tr.Testc.gettime执行远程的方法,而不是本地,怎么解决?
...全文
536 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lordard 2013-11-20
  • 打赏
  • 举报
回复
在服务器端做一个API,专门回传服务器的时间〜 应该比较单纯吧
llsus 2013-11-20
  • 打赏
  • 举报
回复
看完了,没提我遇到的问题,有谁能帮忙? 我不是不知道怎么获得远程对象,远程对象的方法确实是在远程执行的,但是远程对象属性的方法却是在本地执行的。
llsus 2013-11-20
  • 打赏
  • 举报
回复
我才看了一半,不过,文章讲是教我怎么在客户端获得“MarshalByRefObject”对象,而我的问题不是获取不到MarshalByRefObject对象,而是获得的MarshalByRefObject对象的属性(也是一个对象)的方法执行的是本地的,不是远程的,也许后面会讲到,我继续看下去。不明白再来问。
wyufen 2013-11-20
  • 打赏
  • 举报
回复
http://www.cnblogs.com/wayfarer/archive/2004/08/05/30437.html
llsus 2013-11-20
  • 打赏
  • 举报
回复
谢谢,我先看下你提供文章,否则好多我还不懂。
  • 打赏
  • 举报
回复
System.Activator.GetObject() 呼叫 Proxy 来传送讯息至远程对象。 没有任何信息会经网络传送,直到在 Proxy 上呼叫某一方法。
  • 打赏
  • 举报
回复
你用反射创建的实例(只不过命名空间是远程的)是存储在本地的,代码也是运行在本地的,自然是客户端时间 你可以查一下Remoting资料,或者直接用wcf更省事 TcpChannel channel = new TcpChannel(端口号,序列化提供者); ChannelServices.RegisterChannel(channel); http://www.cnblogs.com/wayfarer/archive/2004/08/05/30437.html
llsus 2013-11-20
  • 打赏
  • 举报
回复
谢谢各位,在各位的启发下,我把问题解决了。 客户端和服务端一句代码也不用改,服务端的MarshalByRefObject分配信道,提供远程对象,类库的每个类也都必须继承自MarshalByRefObject,如果不继承,tr.Testc.gettime()就在本地执行,继承了,tr.Testc.gettime()就在服务端执行。原来这么简单就解决了,困扰了我两天。gomoku 的一句提醒了我。谢谢。
llsus 2013-11-20
  • 打赏
  • 举报
回复
另外,如果c1不能继承自MarshalByRefObject,你也可以在testRemoteServer中添加一个方法,在该方法中调用return this.TestC.gettime(); ------------------------------------------------------------- 这个我试过了,依然执行的本地代码,并非远程的。而且我用WCF也试过,你看上面的WCF例子就是你说的这样的,也是执行本地代码。
loveASUS 2013-11-20
  • 打赏
  • 举报
回复
不会,帮你顶一下
gomoku 2013-11-20
  • 打赏
  • 举报
回复
并不需要每个类分配通讯通道。但要远程执行,需要MarshalByRefObject:

public class c1 : MarshalByRefObject //<--
{   //获取本机时间
    public string gettime()
    {
        return DateTime.Now.ToString();
    }
    public string Test()
    {
        return AppDomain.CurrentDomain.FriendlyName;
    }
}

void Test()
{
    AppDomain domain = AppDomain.CreateDomain("hello new domain");
    testRemoteServer proxy = (testRemoteServer)domain.CreateInstanceAndUnwrap(typeof(testRemoteServer).Assembly.FullName, typeof(testRemoteServer).FullName);
    string s = proxy.TestC.gettime();  // <-- "hello new domain"
}
另外,如果c1不能继承自MarshalByRefObject,你也可以在testRemoteServer中添加一个方法,在该方法中调用return this.TestC.gettime();
tcmakebest 2013-11-20
  • 打赏
  • 举报
回复
如果要在服务端运行代码,肯定有进程的吧,那段代码是在哪里执行呢
灬浪子灬 2013-11-20
  • 打赏
  • 举报
回复
引用 1 楼 dongxinxi 的回复:
你用反射创建的实例(只不过命名空间是远程的)是存储在本地的,代码也是运行在本地的,自然是客户端时间 你可以查一下Remoting资料,或者直接用wcf更省事 TcpChannel channel = new TcpChannel(端口号,序列化提供者); ChannelServices.RegisterChannel(channel); http://www.cnblogs.com/wayfarer/archive/2004/08/05/30437.html
+1
llsus 2013-11-20
  • 打赏
  • 举报
回复
那看来是做不到了。如果每个类都继承MarshalByRefObject,分配通讯通道,在客户端单独创建,我就不需要来问了,也失去了意义。
gomoku 2013-11-20
  • 打赏
  • 举报
回复
要在远程端运行,那么class c1必须是MarshalByRefObject。 如果它只是Serializable,那么远程端传递c1时,把c1办成字节流进行传输,本地端在把字节流生成c1实例(该实例生存在本地端)。c1是本地实例,因此任何运行c1的方法的发生在本地。
llsus 2013-11-20
  • 打赏
  • 举报
回复
是不是根本就做不到啊?我用WCF去做了一次,第二层的方法一样是执行的本地的代码 WCF用的通道用接口,而接口不允许有属性,我用一个方法来返回一个对象,然后在本地调用这个对象的方法,还是执行的本地代码。 服务端代码

        [ServiceContract]
        public interface IHello
        {
            [OperationContract]
            string gettime();

            [OperationContract]
            c1 testc();
        }


        public class HelloWorld : IHello
        {
            public string  gettime()
            {
                   return DateTime.Now.ToString();
            }

            public c1 testc()
            {
                return new c1();
            }
        }

        public class c1
        {
            public string gettime()
            {
                return DateTime.Now.ToString();
            }
        }
客户端代码

       [ServiceContract]
        public interface IHello
        {
            [OperationContract]
            string gettime();

            [OperationContract]
            c1 testc();
        }

        public class c1
        {
            public string gettime()
            {
                return "本地";
            }
        }


void main()
{
           ServiceEndpoint httpEndpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(IHello))
                                         , new BasicHttpBinding(), new EndpointAddress(@"http://localhost:4002/HelloService/Svc"));

            using (ChannelFactory<IHello> factory = new ChannelFactory<IHello>(httpEndpoint))
            {

                IHello service = factory.CreateChannel();
                MessageBox.Show(service.gettime());
                MessageBox.Show(service.testc().gettime());

}

111,094

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧