예제 #1
0
            /// <summary>
            /// Occurs when the remote party has accepted our offer of this channel.
            /// </summary>
            /// <param name="acceptanceParameters">The channel parameters provided by the accepting party.</param>
            /// <returns>A value indicating whether the acceptance went through; <c>false</c> if the channel is already accepted, rejected or offer rescinded.</returns>
            internal bool OnAccepted(AcceptanceParameters acceptanceParameters)
            {
                lock (this.SyncObject)
                {
                    if (this.acceptanceSource.TrySetResult(acceptanceParameters))
                    {
                        this.remoteWindowSize = acceptanceParameters.RemoteWindowSize;
                        return(true);
                    }

                    return(false);
                }
            }
예제 #2
0
            /// <summary>
            /// Accepts an offer made by the remote party.
            /// </summary>
            /// <param name="channelOptions">The options to apply to the channel.</param>
            /// <returns>A value indicating whether the offer was accepted. It may fail if the channel was already closed or the offer rescinded.</returns>
            internal bool TryAcceptOffer(ChannelOptions channelOptions)
            {
                lock (this.SyncObject)
                {
                    // If the local window size has already been determined, we have to keep that since it can't be expanded once the Pipe is created.
                    // Otherwise use what the ChannelOptions asked for, so long as it is no smaller than the default channel size, since we can't make it smaller either.
                    this.localWindowSize ??= channelOptions.ChannelReceivingWindowSize is long windowSize?Math.Max(windowSize, this.MultiplexingStream.DefaultChannelReceivingWindowSize) : this.MultiplexingStream.DefaultChannelReceivingWindowSize;
                }

                var acceptanceParameters = new AcceptanceParameters(this.localWindowSize.Value);

                if (this.acceptanceSource.TrySetResult(acceptanceParameters))
                {
                    if (this.QualifiedId.Source != ChannelSource.Seeded)
                    {
                        var payload = this.MultiplexingStream.formatter.Serialize(acceptanceParameters);
                        this.MultiplexingStream.SendFrame(
                            new FrameHeader
                        {
                            Code      = ControlCode.OfferAccepted,
                            ChannelId = this.QualifiedId,
                        },
                            payload,
                            CancellationToken.None);
                    }

                    try
                    {
                        this.ApplyChannelOptions(channelOptions);
                        return(true);
                    }
                    catch (ObjectDisposedException)
                    {
                        // A (harmless) race condition was hit.
                        // Swallow it and return false below.
                    }
                }

                return(false);
            }