前言
今天在整理以前写的一些demo,看到一个关于remoting的例子。好久不用remoting了,果断记录一下。
什么是Remoting
简单回顾下:
1.Remoting是一种远程通信,或者说跨应用程序(域)通信的技术,在C/S架构的程序中应用较多。
2.支持协议:TCP和HTTP。
3.激活方式:服务器端激活(WellKnow)和客户端激活。其中服务端激活又包含了SingleTon模式和SingleCall模式
HelloRemoting示例
一个完整的远程通信程序基本上包括以下几部分:
1.定义远程对象。Remoting传递的对象是以引用的方式,因此所传递的远程对象类必须继承MarshalByRefObject;
2.服务端,主要是注册通道、注册远程对象、注销通道;
3.客户端,主要完成注册通道、获取远程对象。
第一步:
创建一个solution(HelloRemoting.sln)。然后按照上面描述的分别建立三个project:RemoteClient,RemoteObject,RemoteServer,如下图所示:
说明:我这里的使用的VS2008创建的,其中Client和Server是Winform程序,RemoteObject是类库。
第二步:
定义远程对象。Remoting的远程对象必须继承自:MarshalByRefObject。我们这里创建一个HelloRemote类,包含有求和运算。
View Source /// <summary>/// 建立远程调用对象/// </summary>public class HelloRemote:MarshalByRefObject{public HelloRemote(){//构造函数}~HelloRemote(){ //析构函数}/// <summary>/// 求两数和/// </summary>/// <param name="a"></param>/// <param name="b"></param>/// <returns>和</returns>public int Sum(int a, int b){return a + b;}}
第三步:
创建服务,注册通道、远程对象。本示例使用服务端激活,TCP通道注册远程对象。具体如下:添加一个Form窗体,简单设置UI如下:
分别添加启动服务和关闭服务的按钮点击事件。代码如下(代码中已经有详细注释):我们把服务注册到10086端口上
View Source/// <summary>/// 启动服务/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnStartUp_Click(object sender, EventArgs e){try{//创建一个TCP通道TcpServerChannel channel = new TcpServerChannel(10086);//注册通道ChannelServices.RegisterChannel(channel);//使用WellKnown激活方式中的SingleCall模式注册远程对象RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteObject.HelloRemote), "HelloRemote", WellKnownObjectMode.SingleCall);MessageBox.Show("启动成功", "提示");lblMsg.Text = "(服务已启动)";this.btnStartUp.Visible = false;//启动服务后隐藏启动按钮btnClose.Visible = true;//显示关闭服务按钮}catch (Exception ex){MessageBox.Show(ex.ToString(), "提示");}}/// <summary>/// 关闭服务/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnClose_Click(object sender, EventArgs e){//获取当前已注册的通道IChannel[] registeredChannels = ChannelServices.RegisteredChannels;if (registeredChannels == null || registeredChannels.Length <= 0){MessageBox.Show("没有注册任何通道!", "提示");return;}foreach (IChannel channel in registeredChannels){//循环已经注册的通道if (channel.ChannelName.ToLower() == "tcp"){TcpServerChannel tcpchannel = (TcpServerChannel)channel;tcpchannel.StopListening(null);//关闭监听ChannelServices.UnregisterChannel(tcpchannel);//注销通道MessageBox.Show("服务关闭成功!", "提示");btnClose.Visible = false;btnStartUp.Visible = true;}}}
第四步:
创建客户端(Client),获取远程对象。同Server一样,在RemoteClient中添加一个Form如下:
在【点击计算】按钮上添加点击事件,完成注册通道,获取远程对象,以及调用远程对象计算并返回结果。代码如下:
View Source/// <summary>/// 计算两数的和/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSumbit_Click(object sender, EventArgs e){//获取远程对象其实是创建一个远程对象在客户端的代理HelloRemote obj = (HelloRemote)Activator.GetObject(typeof(HelloRemote), "tcp://localhost:10086/HelloRemote");if (obj == null){Console.WriteLine("Could not local Server");return;}try{//获取需要就算得两个数并转化为int型int firNum = Convert.ToInt32(txtFirst.Text.Trim());int secNum = Convert.ToInt32(txtSecond.Text.Trim());//调用远程对象int sum = obj.Sum(firNum, secNum);txtResult.Text = sum.ToString();}catch (Exception ex){MessageBox.Show(ex.ToString(), "提示");}}
通过上面的几步我们就创建了一个远程通信的示例,我们看一下运行结果,分别启动Server和Client,并输入10,20点击提交:
服务端:
客户端:
结果为30,说明我们成功的创建了一个使用Remoting的分布式应用程序。
源码如下:HelloRemoting.rar