.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:ProxyClient
客户端每次调用完成以后,需要注销掉当前信道,ChannelServices.UnregisterChannel(tcpChannel);
不然会发生异常:信道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的依赖,
客户端编译成一个单独的dll可被第三方程序调用。
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.服务端管理工具
实现启动服务,暂停服务,开机自动运行功能
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(); } } }