示例#1
0
        protected virtual async Task <AmqpSession> CreateSessionAsync(TimeSpan timeout, CancellationToken token)
        {
            this.OnCreateSession();

            var timeoutHelper = new TimeoutHelper(timeout);

            AmqpSettings  amqpSettings = CreateAmqpSettings();
            TransportBase transport;

            token.ThrowIfCancellationRequested();

            switch (this.AmqpTransportSettings.GetTransportType())
            {
#if !WINDOWS_UWP && !PCL
            case TransportType.Amqp_WebSocket_Only:
                transport = await this.CreateClientWebSocketTransportAsync(timeoutHelper.RemainingTime());

                break;
#endif
            case TransportType.Amqp_Tcp_Only:
                TlsTransportSettings tlsTransportSettings = this.CreateTlsTransportSettings();
                var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
                transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime());

                break;

            default:
                throw new InvalidOperationException("AmqpTransportSettings must specify WebSocketOnly or TcpOnly");
            }

            var amqpConnectionSettings = new AmqpConnectionSettings()
            {
                MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                ContainerId  = Guid.NewGuid().ToString("N"),
                HostName     = this.hostName
            };

            var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            try
            {
                token.ThrowIfCancellationRequested();
                await amqpConnection.OpenAsync(timeoutHelper.RemainingTime());

                var sessionSettings = new AmqpSessionSettings()
                {
                    Properties = new Fields()
                };

                AmqpSession amqpSession = amqpConnection.CreateSession(sessionSettings);
                token.ThrowIfCancellationRequested();
                await amqpSession.OpenAsync(timeoutHelper.RemainingTime());

                // This adds itself to amqpConnection.Extensions
                var cbsLink = new AmqpCbsLink(amqpConnection);
                return(amqpSession);
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                if (amqpConnection.TerminalException != null)
                {
                    throw AmqpClientHelper.ToIotHubClientContract(amqpConnection.TerminalException);
                }

                amqpConnection.SafeClose(ex);
                throw;
            }
        }
            public async Task ReadAsync(TimeSpan timeout)
            {
                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
                do
                {
                    this.TcpClient.Client.ReceiveTimeout = GetSocketTimeoutInMilliSeconds(timeoutHelper.RemainingTime());
                    this.bytesRead = 0;

                    this.bytesRead = await this.Stream.ReadAsync(this.Buffer, this.TotalBytesRead, this.Buffer.Length - this.TotalBytesRead);

                    this.TotalBytesRead += this.bytesRead;
                    if (this.bytesRead == 0 || this.TryParseBuffer())
                    {
                        // exit the do/while loop
                        break;
                    }
                }
                while (true);

                if (this.TotalBytesRead == 0)
                {
                    var socketException = new SocketException((int)SocketError.ConnectionRefused);
                    throw Fx.Exception.AsWarning(new IOException(socketException.Message, socketException));
                }
            }
        public async Task <SendingAmqpLink> CreateSendingLinkAsync(
            string path,
            IotHubConnectionString connectionString,
            string corrId,
            SendingLinkType linkType,
            TimeSpan timeout,
            CancellationToken cancellationToken)
        {
            this.OnCreateSendingLink(connectionString);

            var timeoutHelper = new TimeoutHelper(timeout);

            AmqpSession session = await this.GetSessionAsync(timeoutHelper, cancellationToken);

            var linkAddress = this.BuildLinkAddress(connectionString, path);

            var linkSettings = new AmqpLinkSettings()
            {
                Role = false,
                InitialDeliveryCount = 0,
                Target = new Target()
                {
                    Address = linkAddress.AbsoluteUri
                },
                LinkName = Guid.NewGuid().ToString("N") // Use a human readable link name to help with debugging
            };

            switch (linkType)
            {
            case SendingLinkType.TelemetryEvents:
                linkSettings.SndSettleMode = null;     // SenderSettleMode.Unsettled (null as it is the default and to avoid bytes on the wire)
                linkSettings.RcvSettleMode = null;     // (byte)ReceiverSettleMode.First (null as it is the default and to avoid bytes on the wire)
                break;

            case SendingLinkType.Methods:
            case SendingLinkType.Twin:
                linkSettings.SndSettleMode = (byte)SenderSettleMode.Settled;
                linkSettings.RcvSettleMode = (byte)ReceiverSettleMode.First;
                break;
            }

            SetLinkSettingsCommonProperties(linkSettings, timeoutHelper.RemainingTime());
            if (linkType == SendingLinkType.Methods)
            {
                SetLinkSettingsCommonPropertiesForMethod(linkSettings, corrId);
            }
            else if (linkType == SendingLinkType.Twin)
            {
                SetLinkSettingsCommonPropertiesForTwin(linkSettings, corrId);
            }

            var link = new SendingAmqpLink(linkSettings);

            link.AttachTo(session);

            var audience = this.BuildAudience(connectionString, path);

            await this.OpenLinkAsync(link, connectionString, audience, timeoutHelper.RemainingTime(), cancellationToken);

            return(link);
        }
        public async Task <ReceivingAmqpLink> CreateReceivingLinkAsync(
            string path,
            IotHubConnectionString connectionString,
            string corrId,
            ReceivingLinkType linkType,
            uint prefetchCount,
            TimeSpan timeout,
            CancellationToken cancellationToken)
        {
            this.OnCreateReceivingLink(connectionString);

            var timeoutHelper = new TimeoutHelper(timeout);

            AmqpSession session = await this.GetSessionAsync(timeoutHelper, cancellationToken);

            var linkAddress = this.BuildLinkAddress(connectionString, path);

            var linkSettings = new AmqpLinkSettings()
            {
                Role            = true,
                TotalLinkCredit = prefetchCount,
                AutoSendFlow    = prefetchCount > 0,
                Source          = new Source()
                {
                    Address = linkAddress.AbsoluteUri
                },
                LinkName = Guid.NewGuid().ToString("N") // Use a human readable link name to help with debuggin
            };

            switch (linkType)
            {
            case ReceivingLinkType.C2DMessages:
                linkSettings.SndSettleMode = null;     // SenderSettleMode.Unsettled (null as it is the default and to avoid bytes on the wire)
                linkSettings.RcvSettleMode = (byte)ReceiverSettleMode.Second;
                break;

            case ReceivingLinkType.Methods:
            case ReceivingLinkType.Twin:
                linkSettings.SndSettleMode = (byte)SenderSettleMode.Settled;
                linkSettings.RcvSettleMode = (byte)ReceiverSettleMode.First;
                break;
            }

            SetLinkSettingsCommonProperties(linkSettings, timeoutHelper.RemainingTime());
            if (linkType == ReceivingLinkType.Methods)
            {
                SetLinkSettingsCommonPropertiesForMethod(linkSettings, corrId);
            }
            else if (linkType == ReceivingLinkType.Twin)
            {
                SetLinkSettingsCommonPropertiesForTwin(linkSettings, corrId);
            }

            var link = new ReceivingAmqpLink(linkSettings);

            link.AttachTo(session);

            var audience = this.BuildAudience(connectionString, path);

            await this.OpenLinkAsync(link, connectionString, audience, timeoutHelper.RemainingTime(), cancellationToken);

            return(link);
        }
            public async Task ReadAsync(TimeSpan timeout)
            {
                TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

                do
                {
                    this.TcpClient.Client.ReceiveTimeout = GetSocketTimeoutInMilliSeconds(timeoutHelper.RemainingTime());
                    this.bytesRead = 0;

                    this.bytesRead = await this.Stream.ReadAsync(this.Buffer, this.TotalBytesRead, this.Buffer.Length - this.TotalBytesRead);

                    this.TotalBytesRead += this.bytesRead;
                    if (this.bytesRead == 0 || this.TryParseBuffer())
                    {
                        // exit the do/while loop
                        break;
                    }
                }while (true);

                if (this.TotalBytesRead == 0)
                {
                    var socketException = new SocketException((int)SocketError.ConnectionRefused);
                    throw Fx.Exception.AsWarning(new IOException(socketException.Message, socketException));
                }
            }
        async Task <TransportBase> CreateClientWebSocketTransport(TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            Uri           websocketUri  = new Uri(WebSocketConstants.Scheme + this.ConnectionString.HostName + ":" + WebSocketConstants.SecurePort + WebSocketConstants.UriSuffix);
            var           websocket     = await this.CreateClientWebSocket(websocketUri, timeoutHelper.RemainingTime());

            return(new ClientWebSocketTransport(
                       websocket,
                       this.connectionString.IotHubName,
                       null,
                       null));
        }
        async Task <AmqpSession> CreateSessionAsync(TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            this.refreshTokenTimer.Cancel();

            var amqpSettings         = this.CreateAmqpSettings();
            var tlsTransportSettings = this.CreateTlsTransportSettings();

            var           amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
            TransportBase transport;

            if (this.useWebSocketOnly)
            {
                // Try only Amqp transport over WebSocket
                transport = await this.CreateClientWebSocketTransport(timeoutHelper.RemainingTime());
            }
            else
            {
                try
                {
                    transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime());
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        throw;
                    }

                    // Amqp transport over TCP failed. Retry Amqp transport over WebSocket
                    if (timeoutHelper.RemainingTime() != TimeSpan.Zero)
                    {
                        transport = await this.CreateClientWebSocketTransport(timeoutHelper.RemainingTime());
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            AmqpConnectionSettings amqpConnectionSettings = new AmqpConnectionSettings()
            {
                MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                ContainerId  = Guid.NewGuid().ToString("N"),
                HostName     = this.connectionString.AmqpEndpoint.Host
            };

            var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            await amqpConnection.OpenAsync(timeoutHelper.RemainingTime());

            var sessionSettings = new AmqpSessionSettings()
            {
                Properties = new Fields()
            };

            var amqpSession = amqpConnection.CreateSession(sessionSettings);
            await amqpSession.OpenAsync(timeoutHelper.RemainingTime());

            // This adds itself to amqpConnection.Extensions
            var cbsLink = new AmqpCbsLink(amqpConnection);

            await this.SendCbsTokenAsync(cbsLink, timeoutHelper.RemainingTime());

            return(amqpSession);
        }