求个remoting 思路
今天才开始看remoting 感觉好抽象。
要求能调用另一台电脑上的程序或进程。
请问有没好的思路啊?
或者有好的代码等就感激不尽...
代码:liuhui2082@163.com 并请留言说明下 谢谢
[解决办法]
http://blog.csdn.net/winderxp/archive/2007/04/13/1562963.aspx
[解决办法]
帮LZ顶 给点分把
[解决办法]
微软webcast 系列 课程 Remoting
http://www.msdnwebcast.com.cn/CourseSeries.aspx?id=57
[解决办法]
学习ing..
[解决办法]
其实就是winSocket了。
[解决办法]
帮LZ顶
[解决办法]
RemotingServices
通过使用类 RemotingServices 提供的方法,我们可以很轻松实现这些目标。
Marshal: 用于将 MarshalByRefObject 转换为 ObjRef 类的实例。
Connect:客户端可以用该方法创建远程代理对象的实例。
Disconnect:断开服务器远程对象与信道的连接。客户端代理在断开后调用任何方法都会触发 RemotingException。
Unmarshal:接受 ObjRef 并从它创建一个客户端代理对象。这个方法很少被使用,因为多数情况下我们并不会直接将 ObjRef 显示传递给客户端,而是交由 Remoting 基础结构来处理。
ObjRef
ObjRef 是远程对象的可序列化表示,用于跨应用程序域边界传输对象引用。为对象创建 ObjRef 称为封送。可以通过信道将 ObjRef 传输到另一个应用程序域(可能在另一个进程或计算机上)。达到其他应用程序域后,需立即分析 ObjRef,以便为该对象创建一个代理(通常连接到实际的对象)。此操作称为拆收处理 (Unmarshaling)。在拆收处理过程中,分析 ObjRef 以提取远程对象的方法信息,并创建透明代理和 RealProxy 对象。在透明代理注册到公共语言运行库之前,将已分析的 ObjRef 的内容添加到透明代理中。
ObjRef 包含:描述所封送对象的 Type 和类的信息,唯一标识特定对象实例的 URI,以及有关如何到达对象所在的远程处理分支的相关通信信息。
--------------------------------------------
实现已知对象:
1.构建服务器端:
(1)添加对System.Runtime.Remoting.dll
(2)实现一个派生自MarshalByRefObject的类
(3)选择一种可用的通道,TCP,HTTP,然后用ChannelServices.RegisterChannel()方法注册此通道
(4)用RemotingConfiguration.RegisterWellKnownServiceType()方法把这个类注册为已知对象
(5)保持服务器处于激活态
首先是继承了MarshalByRefObject的类:
using System;
namespace MathLibrary
{
/**//// <summary>
/// SimpleMath 的摘要说明。
/// </summary>
public class SimpleMath:MarshalByRefObject
{
public SimpleMath()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public int Add(int a ,int b)
{
Console.WriteLine( "SimpleMath.Add({0},{1}) ",a,b);
return a+b;
}
public int Subtract(int a, int b)
{
Console.WriteLine( "SimpleMath.Subtract({0},{1}) ",a,b);
return a-b;
}
}
}
接着构建服务器端:
1using System;
2using System.Runtime.Remoting;
3using System.Runtime.Remoting.Channels;
4using System.Runtime.Remoting.Channels.Http;
5using MathLibrary;
6
7namespace MathServer
8{
9 /**//// <summary>
10 /// ServerMain 的摘要说明。
11 /// </summary>
12 public class ServerMain
13 {
14 public ServerMain()
15 {
16 //
17 // TODO: 在此处添加构造函数逻辑
18 //
19 }
20 public static void Main(string[] args)
21 {
22 //建立一个通道并指定段口号
23 HttpChannel channel = new HttpChannel(13101);
24 //通过运行时的远程服务来注册通道
25 ChannelServices.RegisterChannel(channel);
26 //注册被调用类为已知对象well-know
27 RemotingConfiguration.RegisterWellKnownServiceType(
28 typeof(MathLibrary.SimpleMath),//被注册的类
29 "MyURI.soap ", //已知对象名称Well-Know Name
30 WellKnownObjectMode.Singleton); //被调用模式Singleton 或者 SingleCall
31
32 Console.WriteLine( "Server started.Press Enter to End! ");
33 Console.ReadLine();
34 }
35 }
36}
然后构建客户端,注意代码注释:
需要知道如下信息:服务器机器名,通道类型,端口,分配给远程对象的URI
(1)添加引用如下所示
(2)添加对程序集的引用,本例中为MathLibrary.dll
(3)使用与服务器相同的通道类型注册一个通道,本例中为HTTP
(4)调用Activator.GetObject()方法,传递合适的URL以取得一个远程对象的代理
(5)找代理强制转换成合适的类型,并把他当真实对象使用
1 using System;
2 using System.Runtime.Remoting;
3 using System.Runtime.Remoting.Channels;
4 using System.Runtime.Remoting.Channels.Http;
5 using MathLibrary;
6 namespace MathClient
7 {
8 /// <summary>
9 /// ClientMain 的摘要说明。
10 /// </summary>
11 public class ClientMain
12 {
13 public ClientMain()
14 {
15 //
16 // TODO: 在此处添加构造函数逻辑
17 //
18 }
19 public static void Main(string[] args)
20 {
21 //创建并注册通道,没有指定段口号,所以不能接受消息
22 HttpChannel channel = new HttpChannel();
23 ChannelServices.RegisterChannel(channel);
24
25 //获取远程对象的一个代理
26 Object remoteObj = Activator.GetObject(typeof(MathLibrary.SimpleMath), "Http://localhost:13101/MyURI.soap ");
27 //将代理转换为所需要的类
28 SimpleMath math1 = (SimpleMath)remoteObj;
29
30 //方法2
31 SimpleMath math2 = (SimpleMath)RemotingServices.Connect(
32 typeof(MathLibrary.SimpleMath),
33 "Http://localhost:13101/MyURI.soap "
34 );
35 //方法3
36 RemotingConfiguration.RegisterWellKnownClientType(
37 typeof(MathLibrary.SimpleMath),
38 "Http://localhost:13101/MyURI.soap "
39 );
40 SimpleMath math3 = new SimpleMath();
41
42
43
44 Console.WriteLine( "5+2={0} ",math3.Add(5,2));
45 Console.WriteLine( "5-2={0} ",math3.Subtract(5,2));
46 Console.WriteLine( "Press enter to End ");
47 Console.ReadLine();
48 }
49 }
50 }
[解决办法]
RemotingServices
通过使用类 RemotingServices 提供的方法,我们可以很轻松实现这些目标。
Marshal: 用于将 MarshalByRefObject 转换为 ObjRef 类的实例。
Connect:客户端可以用该方法创建远程代理对象的实例。
Disconnect:断开服务器远程对象与信道的连接。客户端代理在断开后调用任何方法都会触发 RemotingException。
Unmarshal:接受 ObjRef 并从它创建一个客户端代理对象。这个方法很少被使用,因为多数情况下我们并不会直接将 ObjRef 显示传递给客户端,而是交由 Remoting 基础结构来处理。
ObjRef
ObjRef 是远程对象的可序列化表示,用于跨应用程序域边界传输对象引用。为对象创建 ObjRef 称为封送。可以通过信道将 ObjRef 传输到另一个应用程序域(可能在另一个进程或计算机上)。达到其他应用程序域后,需立即分析 ObjRef,以便为该对象创建一个代理(通常连接到实际的对象)。此操作称为拆收处理 (Unmarshaling)。在拆收处理过程中,分析 ObjRef 以提取远程对象的方法信息,并创建透明代理和 RealProxy 对象。在透明代理注册到公共语言运行库之前,将已分析的 ObjRef 的内容添加到透明代理中。
ObjRef 包含:描述所封送对象的 Type 和类的信息,唯一标识特定对象实例的 URI,以及有关如何到达对象所在的远程处理分支的相关通信信息。
--------------------------------------------
实现已知对象:
1.构建服务器端:
(1)添加对System.Runtime.Remoting.dll
(2)实现一个派生自MarshalByRefObject的类
(3)选择一种可用的通道,TCP,HTTP,然后用ChannelServices.RegisterChannel()方法注册此通道
(4)用RemotingConfiguration.RegisterWellKnownServiceType()方法把这个类注册为已知对象
(5)保持服务器处于激活态
首先是继承了MarshalByRefObject的类:
using System;
namespace MathLibrary
{
/**//// <summary>
/// SimpleMath 的摘要说明。
/// </summary>
public class SimpleMath:MarshalByRefObject
{
public SimpleMath()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public int Add(int a ,int b)
{
Console.WriteLine( "SimpleMath.Add({0},{1}) ",a,b);
return a+b;
}
public int Subtract(int a, int b)
{
Console.WriteLine( "SimpleMath.Subtract({0},{1}) ",a,b);
return a-b;
}
}
}
接着构建服务器端:
1using System;
2using System.Runtime.Remoting;
3using System.Runtime.Remoting.Channels;
4using System.Runtime.Remoting.Channels.Http;
5using MathLibrary;
6
7namespace MathServer
8{
9 /**//// <summary>
10 /// ServerMain 的摘要说明。
11 /// </summary>
12 public class ServerMain
13 {
14 public ServerMain()
15 {
16 //
17 // TODO: 在此处添加构造函数逻辑
18 //
19 }
20 public static void Main(string[] args)
21 {
22 //建立一个通道并指定段口号
23 HttpChannel channel = new HttpChannel(13101);
24 //通过运行时的远程服务来注册通道
25 ChannelServices.RegisterChannel(channel);
26 //注册被调用类为已知对象well-know
27 RemotingConfiguration.RegisterWellKnownServiceType(
28 typeof(MathLibrary.SimpleMath),//被注册的类
29 "MyURI.soap ", //已知对象名称Well-Know Name
30 WellKnownObjectMode.Singleton); //被调用模式Singleton 或者 SingleCall
31
32 Console.WriteLine( "Server started.Press Enter to End! ");
33 Console.ReadLine();
34 }
35 }
36}
然后构建客户端,注意代码注释:
需要知道如下信息:服务器机器名,通道类型,端口,分配给远程对象的URI
(1)添加引用如下所示
(2)添加对程序集的引用,本例中为MathLibrary.dll
(3)使用与服务器相同的通道类型注册一个通道,本例中为HTTP
(4)调用Activator.GetObject()方法,传递合适的URL以取得一个远程对象的代理
(5)找代理强制转换成合适的类型,并把他当真实对象使用
1 using System;
2 using System.Runtime.Remoting;
3 using System.Runtime.Remoting.Channels;
4 using System.Runtime.Remoting.Channels.Http;
5 using MathLibrary;
6 namespace MathClient
7 {
8 /// <summary>
9 /// ClientMain 的摘要说明。
10 /// </summary>
11 public class ClientMain
12 {
13 public ClientMain()
14 {
15 //
16 // TODO: 在此处添加构造函数逻辑
17 //
18 }
19 public static void Main(string[] args)
20 {
21 //创建并注册通道,没有指定段口号,所以不能接受消息
22 HttpChannel channel = new HttpChannel();
23 ChannelServices.RegisterChannel(channel);
24
25 //获取远程对象的一个代理
26 Object remoteObj = Activator.GetObject(typeof(MathLibrary.SimpleMath), "Http://localhost:13101/MyURI.soap ");
27 //将代理转换为所需要的类
28 SimpleMath math1 = (SimpleMath)remoteObj;
29
30 //方法2
31 SimpleMath math2 = (SimpleMath)RemotingServices.Connect(
32 typeof(MathLibrary.SimpleMath),
33 "Http://localhost:13101/MyURI.soap "
34 );
35 //方法3
36 RemotingConfiguration.RegisterWellKnownClientType(
37 typeof(MathLibrary.SimpleMath),
38 "Http://localhost:13101/MyURI.soap "
39 );
40 SimpleMath math3 = new SimpleMath();
41
42
43
44 Console.WriteLine( "5+2={0} ",math3.Add(5,2));
45 Console.WriteLine( "5-2={0} ",math3.Subtract(5,2));
46 Console.WriteLine( "Press enter to End ");
47 Console.ReadLine();
48 }
49 }
50 }
[解决办法]
热心群众真多,看的头都晕了。
[解决办法]
说白了就是
1:在服务器上有一个对象A,带一个方法A.FUNCTION();
2:客户机注册了服务器这个对象A,那么.NET就在客户机上通过A的元数据创建一个客户端代理对象a
3:客户机想执行服务器上的A.FUNCTION(),于是调用A.FUNCTION(),实际是调用本机(客户机)对象a.Function()
4:.NET自动把a获取的信息通过SOAP协议传递给A(a是A的代理么),于是服务器上的A就执行了A.Function()
5:
[解决办法]
5:客户机对服务器上A的操作,其实都是先反应到客户机上a的操作,然后由A所在类的代理机制,自动传递到服务器上的A对象
如此而已...