想了好久,语言表达能力还是不行,想写点关于.NET Remoting的理论知识,水平还是不够。
虽然自己能看懂别人的文章,但是自己理解的不够深刻,所以只能给个网址和自己写的例子,例子我会详细的讲解。
详细的理论http://www.codesky.net/article/doc/200803/2008032665782082.htm。
看例子之前我要说两句,对初涉此道的人希望有些帮助,当初学习这个Remoting真是又爱又恨,到网上搜索,绝大多数是废话而且看起来很是费力。什么COM、DCOM了、跟webservice的区别了等等,云里雾里的,我就是要了解一下remoting,其他的什么webservice可以等我会用remoting了再讲也不迟啊,这儿抄一点那儿抄一点就是一篇文章了,讲的有水平但是不实用。
上面发泄了一下,下面谈谈我刚开始的疑惑以及自己的理解:
1、客户端、服务端、远程对象
理解了这3个什么都好办,客户端:说白了就是自己正在使用的机器(这样解释可能不专业或者有局限,但是权且这样理解)。远程对象:就是一个与客户端程序不在同一个程序域、电脑等等(这里权且理解为在另一台电脑上的用C#写的类)。服务端:就是跟远程对象在同一机器上的自己写的程序。
那么这个remoting有啥用呢?我按照自己的理解讲了:就是把一部分功能在另外的机器上实现,差不多所谓的分布式应用啊(这个解释可能有局限,我也是刚涉入不久)。
好了,上面这样讲够白了吧,有人再不明白我就无语了。
下面的例子中我就将客户端代码在自己的机器上运行,远程对象类和服务端代码写在192.168.0.72(别人的机器,嘿嘿)机器上。
例子:
序:我用了两台电脑进行操作,我很实在,一台电脑我看不出什么效果,所以就老老实实的用了两台。
服务端的IP为:192.168.0.72
客户端的IP为:192.168.0.40
客户端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace Wrox.ProCSharp.Remoting
{
public class HelloClient
{
[STAThread]
public static void Main(string[] args)
{
//想信道服务注册信道,remoting通信时基于信道的,没有信道怎么交互
ChannelServices.RegisterChannel(new TcpClientChannel());
//就是获得远程对象的代理,远程对象就是远程对象代码中的hello类,8086端口要与服务端的端口一致
Hello obj = (Hello)Activator.GetObject(typeof(Hello), "tcp://192.168.0.72:8086/Hi");
if (obj == null)
{
Console.WriteLine("could not locate server");
return;
}
for (int i = 0; i < 5; i++)
{
//obj.Greeting("Christian")调用的是远程对象的Hello类的Greeting方法。你可以在服务端设置断点,保证会执行到得。
//这里可以看出来remoting的好处吧,具体方法在服务端执行,利用服务端的资源。
Console.WriteLine(obj.Greeting("Christian"));
}
}
}
}
服务端代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using Wrox.ProCSharp.Remoting;
namespace Wrox.ProCharp.Remoting
{
public class HelloServer
{
[STAThread]
public static void Main(string[] args)
{
//用8086 端口创建一个基于TCP协议的ServerChannel对象;
TcpServerChannel channel = new TcpServerChannel(8086);
//该信道使用ChannelServices 注册,使之可用于远程对象,并禁用安全性;
ChannelServices.RegisterChannel(channel,false);
// 通过使用给定的参数初始化 System.Runtime.Remoting.WellKnownServiceTypeEntry 的新实例,将服务端上的对象Hello 注册为已知类型。
//当然了可以是Singleton模式,具体的看上面的理论链接,这里不详细讲了。
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Hello), "Hi",
WellKnownObjectMode.SingleCall);
System.Console.WriteLine("hit to exit");
System.Console.ReadLine();
}
}
}
远程对象代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace Wrox.ProCSharp.Remoting
{
//远程对象派生自System.marshalByRefObject类
public class Hello : System.MarshalByRefObject
{
public Hello()
{
//
// TODO: 在此处添加构造函数逻辑
//
Console.WriteLine("Constructor called");
}
~Hello()
{
Console.WriteLine("Destructor called");
}
public string Greeting(string name)
{
Console.WriteLine("Greeting called");
// return "Hello," + name;
return GetMessage();
}
public string GetMessage()
{
StreamReader sr = null;
string line = string.Empty;
try
{
FileStream DataStream = new FileStream
//System.AppDomain.CurrentDomain.BaseDirectory就是exe文件所在的目录,默认是debug目录
//我在debug目录下建了ServerTest.txt。当然了这段代码是写在服务端的,所以路径是服务端的某个路径。
(System.AppDomain.CurrentDomain.BaseDirectory+"ServerTest.txt", FileMode.Open);
sr = new StreamReader(DataStream,Encoding.Default);
line = sr.ReadLine();
sr.Close();
}
catch (Exception ex)
{
line = "找不到文件";
}
finally
{
if (sr != null)
{
sr.Close();
}
}
return line;
}
}
}
当然了上面讲的很简单,但是可以基本知道remoting是怎么一回事,基本上怎么使用。
上面代码运行时,先启动服务端,然后启动客户端即可。
上面讲的比较简单,但是初衷就是希望大家能快速入门,讲的复杂就会违背写这篇文章的初衷。
如有错误之处还请大家指出,一起学习。