我对Remoting的一点点理解,附简单示例入门篇
今天闲来无事,就把remoting研究了下,之前也接触过,对remoting也有一点点的了解,只是没怎么去深究过,今天我通过我对remoting的一点点理解,给刚接触remoting的学友们介绍下remoting到底是什么,怎么去用,在什么场合去用。 remoting的工作原理:就是服务端向客户端发送一个进程编号,一个程序域编号,以确定对象的位置。一般用在2个或2个以上的进程中,也就是所谓的跨程序来执行项目,类型webservice。 接下来,我就把我做得一个简单示例讲解下,如何去实现remoting。这个示例主要实现的是"当前时间自动更新"。 ? 先看看效果图: 整个程序,我新建了2个项目,一个是服务端项目RemotingDemo,另一个是客户端项目RemotingCustom。 我们第一步先在服务端新建一个Message类,因为这个类起着关键性的作用。 代码中用的是委托和事件,相信大家都能理解。 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace RemotingDemo { //将定义的message类继承MarshalByRefObject,主要是因为继承此类的对象可以跨越应用程序域边界被引用,甚至被远程引用。远程调用时,将产生一个远程对象在本地的透明代理,通过此代理来进行远程调用。 public class Message:MarshalByRefObject { public delegate void DeleHanlder(string time); public static event DeleHanlder getCurrentTime; public void CurrentTime(string time) { if (getCurrentTime != null) { getCurrentTime(time); } } } } 好了,第一步已经完成。 接下来我们先部署服务端 服务端: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.Remoting.Channels.Http; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting; using System.Threading; namespace RemotingDemo { public partial class Form1 : Form { public Form1() { InitializeComponent(); } /// <summary> /// 开启服务端 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender,EventArgs e) { //首先要先添加System.Runtime.Remoting的引用,不然不能使用Remoting相关的指令 HttpChannel channel = new HttpChannel(3000);//给3000端口指定通道 ChannelServices.RegisterChannel(channel,false);//注册通道 RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingDemo.Message),"Message",WellKnownObjectMode.SingleCall);//激活通道,通常激活通道的方式有2种:SingleCall和Singleton;前者是每个传入的消息是由新的对象提供服务,后者则是每个传入的消息由同一个对象提供服务,两者是有差别的。比如:我实现一个i不断自加,如果我用前者,则每次返回的都是从头开始的数,如果是用后者,则i不断的自加,区别就在这里 button1.Enabled = false; RemotingDemo.Message.getCurrentTime += new Message.DeleHanlder(Message_getCurrentTime);//服务端通道已经激活,我们这时就可以订阅事件来实现相应操作的效果 } void Message_getCurrentTime(string time) { //下面这段代码对于多线程不太了解的人来说,可能不好理解,这里我就先简单的阐述下,如果不使用invoke的话,会报子线程不能直接访问主线程UI的异常,简单点来说就是不具备使用它的权限,需要使用权限。还有"=>"这个写法是Lambda表达式,大家不了解的可以去网上查看,我就不再复述了 if (this.InvokeRequired) { this.Invoke(new MethodInvoker(() => { textBox1.Text = time; })); } else { textBox1.Text = time; } } } } 客户端: using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels.Http;
using System.Threading;
namespace RemotingCustom
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender,EventArgs e)
{
HttpChannel channel = new HttpChannel();//不需要指定端口
ChannelServices.RegisterChannel(channel,false);//注册通道
RemotingConfiguration.RegisterWellKnownClientType(typeof(RemotingDemo.Message),"http://localhost:3000/Message");//客户端指定的url,以便于发送信息
RemotingDemo.Message msg = new RemotingDemo.Message();
while (true)
{
msg.CurrentTime(DateTime.Now.ToString("HH:mm:ss"));
Thread.Sleep(1000);
}
}
}
}
? 还有,我要提一下的是,或许有人会不知道怎么同时启动2个项目,这里呢,我们先将服务端项目设为启动项目,启动服务端后,我们右击客户端项目=>调试=>启动新实例,这时客户端就启动了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |