我对Remoting的一点点理解,附简单示例入门篇

来源:互联网 发布:永久域名发布器电影 编辑:程序博客网 时间:2024/06/05 20:58

今天闲来无事,就把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);            }        }           }}


正个流程就是我们开启服务器,服务端已订阅事件,等待一个事件的触发,这时刚好客户端启动后,触发了这个事件,来完成两个进程间的合作关系。好了,如果大家对remoting感兴趣的话,可以深入的去理解。

 

还有,我要提一下的是,或许有人会不知道怎么同时启动2个项目,这里呢,我们先将服务端项目设为启动项目,启动服务端后,我们右击客户端项目=>调试=>启动新实例,这时客户端就启动了。