自定义流升级

面向流的传输(如 TCP 和命名管道)对客户端与服务器之间的连续字节流进行操作。 此流通过 Stream 对象实现。 在流升级中,客户端需要向通道堆栈中添加可选的协议层,并要求通信通道的另一端也执行该操作。 流升级包括使用升级后的对象替换原始 Stream 对象的过程。

例如,可以直接在传输流之上生成压缩流。 在这种情况下,原始传输 Stream 将替换为围绕原始传输流包装压缩 Stream 的传输流。

可以应用多次流升级,每次升级都包装前一次升级。

流升级如何工作

流升级过程包括四个部分。

  1. 升级流发起程序开始该过程:在运行时,发起程序可以向其连接的另一端发起升级通道传输层的请求。

  2. 升级流接受程序执行该升级:在运行时,接受程序接收来自其他计算机的升级请求,并尽可能接受该升级。

  3. 升级提供程序在客户端上创建发起程序,在服务器上创建接受程序。

  4. 流升级绑定元素将添加到服务和客户端上的绑定,并在运行时创建提供程序。

请注意,如果要进行多个升级,则发起程序和接受程序将会封装状态计算机,以便强制实施哪些升级转变对于每次“发起”都是有效的。

如何实现流升级

Windows Communication Foundation (WCF) 提供四个可以实现的 abstract 类:

若要实现自定义流升级,请执行下列操作。 此过程在客户端计算机和服务器计算机上均实现最低流升级过程。

  1. 创建用于实现 StreamUpgradeInitiator 的类。

    1. 重写要在所升级的流中采用的 InitiateUpgrade 方法,并返回升级后的流。 此方法同步工作;异步启动升级存在类似方法。

    2. 重写 GetNextUpgrade 方法以检查其他升级。

  2. 创建用于实现 StreamUpgradeAcceptor 的类。

    1. 重写要在所升级的流中采用的 AcceptUpgrade 方法,并返回升级后的流。 此方法同步工作;异步接受升级存在类似方法。

    2. 重写 CanUpgrade 方法,以确定在升级过程中的此时该升级接受程序是否支持请求的升级。

  3. 创建用于实现 StreamUpgradeProvider 的类。 重写 CreateUpgradeAcceptor 方法和 CreateUpgradeInitiator 方法,以返回步骤 2 和步骤 1 中定义的接受程序和发起程序的实例。

  4. 创建用于实现 StreamUpgradeBindingElement 的类。

    1. 在客户端上重写 BuildClientStreamUpgradeProvider 方法,然后在服务上重写 BuildServerStreamUpgradeProvider 方法。

    2. 在客户端上重写 BuildChannelFactory 方法,然后在服务上重写 BuildChannelListener 方法,以便将升级“绑定元素”添加到 BindingParameters

  5. 将新的流升级绑定元素添加到服务器计算机和客户端计算机上的绑定。

安全升级

添加安全升级是常规流升级过程的专用版本。

WCF 已为升级流安全提供了两个绑定元素。 传输级安全的配置由 WindowsStreamSecurityBindingElementSslStreamSecurityBindingElement 封装,可以对该两个元素进行配置并将其添加到自定义绑定。 这些绑定元素扩展用于生成客户端和服务器流升级提供程序的 StreamUpgradeBindingElement 类。 这些绑定元素包含的方法可用于创建专用的安全流升级提供程序类(不是 public),因此对于这两种情况,你需要做的只是将绑定元素添加到绑定。

对于上述两个绑定元素都不满足的安全方案,可从上述发起程序、接受程序和提供程序的基类派生三个与安全相关的 abstract 类:

  1. System.ServiceModel.Channels.StreamSecurityUpgradeInitiator

  2. System.ServiceModel.Channels.StreamSecurityUpgradeAcceptor

  3. System.ServiceModel.Channels.StreamSecurityUpgradeProvider

实现安全流升级的过程与以前的升级过程基本相同,不同的是将从这三个类进行派生。 重写这些类中的其他属性以便为运行时提供安全信息。

多个升级

若要创建其他升级请求,请重复上述过程:创建 StreamUpgradeProvider 的附加扩展和绑定元素。 将绑定元素添加到绑定。 这些附加绑定元素将按顺序进行处理,首先处理添加到绑定的第一个绑定元素。 在 BuildChannelFactoryBuildChannelListener 中,每个升级提供程序均可确定如何在任何已预先存在的升级绑定参数上对自身进行分层。 然后,它应使用新的复合升级绑定参数替换现有的升级绑定参数。

或者,一个升级提供程序可以支持多个升级。 例如,您可能需要实现既支持安全又支持压缩的自定义流升级提供程序。 执行以下步骤:

  1. 创建 StreamSecurityUpgradeProvider 的子类,以编写用于创建发起程序和接受程序的提供程序类。

  2. 创建 StreamSecurityUpgradeInitiator 的子类,确保重写 GetNextUpgrade 方法以按顺序返回压缩流和安全流的内容类型。

  3. 创建理解其 StreamSecurityUpgradeAcceptor 方法中的自定义内容类型的 CanUpgrade 的子类。

  4. 每次调用 GetNextUpgradeCanUpgrade 之后,都会升级该流。

请参阅