.NET Remoting 入门实例

1.建立服务端Class:ProxyServerRemoting服务器

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 using Inscription.Manadal.EmrPlugIn.NetMessage;
 5 using NLog;
 6 using Inscription.Manadal.EmrPlugIn;
 7 using System.ComponentModel;
 8 using System.Runtime.Remoting;
 9 using System.Runtime.Remoting.Channels.Tcp;
10 using System.Runtime.Remoting.Channels;
11 
12 namespace Inscription.Mandala.EmrPlugIn.ProxyServer
13 {
14     public class ProxyServerRemoting
15     {
16         // 监听端口
17         private static int port;
18         // 单例对象
19         private static ProxyServerRemoting Instance = null;
20         // 后台工做线程对象
21         private BackgroundWorker backWork = null;
22         //定义服务端监听信道
23         private static TcpServerChannel tcpServerChannel = null; 
24 
25         private ProxyServerRemoting()
26         {
27             //建立后台工做对象(线程)
28             backWork = new BackgroundWorker();
29             //绑定DoWork事件程序
30             backWork.DoWork += new DoWorkEventHandler(backWork_DoWork);
31             //开始执行后台操做
32             backWork.RunWorkerAsync();
33         }
34 
35         /// <summary>
36         /// 后台线程
37         /// </summary>
38         /// <param name="sender"></param>
39         /// <param name="e"></param>
40         private void backWork_DoWork(object sender, DoWorkEventArgs e)
41         {
42             StartServer();
43         }
44 
45         /// <summary>
46         /// 单例实现
47         /// </summary>
48         /// <returns></returns>
49         public static ProxyServerRemoting getInstance(int Port)
50         {
51             if (Instance == null)
52             {
53                 Instance = new ProxyServerRemoting();
54                 tcpServerChannel = new TcpServerChannel(port);
55                 port = Port;
56             }
57             return Instance;
58         }
59 
60         /// <summary>
61         /// 启动服务
62         /// </summary>
63         public void StartServer()
64         {
65             ChannelServices.RegisterChannel(tcpServerChannel, false);
66                         
67             RemotingConfiguration.RegisterWellKnownServiceType(typeof(epiManagerV2), "GetEmrPlugInFunctionV3", WellKnownObjectMode.Singleton);
68         }
69 
70         /// <summary>
71         /// 中止服务
72         /// </summary>
73         public void StopServer()
74         {
75             ChannelServices.UnregisterChannel(tcpServerChannel);
76         }
77     }
78 }

2.建立客户端调用Class:ProxyClienttcp

客户端每次调用完成之后,须要注销掉当前信道,ChannelServices.UnregisterChannel(tcpChannel);ide

否则会发生异常:信道tcp已注册函数

using System;
using System.Collections.Generic;
using System.Text;
using NLog;
using System.Runtime.Remoting.Channels.Tcp;
using System.Diagnostics;
using System.Configuration;
using System.Reflection;
using System.Runtime.Remoting.Channels;
using Inscription.Manadal.EmrPlugIn;

namespace Inscription.Mandala.EmrPlugIn.ProxyClient
{
    public static class ProxyClient
    {
        /// <summary>
        /// 获取基于函数的外部接口
        /// </summary>
        /// <param name="MainName"></param>
        /// <param name="ConfigInfo"></param>
        /// <param name="worker"></param>
        /// <param name="patientIndex"></param>
        /// <returns></returns>
        public static string GetEmrPlugInFunctionV3(string MainName, string ConfigInfo, string strWorker, string strPatientIndex, string CommandKey, string strParamLst)
        {
            TcpChannel tcpChannel = null;
            Logger logger = NLogManagerV2.GetLogger("GetEmrPlugInFunctionV3_Client");
            try
            {
                logger.Trace("判断服务端进程是否存在");

                string strAppName = "IMPIProxyServer";
                Process[] curProcesses = Process.GetProcesses();
                bool isExist = false;
                foreach (Process p in curProcesses)
                {
                    if (p.ProcessName == strAppName)
                    {
                        isExist = true;
                        logger.Trace("服务端进程存在");
                        break;
                    }
                }
                if (isExist == false)
                {
                    logger.Trace("服务端进程不存在");
                    Process.Start(strAppName);
                    logger.Trace("从新启动服务端进程");
                }

                //int port = 3399;
                string ip = ConfigurationManager.AppSettings["ServerIP"];
                int port = Convert.ToInt32(ConfigurationManager.AppSettings["ServerPort"]);
                logger.Trace("监听IP:" + ip + "    监听端口" + port);


                //使用TCP通道获得远程对象
                tcpChannel = new TcpChannel();
                ChannelServices.RegisterChannel(tcpChannel, false);
                IepiManagerV2 manager = (IepiManagerV2)Activator.GetObject(typeof(IepiManagerV2), string.Format("tcp://{0}:{1}/GetEmrPlugInFunctionV3", ip, port));
                logger.Trace("取得.Net Remoting对象成功");

                string strReturn = manager.GetEmrPlugInFunctionV3(MainName, ConfigInfo, strWorker, strPatientIndex, CommandKey, strParamLst);
                logger.Trace("客户端调用结束");
                return strReturn;
            }
            catch (Exception ex)
            {
                logger.Trace(ex.Message);
                return string.Empty;
            }
            finally
            {
                ChannelServices.UnregisterChannel(tcpChannel);
            }
        }
    }
}

 

3.业务类:epiManagerV2 工具

业务类实现了IepiManagerV2接口,其中客户端也连接引用了IepiManagerV2接口文件,这样客户端就摆脱了对具体业务Dll的依赖,this

客户端编译成一个单独的dll可被第三方程序调用。spa

public class epiManagerV2 :  MarshalByRefObject,IepiManagerV2
{
        /// <summary>
        /// 获取基于函数的外部接口
        /// </summary>
        /// <param name="MainName"></param>
        /// <param name="ConfigInfo"></param>
        /// <param name="worker"></param>
        /// <param name="patientIndex"></param>
        /// <returns></returns>
        public string GetEmrPlugInFunctionV3(string MainName, string ConfigInfo, string strWorker, string strPatientIndex, string CommandKey, string strParamLst)
        {
        实现略
        }            
}

 IepiManagerV2接口线程

using System;
namespace Inscription.Manadal.EmrPlugIn
{
    interface IepiManagerV2
    {
        string GetEmrPlugInFunctionV3(string MainName, string ConfigInfo, string strWorker, string strPatientIndex, string CommandKey, string strParamLst);
    }
}

 4.服务端管理工具 code

实现启动服务,暂停服务,开机自动运行功能orm

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Configuration;
using Microsoft.Win32;
using System.IO;

namespace Inscription.Mandala.EmrPlugIn.ProxyServer
{
    public partial class frmMainServer : Form
    {
        private ProxyServerRemoting Instance = null;

        string ip = "127.0.0.1";
        int port = 3399;

        public frmMainServer()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmMain_Load(object sender, EventArgs e)
        {
            InitForm();
            StartServer();
        }

        private void InitForm()
        {
            this.ip = ConfigurationManager.AppSettings["ServerIp"];
            this.port = Convert.ToInt32(ConfigurationManager.AppSettings["ServerPort"]);
        }

        /// <summary>
        /// 打开服务端
        /// </summary>
        private void StartServer()
        {
            try
            {
                Instance = ProxyServerRemoting.getInstance(port);
                Instance.StartServer();

                btnStart.Enabled = false;
                btnStop.Enabled = true;
                lblStatus.Text = "服务正在运行";
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 关闭服务
        /// </summary>
        private void StopServer()
        {
            try
            {
                Instance.StopServer();

                btnStart.Enabled = true;
                btnStop.Enabled = false;
                lblStatus.Text = "服务已关闭";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 窗口显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmMainServer_Shown(object sender, EventArgs e)
        {
            this.Hide();
        }

        /// <summary>
        /// 启动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, System.EventArgs e)
        {
            StartServer();
        }

        /// <summary>
        /// 暂停服务器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsbStop_Click(object sender, EventArgs e)
        {
            StopServer();
        }

        /// <summary>
        /// 关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmMainServer_FormClosing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Instance.StopServer();
        }

        /// <summary>
        /// 菜单命令
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            switch (e.ClickedItem.Text)
            {
                case "打开":
                    this.Show();
                    break;
                case "隐藏":
                    this.Hide();
                    break;
                case "关闭":
                    Instance.StopServer();
                    this.Close();
                    break;
            }
        }

        /// <summary>
        /// 工具栏事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            switch (e.ClickedItem.Name)
            {
                case "tsbAutoRun":
                    SetAutoRun(Core.App.fullPath, true);
                    break;
                case "tsbAutoRunCancel":
                    SetAutoRun(Core.App.fullPath, false);
                    break;
            }
        }

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            this.Show();
        }


        /// <summary>
        /// 设置应用程序开机自动运行
        /// </summary>
        /// <param name="fileName">应用程序的文件名</param>
        /// <param name="isAutoRun">是否自动运行,为false时,取消自动运行</param>
        /// <exception cref="System.Exception">设置不成功时抛出异常</exception>
        private static void SetAutoRun(string fileName, bool isAutoRun)
        {
            RegistryKey reg = null;
            try
            {
                String name = fileName.Substring(fileName.LastIndexOf(@"\") + 1);
                reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
                if (reg == null)
                    reg = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
                if (isAutoRun)
                    reg.SetValue(name, fileName);
                else
                    reg.SetValue(name, false);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (reg != null)
                    reg.Close();
            }
        }


        public static void Test()
        {
            frmMainServer f = new frmMainServer();
            f.Show();
        }
    }
}