| File: System\ServiceModel\Channels\ReliableChannelFactory.cs | Web Access |
| Project: src\src\System.ServiceModel.Primitives\src\System.ServiceModel.Primitives.csproj (System.ServiceModel.Primitives) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Runtime; using System.Threading.Tasks; namespace System.ServiceModel.Channels { internal class ReliableChannelFactory<TChannel, InnerChannel> : ChannelFactoryBase<TChannel>, IReliableFactorySettings where InnerChannel : class, IChannel { public ReliableChannelFactory(ReliableSessionBindingElement settings, IChannelFactory<InnerChannel> innerChannelFactory, Binding binding) : base(binding) { AcknowledgementInterval = settings.AcknowledgementInterval; FlowControlEnabled = settings.FlowControlEnabled; InactivityTimeout = settings.InactivityTimeout; MaxPendingChannels = settings.MaxPendingChannels; MaxRetryCount = settings.MaxRetryCount; MaxTransferWindowSize = settings.MaxTransferWindowSize; MessageVersion = binding.MessageVersion; Ordered = settings.Ordered; ReliableMessagingVersion = settings.ReliableMessagingVersion; InnerChannelFactory = innerChannelFactory; FaultHelper = new SendFaultHelper(binding.SendTimeout, binding.CloseTimeout); } public TimeSpan AcknowledgementInterval { get; } public FaultHelper FaultHelper { get; } public bool FlowControlEnabled { get; } public TimeSpan InactivityTimeout { get; } protected IChannelFactory<InnerChannel> InnerChannelFactory { get; } public int MaxPendingChannels { get; } public int MaxRetryCount { get; } public MessageVersion MessageVersion { get; } public int MaxTransferWindowSize { get; } public bool Ordered { get; } public ReliableMessagingVersion ReliableMessagingVersion { get; } public override T GetProperty<T>() { if (typeof(T) == typeof(IChannelFactory<TChannel>)) { return (T)(object)this; } T baseProperty = base.GetProperty<T>(); if (baseProperty != null) { return baseProperty; } return InnerChannelFactory.GetProperty<T>(); } public TimeSpan SendTimeout => InternalSendTimeout; protected override void OnAbort() { // Aborting base first to abort channels. Must abort higher channels before aborting lower channels. base.OnAbort(); FaultHelper.Abort(); InnerChannelFactory.Abort(); } protected internal override Task OnOpenAsync(TimeSpan timeout) { return InnerChannelFactory.OpenHelperAsync(timeout); } protected override void OnOpen(TimeSpan timeout) { CommunicationObjectInternal.OnOpen(this, timeout); } protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { return CommunicationObjectInternal.OnBeginOpen(this, timeout, callback, state); } protected override void OnEndOpen(IAsyncResult result) { CommunicationObjectInternal.OnEnd(result); } protected internal override async Task OnCloseAsync(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); // Closing base first to close channels. Must close higher channels before closing lower channels. await base.OnCloseAsync(timeoutHelper.RemainingTime()); await FaultHelper.CloseAsync(timeoutHelper.RemainingTime()); await InnerChannelFactory.CloseHelperAsync(timeoutHelper.RemainingTime()); } protected override void OnClose(TimeSpan timeout) { CommunicationObjectInternal.OnClose(this, timeout); } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return CommunicationObjectInternal.OnBeginClose(this, timeout, callback, state); } protected override void OnEndClose(IAsyncResult result) { CommunicationObjectInternal.OnEnd(result); } protected override TChannel OnCreateChannel(EndpointAddress address, Uri via) { LateBoundChannelParameterCollection channelParameters = new LateBoundChannelParameterCollection(); IClientReliableChannelBinder binder = ClientReliableChannelBinder<InnerChannel>.CreateBinder(address, via, InnerChannelFactory, MaskingMode.All, TolerateFaultsMode.IfNotSecuritySession, channelParameters, DefaultCloseTimeout, DefaultSendTimeout); if (typeof(TChannel) == typeof(IOutputSessionChannel)) { if (typeof(InnerChannel) == typeof(IDuplexChannel) || typeof(InnerChannel) == typeof(IDuplexSessionChannel)) return (TChannel)(object)new ReliableOutputSessionChannelOverDuplex(this, this, binder, FaultHelper, channelParameters); // typeof(InnerChannel) == typeof(IRequestChannel) || typeof(InnerChannel) == typeof(IRequestSessionChannel)) return (TChannel)(object)new ReliableOutputSessionChannelOverRequest(this, this, binder, FaultHelper, channelParameters); } else if (typeof(TChannel) == typeof(IDuplexSessionChannel)) { return (TChannel)(object)new ClientReliableDuplexSessionChannel(this, this, binder, FaultHelper, channelParameters, WsrmUtilities.NextSequenceId()); } // (typeof(TChannel) == typeof(IRequestSessionChannel) return (TChannel)(object)new ReliableRequestSessionChannel(this, this, binder, FaultHelper, channelParameters, WsrmUtilities.NextSequenceId()); } } }