.NET Remoting 入门实例
1.创建服务端Class:ProxyServerRemoting
using System;
using System.Collections.Generic;
using System.Text;
using Inscription.Manadal.EmrPlugIn.NetMessage;
using NLog;
using Inscription.Manadal.EmrPlugIn;
using System.ComponentModel;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels; namespace Inscription.Mandala.EmrPlugIn.ProxyServer
{
public class ProxyServerRemoting
{
// 监听端口
private static int port;
// 单例对象
private static ProxyServerRemoting Instance = null;
// 后台工作线程对象
private BackgroundWorker backWork = null;
//定义服务端监听信道
private static TcpServerChannel tcpServerChannel = null; private ProxyServerRemoting()
{
//创建后台工作对象(线程)
backWork = new BackgroundWorker();
//绑定DoWork事件程序
backWork.DoWork += new DoWorkEventHandler(backWork_DoWork);
//开始执行后台操作
backWork.RunWorkerAsync();
} /// <summary>
/// 后台线程
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backWork_DoWork(object sender, DoWorkEventArgs e)
{
StartServer();
} /// <summary>
/// 单例实现
/// </summary>
/// <returns></returns>
public static ProxyServerRemoting getInstance(int Port)
{
if (Instance == null)
{
Instance = new ProxyServerRemoting();
tcpServerChannel = new TcpServerChannel(port);
port = Port;
}
return Instance;
} /// <summary>
/// 启动服务
/// </summary>
public void StartServer()
{
ChannelServices.RegisterChannel(tcpServerChannel, false); RemotingConfiguration.RegisterWellKnownServiceType(typeof(epiManagerV2), "GetEmrPlugInFunctionV3", WellKnownObjectMode.Singleton);
} /// <summary>
/// 停止服务
/// </summary>
public void StopServer()
{
ChannelServices.UnregisterChannel(tcpServerChannel);
}
}
}
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 = ; 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(@"\") + );
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();
}
}
}
.NET Remoting 入门实例的更多相关文章
- React 入门实例教程(转载)
本人转载自: React 入门实例教程
- struts入门实例
入门实例 1 .下载struts-2.3.16.3-all .不摆了.看哈就会下载了. 2 . 解压 后 找到 apps 文件夹. 3. 打开后将 struts2-blank.war ...
- Vue.js2.0从入门到放弃---入门实例
最近,vue.js越来越火.在这样的大浪潮下,我也开始进入vue的学习行列中,在网上也搜了很多教程,按着教程来做,也总会出现这样那样的问题(坑啊,由于网上那些教程都是Vue.js 1.x版本的,现在用 ...
- wxPython中文教程入门实例
这篇文章主要为大家分享下python编程中有关wxPython的中文教程,分享一些wxPython入门实例,有需要的朋友参考下 wxPython中文教程入门实例 wx.Window 是一个基类 ...
- Omnet++ 4.0 入门实例教程
http://blog.sina.com.cn/s/blog_8a2bb17d01018npf.html 在网上找到的一个讲解omnet++的实例, 是4.0下面实现的. 我在4.2上试了试,可以用. ...
- Spring中IoC的入门实例
Spring中IoC的入门实例 Spring的模块化是很强的,各个功能模块都是独立的,我们可以选择的使用.这一章先从Spring的IoC开始.所谓IoC就是一个用XML来定义生成对象的模式,我们看看如 ...
- Node.js入门实例程序
在使用Node.js创建实际“Hello, World!”应用程序之前,让我们看看Node.js的应用程序的部分.Node.js应用程序由以下三个重要组成部分: 导入需要模块: 我们使用require ...
- Java AIO 入门实例(转)
Java7 AIO入门实例,首先是服务端实现: 服务端代码 SimpleServer: public class SimpleServer { public SimpleServer(int port ...
- Akka入门实例
Akka入门实例 Akka 是一个用 Scala 编写的库,用于简化编写容错的.高可伸缩性的 Java 和 Scala 的 Actor 模型应用. Actor模型并非什么新鲜事物,它由Carl Hew ...
随机推荐
- poj 2940
Wine Trading in Gergovia Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3187 Accepte ...
- 关于oracle存储过程需要注意的问题
在使用oracle存储过程时,有一些需要注意的地方,下面就来总结一下. 1.在oracle的存储过程中,数据表别名不能加as 也许是为了区分存储过程中的as,怕与过程中的as冲突. 如: select ...
- AtCoder - 3939 Strange Nim
Problem Statement Takahashi and Aoki are playing a stone-taking game. Initially, there are N piles o ...
- [Codeforces-div.1 24D] Broken robots
[Codeforces-div.1 24D] Broken robots 试题分析 显然设\(f_{i,j}\)为到\((i,j)\)的期望步数,将转移表达式列出来. 首先自己跟自己的项消掉. 然后规 ...
- 【推导】Codeforces Round #364 (Div. 2) D. As Fast As Possible
一种方法是二分总时间,复杂度O(nlogn). 另外我们可以证明,当所有人同时到达终点的时候,是最优的,因为没有人的时间“浪费”了. 我们又发现,每个人的运动过程总是两段,要么是走路,要么是坐车.于是 ...
- JDK源码学习笔记——LinkedHashMap
HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序. LinkedHashMap保证了元素迭代的顺序.该迭代顺序可以是插入顺序或者是访问顺序.通过维护一个 ...
- iOS 日志管理异常捕获组件LFLogManager
一.功能 1.分级打印保存 解决一大堆重要.不重要打印信息在控制台混为一团的尴尬局面.可设置仅打印某级别及以上的信息.分为5类打印: DDLogError(@"打印并保存特别重要信息&quo ...
- Word中插入英文格式的算法流程
如图上部分所示,需要序号自动编号,那么插入一个一行一列的的表格,然后点击编号,使得项目自动编号,编号一个就在后面输入一些内容,按enter后第二行开始自动编号,如果要缩进,不能按Tab,Tab自动创建 ...
- JavaScript里的循环方法:forEach,for-in,for-of
JavaScript诞生已经有20多年了,我们一直使用的用来循环一个数组的方法是这样的: for (var index = 0; index < myArray.length; index++) ...
- Objective-C字面量语法总结
通常情况下,创建数组,字典的时候需要写一些很长的方法名,今天就总结一下如何使用字面量语法代替这些方法. 1.数值的创建 NSNumber *number1 = [NSNumber numberWith ...