信道(Channel)是 Remoting 体系的承载平台,负责处理客户端和服务器之间的通讯,其内容包括跨域通讯、消息传递、对象编码等等。信道必须实现 IChannel 接口,根据通讯方向又分别提供了继承版本 IChannelReceiver 和 IChannelSender。Remoting 框架为我们提供了 IPC、TCP 以及 HTTP 的实现版本,当然我们还可以在网络上找到其他协议的实现版本。
TcpServerChannel channel = new TcpServerChannel(801); ChannelServices.RegisterChannel(channel, false);
我们可以使用实用类 ChannelServices 来管理程序域内的信道,诸如注册、注销等等。程序域内可以同时使用多个信道,每个信道需提供唯一的名称,以便 ChannelServices 进行管理,同时信道会随程序域的退出自动销毁。
TcpServerChannel channel = new TcpServerChannel("tcp801", 801); ChannelServices.RegisterChannel(channel, false); IChannel c2 = ChannelServices.GetChannel("tcp801"); Console.WriteLine(Object.ReferenceEquals(channel, c2)); channel.StopListening(null); channel.StartListening(null); foreach (IChannel c in ChannelServices.RegisteredChannels) { Console.WriteLine(c.ChannelName); } ChannelServices.UnregisterChannel(channel);
信道内部包含由多个接收器(Sink)组成的接收链(Sink Chain)。接收器用于处理客户端和服务器之间的来往消息,诸如格式化程序接收器(FormatterSink)、传输接收器(TransportSink)或堆栈生成器接收器(StackBuilderSink)等等。每个接收器或实现 IClientChannelSink,或实现 IServerChannelSink。
Remoting 采用信道接收提供程序(Channel Sink Provider,实现 IClientChannelSinkProvider、IClientFormatterSinkProvider 或 IServerChannelSinkProvider 接口的对象) 来创建接收器,已有的提供程序包括 BinaryClientFormatterSinkProvider / BinaryServerFormatterSinkProvider、SoapClientFormatterSinkProvider / SoapServerFormatterSinkProvider。
在客户端接收链中第一个接收器通常是格式化程序接收器(IClientFormatterSink),且必须实现 IMessageSink。代理通过信道接收提供程序找个该接收器,并通过接口方法将消息传递给链中所有的接收器,最后由传输接收器发送到服务器。同样,在服务器排在最后的接收器是格式化程序接收器和堆栈生成器接收器,分别执行反序列化和将将消息转换成相应的调用堆栈。
TcpServerChannel channel = new TcpServerChannel("tcp801", 801, new BinaryServerFormatterSinkProvider()); ChannelServices.RegisterChannel(channel, false); ... TcpClientChannel channel = new TcpClientChannel("tcp801", new BinaryClientFormatterSinkProvider()); ChannelServices.RegisterChannel(channel, false);
只要看看 BinaryClientFormatterSinkProvider 和 BinaryClientFormatterSink 的代码就很容易理解如何使用提供者模型构造一个接收链了。
BinaryClientFormatterSinkProvider
public IClientChannelSink CreateSink(IChannelSender channel, string url, object remoteChannelData) { IClientChannelSink sink1 = null; if (this._next != null) { sink1 = this._next.CreateSink(channel, url, remoteChannelData); if (sink1 == null) { return null; } } SinkChannelProtocol protocol1 = CoreChannel.DetermineChannelProtocol(channel); BinaryClientFormatterSink sink2 = new BinaryClientFormatterSink(sink1); sink2.IncludeVersioning = this._includeVersioning; sink2.StrictBinding = this._strictBinding; sink2.ChannelProtocol = protocol1; return sink2; }
BinaryClientFormatterSink
public BinaryClientFormatterSink(IClientChannelSink nextSink) { this._includeVersioning = true; this._channelProtocol = SinkChannelProtocol.Other; this._nextSink = nextSink; } public IClientChannelSink NextChannelSink { get { return this._nextSink; } }
信道内的接收器是可 "插入的",这意味着我们可以实现自己的接收器,并将其装配到信道接收链中。比如对消息进行加密,或者对数据流进行压缩等等。
============ 欢迎各位老板打赏~ ===========
与本文相关的文章
- · Remoting 生存期租约
- · Remoting系列之远程对象
- · .NET Remoting系列之远程对象
- · .NET Remoting系列(一)
- · Remoting实现双向通信
- · Microsoft .Net Remoting系列专题之三:Remoting事件处理全接触
- · Microsoft .Net Remoting系列专题之二:Marshal、Disconnect与生命周期以及跟踪服务
- · Microsoft .Net Remoting系列专题之一:.Net Remoting基础篇
- · The instance of entity type ‘Customer’ cannot be tracked because another instance with the same key value for {‘Id’} is already being tracked.
- · .NET8实时更新nginx ip地址归属地
- · 解决.NET Blazor子组件不刷新问题
- · .NET8如何在普通类库中引用 Microsoft.AspNetCore