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); }