C# 下 Remoting远程通讯服务 的创建和使用
与其相关的概念:
1、.NET Remoting是微软随.NET推出的一种分布式应用解决方案,被誉为管理应用程序域之间的 RPC 的首选技,它允许不同应用程序域之间进行通信(这里的通信可以是在同一个进程中进行、一个系统的不同进程间进行、不同系统的进程间进行)。
2、SOAP(Simple Object AccessProtocol)简单对象访问协议。它是轻型协议,用于分散的、分布式计算环境中交换信息。SOAP有助于以独立于平台的方式访问对象、服务和服务器。它借助于XML,提供了HTTP所需的扩展。
3、SOAP与HTTP的区别:
都是底层的通信协议,请求包的格式不同,soap包是XML格式,http纯文本格式
soap 的 可以传递结构化的 数据,http只能传输纯文本数据;
SOAP:简单对象访问协议
http是标准超文本传输协议
SOAP相对http(post/get)由于要进行xml解析,速度可能会有所降低。
4、其他:
1、.NET Remoting是目前分布式对象实现RPC(RPC Remote Procedure Call)—远程过程调用的一种主要方式。
2、.NET Remtoing在性能上可以达到DCOM,或者与之相差不多。
3、.NET Remoting建立在.NET定义的公共数据类型CTS及运行环境CLR之上,和.NET框架有着很好的互操作性,因此功能强大切易于使用。
4、扩展性和安全性方面都比较好。
NET Remoting包括如下几点主要元素:
远程对象:运行在Remoting服务器上的对象。客户端通过代理对象来间接调用该对象的服务,如上图的“通信体系结构”所示。在.NET Remoting体系中,要想成为远程对象提供服务,该对象的类必须是MarshByRefObject的派生对象。另外,要说明的是,需要在网络上传递的对象,例如“参数”,则必须是可序列化的。
Ø 信道:信道是服务器和客户机进行通信用的(这里的服务器和客户机并不一定都是计算机,也可能是进程)。在.NET Remoting中,提供了三种信道类型:TCP、HTTP、IPC,另外,也可以定制不同的信道以适应不同的通信协议(至于如何定制,我尚未涉及到,因此,不好说)。
Ø 消息:客户机和服务器通过消息进行信息交换,消息在信道中传递。这里的消息包括,远程对象的信息,调用方法名称,参数,返回值等。
Ø 格式标识符:该标识符标明了消息是按照什么样的格式被发送到信道上的,目前.NET 2.0提供了两种格式标识符:SOAP格式和二进制格式。SOAP格式标识符符合SOAP标准,比较通用,可以和非.NET 框架的Web服务通信。二进制格式标识符,则在速度、效率上面更生一筹,但通用性较SOAP差。另外,Remoting还支持自定义的格式标识符。(顺便说一下:TCP信道,默认使用二进制格式传输,因为这个效率更高;Http信道则默认使用SOAP格式;不过在系统中,哪种信道具体使用哪种格式,则是可以根据需要设置的。)。
Ø 格式标识符提供程序:它用于把格式标识符和信道联系起来。在创建信道时,可以指定所要使用的标识符提供程序,一旦指定了提供程序,那么消息被发送到信道上的格式也就确定了下来。
以上参考至:https://blog.csdn.net/cnhk1225/article/details/50350290 感谢作者“安静平和” 的知识分享
来说下我用它主要是用来干嘛的:
项目中的需求是统一在服务器端用远程服务的方式发布出来,客户端接收相关配置参数,并根据这个参数做连接数据库、登录系统等操作,这对一个服务器对多个客户端的部署方式很有优势(CS端),这与一般的后台服务类似,可以当作是一种后台的实现方式吧,仅做参考
。
好了 接下来直接来说下如何实现:
远程通信服务包括 服务器端和客户端,接下来我将分别届时服务端和客户端 如何实现:
首先在服务器端和客户端都要继承相同的接口,这点很重要,服务端和客户端他们有相同的实现方法,后期在客户端调用的时候不会出现不知道要调用的是哪个方法的问题。
服务端和客户端共同实现的接口如下
public interface IRemoteService
{
#region
/// <summary>
/// 获取指定的服务器配置
/// </summary>
/// <param name="key">关键字</param>
/// <returns>返回的配置参数</returns>
string GetAppSettings(string key);
/// <summary>
/// 设置指定的服务器配置
/// </summary>
/// <param name="key">关键字</param>
/// <param name="value">对应的配置参数</param>
void SetAppSettings(string key, string value);
/// <summary>
/// 或者其他方法功能的实现
/// </summary>
/// <param name="p1">参数一</param>
/// <param name="p2">参数2</param>
void doSomethiing(string p1, string p2);
#endregion
}
在服务端:
1、方法类必须继承MarshalByRefObject,并实现IRemoteService接口
/// <summary>
/// Remoting 接口的实现
/// </summary>
public class RemoteService : MarshalByRefObject, IRemoteService
{
#region IRemoteService 成员
public string GetAppSettings(string key)
{
return Program.GetAppSettings(key);
}
public void SetAppSettings(string key, string value)
{
Program.SetAppSettings(key, value);
}
#endregion
}
以上方法的实现方法,该方法也可以是其他的操作,比如连接数据库进行 增删改查 或者其他操作
public static string GetAppSettings(string key)
{
try
{
if (ContainsKey(key))
return System.Configuration.ConfigurationManager.AppSettings[key].ToString();
else
return "";
}
catch (Exception ex)
{
WriteLineLog("获取配置参数时发生错误", ex);
return "";
}
}
2、服务端注册端口,开启监控服务,在服务端要创建Window Server 的方式启动 远程通信服务:
public partial class WindowService : ServiceBase
{
public WindowService ()
{
InitializeComponent();
}
#region 服务的启动和停止方法
// 启动远程通信的信道注册、远程对象创建等
protected override void OnStart(string[] args)
{
StartService();
}
protected override void OnStop()
{
}
#endregion
}
private void StartService()
{
try
{
// 初始化配置信息
Program.InitializeAppSettings();
// 从配置文件中读取 端口信息
int port = Int32.Parse(Program.GetAppSettings("TCP_Port"));
// 注册通道
TcpServerChannel channel = new TcpServerChannel(port);
ChannelServices.RegisterChannel(channel, false);
// 注册远程对象,即激活.
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(RemoteService), "RemoteServer",
WellKnownObjectMode.Singleton);
}
catch (Exception ex)
{
Program.WriteLineLog("侦听Remote服务时发生错误", ex);
Stop();
}
}
服务端代码实现完毕,现在可以执行服务端程序,开启服务。
注意:服务器端激活分为:SingleTon模式 SingleCall模式
SingleTon模式
设置为SingleTon激活方式,则Remoting将为所有客户端建立同一个对象实例。当对象处于活动状态时, SingleTon实例会处理所有后来的客户端访问请求,而不管它们是同一个客户端,还是其他客户端。SingleTon实例将在方法调用中一直维持其状态。举例来说,如果一个远程对象有一个累加方法(i=0;++i),被多个客户端(例如两个)调用。如果设置为SingleTon方式,则第一个客户获得值为1,第二个客户获得值为2,因为他们获得的对象实例是相同的。如果熟悉Asp .Net的状态管理,我们可以认为它是一种Application状态。即多个客户端请求的通道,服务端都是用一个通道(一个实例)来进行处理的。
SingleCall模式
SingleCall是一种无状态模式。一旦设置为SingleCall模式,则当客户端调用远程对象的方法时, Remoting会为每一个客户端建立一个远程对象实例,至于对象实例的销毁则是由GC自动管理的。同上一个例子而言,则访问远程对象的两个客户获得的都是1。我们仍然可以借鉴Asp .Net的状态管理,认为它是一种Session状态。每次服务端都会为每一个客户端请求建立一个远程对象实例。
以上的 具体案例解析这里就不一一实验解析了,请移驾到 https://www.cnblogs.com/woxpp/p/3995366.html 这里查看详细的内容,相信你们会有收获。
在客户端:
客户端继承与服务器端继承的接口相同,
IRemoteService pRemoteServic==null;
//客户端调用服务端方法代码如下
if (pRemoteServic==null)
{
// 注册通道
TcpClientChannel channel = new TcpClientChannel();
ChannelServices.RegisterChannel(channel, false);
//激活 strServer 服务器的IP 以及端口号 strPort
pRemoteService = (IRemoteService)Activator.GetObject(typeof(IRemoteService),
String.Format(@"tcp://{0}:{1}/RemoteServer", strServer, strPort));
// 通过调用远程对象 实现GetAppSettings 方法获取配置中的参数信息
string something= pRemoteService.GetAppSettings("SdeServer");
.....
}
注意:@"tcp://{0}:{1}/RemoteServer" 中的 RemoteServer 与服务端注册远程对象中的参数 是一致 的
客户端实现代码完毕。大体上的流程就是如此。
以上文章参考了很多大牛的文章,感谢你们的知识分享,现在罗列供各位参考:
https://blog.csdn.net/cnhk1225/article/details/50350290
https://blog.csdn.net/ttxs99989/article/details/81294958
https://blog.csdn.net/qq_18145031/article/details/52824868