Пример #1
0
        private async ValueTask OnOffer(int channelId, Memory <byte> payloadBuffer, CancellationToken cancellationToken)
        {
            await ReadToFillAsync(this.stream, payloadBuffer, throwOnEmpty : true, cancellationToken).ConfigureAwait(false);

            string name = DecodeString(payloadBuffer);

            var            channel = new Channel(this, channelId, name, channelOptions: DefaultChannelOptions);
            bool           acceptingChannelAlreadyPresent = false;
            ChannelOptions options = null;

            lock (this.syncObject)
            {
                if (name != null && this.acceptingChannels.TryGetValue(name, out var acceptingChannels))
                {
                    while (acceptingChannels.Count > 0)
                    {
                        var candidate = acceptingChannels.Dequeue();
                        if (candidate.TrySetResult(channel))
                        {
                            if (this.TraceSource.Switch.ShouldTrace(TraceEventType.Information))
                            {
                                this.TraceSource.TraceEvent(TraceEventType.Information, (int)TraceEventId.ChannelOfferReceived, "Remote party offers channel {1} \"{0}\" which matches up with a pending " + nameof(this.AcceptChannelAsync), name, channelId);
                            }

                            acceptingChannelAlreadyPresent = true;
                            options = (ChannelOptions)candidate.Task.AsyncState;
                            break;
                        }
                    }
                }

                if (!acceptingChannelAlreadyPresent)
                {
                    if (name != null)
                    {
                        if (this.TraceSource.Switch.ShouldTrace(TraceEventType.Information))
                        {
                            this.TraceSource.TraceEvent(TraceEventType.Information, (int)TraceEventId.ChannelOfferReceived, "Remote party offers channel {1} \"{0}\" which has no pending " + nameof(this.AcceptChannelAsync), name, channelId);
                        }

                        if (!this.channelsOfferedByThemByName.TryGetValue(name, out var offeredChannels))
                        {
                            this.channelsOfferedByThemByName.Add(name, offeredChannels = new Queue <Channel>());
                        }

                        offeredChannels.Enqueue(channel);
                    }
                    else
                    {
                        if (this.TraceSource.Switch.ShouldTrace(TraceEventType.Information))
                        {
                            this.TraceSource.TraceEvent(TraceEventType.Information, (int)TraceEventId.ChannelOfferReceived, "Remote party offers anonymous channel {0}", channelId);
                        }
                    }
                }

                this.openChannels.Add(channelId, channel);
            }

            if (acceptingChannelAlreadyPresent)
            {
                this.AcceptChannelOrThrow(channel, options);
            }

            var args = new ChannelOfferEventArgs(channel.Id, channel.Name, acceptingChannelAlreadyPresent);

            this.OnChannelOffered(args);
        }
Пример #2
0
 /// <summary>
 /// Raises the <see cref="ChannelOffered"/> event.
 /// </summary>
 /// <param name="args">The arguments to pass to the event handlers.</param>
 protected virtual void OnChannelOffered(ChannelOfferEventArgs args) => this.ChannelOffered?.Invoke(this, args);