您的位置:首页 > 编程语言 > C#

C#采用Remoting实现跨进程调用之代码实例

2012-12-31 15:31 831 查看
前言 

辛苦了几个月,期间第一次接触C#的东西,一直很忙碌,如今年底将至,停车场系统目前也即将交货,回顾自己在该系统中所实现的功能,开发过程中遇到的技术点滴,觉得有必要认真记录一下,以便日后翻阅。故以C#中通过Remoting跨进程调用为例,为该系统做个小结。

博客之前有一篇针对C#
跨进程调用的文章,但这些都是网上搜集,原创成分太少,故为此补一篇原创文章,以下代码均为自己结合系统中需要,自己做的小demo,以便初学者更好理解跨进程调用的思想。

1. 新建解决方案,该解决方案中有三个工程,分别是Client(客户端),IRpcAdapter(Server端函数接口),Server(服务端)。

2.
该解决方案中的Client工程和Server工程均为独立的C#可执行程序,IRpcAdapter为类库。
       

3. Client工程

注:该工程中只有Form的frmClient类代码,同时需引入系统的Remoting命名空间和自定义的外部类库IRpcAdapter命名空间。

frmClient.cs代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting;
namespace Client
{
    ///<summary>
    ///拍照程序
    ///</summary>
    publicpartial
class frmClient :
Form
    {
        public frmClient()
        {
            InitializeComponent();
        }
        //图片全路径
        string argImgPath =@"c:\\images\test.jpg";
        //端口号
        staticstring argPort =
"01";
        //拍摄时间
        staticDateTime argSnapShotTime =
DateTime.Now;
        ///<summary>
        ///测试
        ///</summary>
        ///<param name="sender"></param>
        ///<param name="e"></param>
        privatevoid btnTest_Click(object sender,EventArgs e)
        {
           
/********************************************/
           
/*                拍照处理                 */
            /********************************************/ 
           
//调用识别程序
           
string plateNo = this.RegisteClientChannel(argImgPath, argPort, argSnapShotTime);
        }
        ///<summary>
        /// 注册Client管道
        ///</summary>
        ///<param name="args"></param>
        ///<returns></returns>
        publicstring RegisteClientChannel(string argImgPath,string argPort,DateTime
argSnapShotTime)
        {
           
//实例客户端对象
           
TcpClientChannel channel = new
TcpClientChannel();
           
//注册客户端管道
           
ChannelServices.RegisterChannel(channel,false);
           
//获取远程对象
            IRpcAdapter.IPlateNo adapter = (IRpcAdapter.IPlateNo)Activator.GetObject(typeof(IRpcAdapter.IPlateNo),"tcp://localhost:8080/PlateIdentity");
           
//远程调用函数
           
string plateNo = adapter.PlateNo(argImgPath,argPort, argSnapShotTime);
           
MessageBox.Show("车牌号:{0}"+plateNo);
           
return plateNo;
        }      
    }
}

4. Server工程

注:该工程中除了Form的frmServer类之外,还需新建一个接口实现类(Adapter.cs),为公布的外部接口的具体实现类,该类中包含服务端所要公布的具体函数,同时为方便测试,新建一个识别程序类(ProcessPlate.cs)该类中只有一个用于外部调用的函数,也就是服务端公布给Client端调用的函数。同时仍需引入系统的Remoting命名空间和自定义的IRpcAdapter命名空间。

frmServer.cs代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace Server
{
    ///<summary>
    ///识别程序
    ///</summary>
    publicpartial
class frmServer :
Form
    {
        public frmServer()
        {
            InitializeComponent();
        }
        //识别类处理对象
        staticProcessPlate plateProc =
null; 
        publicstatic
ProcessPlate PlateProc
        {
           
get { return plateProc; }
           
set { plateProc = value; }
        }
        ///<summary>
        /// Load事件
        ///</summary>
        ///<param name="sender"></param>
        ///<param name="e"></param>
        privatevoid frmServer_Load(object sender,EventArgs e)
        {
           
///****************************/
           
///*       数据一览         */
           
///****************************/ 
           
//PlateProc = new ProcessPlate();
            RegisterServerChannel();          
        }
        ///<summary>
        ///注册Server管道
        ///</summary>
        publicstatic
void RegisterServerChannel()
        {
           
//实例Server对象
           
TcpServerChannel channel = new
TcpServerChannel(8080);
           
//注册Server管道
           
ChannelServices.RegisterChannel(channel,false);
           
//配置远程对象注:PlateIdentity 为Client调用的函数名,例:tcp://localhost:8080/PlateIdentity
           
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Adapter),"PlateIdentity",
WellKnownObjectMode.Singleton);
        } 
    }
}

Adatapter.cs实现类

using System;
using System.Collections.Generic;
using System.Text;
using IRpcAdapter;
namespace Server
{
    ///<summary>
    ///识别程序接口转换类
    ///</summary>
    publicclass
Adapter : MarshalByRefObject,
IPlateNo
    {
        ///<summary>
        ///接口内的定义函数
        ///</summary>
        ///<returns>车牌号</returns>
        publicstring PlateNo(string argImgPath,string argPort,DateTime
argSnapShotTime)
        {
           
string plateNo = Server.ProcessPlate.Process(argImgPath,argPort,argSnapShotTime);
           
return plateNo;
        }
    }
}
ProcessPlate.cs识别车牌类

using System;
using System.Collections.Generic;
using System.Text;
 
namespace Server
{
    ///<summary>
    ///车牌识别类
    ///</summary>
    publicclass
ProcessPlate
    {
        ///<summary>
        ///识别程序函数
        ///</summary>
        ///<param name="argImgPath"></param>
        ///<param name="argPort"></param>
        ///<param name="argSnapShotTime"></param>
        ///<returns></returns>
        publicstatic
string Process(string argImgPath,string argPort,DateTime argSnapShotTime)

        {
           
string plateNo = "沪A 8888";
           
/*************************************/
           
/*************车牌识别处理************/
           
/*************************************/
           
return plateNo;
        }
    }
}
5. IRpcAdapter工程

注:该工程为外部的DLL,Client与Server都需引入其命名空间,新建一个类,自定义类名,目前定义为:IRpcAdapterMethod.cs

IRpcAdapterMethod.cs代码

using System;
using System.Collections.Generic;
using System.Text;
namespace IRpcAdapter
{
    ///<summary>
    ///识别程序接口
    ///</summary>
    publicinterface
IPlateNo
    {
        string PlateNo(string argImgPath,string argPort,DateTime argSnapShotTime);
    }
}
小结:该工程为加深C#中采用Remoting对象以RPC管道形式对各种应用程序之间实现跨进程调用。在实际系统中,跨进程调用其另一程序的某一函数,经常有遇到,特别是在给某一系统添加外部辅助程序和引入第三方程序,在此记录,以便日后翻阅。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息