void OnAcceptTransport(TransportListener innerListener, TransportAsyncCallbackArgs args) { TransportBase transport = args.Transport; AmqpConnection connection = null; string operation = "Create"; try { AmqpSettings amqpSettings = this.listener.AmqpSettings; // no need to clone ProtocolHeader header = (ProtocolHeader)args.UserToken; AmqpConnectionSettings settings = this.connectionSettings.Clone(); connection = this.runtime.CreateConnection(transport, header, false, this.listener.AmqpSettings, settings); operation = "BeginOpen"; connection.BeginOpen(AmqpConstants.DefaultTimeout, OnConnectionOpenComplete, Tuple.Create(this, innerListener, connection)); } catch (Exception ex) when(!Fx.IsFatal(ex)) { AmqpTrace.Provider.AmqpLogError(innerListener, operation, ex); if (connection != null) { connection.SafeClose(ex); } else { transport.Abort(); } } }
public OpenCbsRequestResponseLinkAsyncResult(AmqpConnection connection, TimeSpan timeout, AsyncCallback callback, object state) : base(timeout, callback, state) { this.connection = connection; this.Start(); }
internal static void Trace(this ProtocolHeader header, bool send, AmqpConnection connection) { if (!AmqpTrace.AmqpDebug) { return; } string message = string.Format( "{0} [{1:X3}.{2:X3} {3:HH:mm:ss.fff}] {4} {5}", AppDomain.CurrentDomain.FriendlyName, Process.GetCurrentProcess().Id, Environment.CurrentManagedThreadId, DateTime.UtcNow, send ? "SEND" : "RECV", header.ToString()); if (AmqpTrace.TraceCallback != null) { AmqpTrace.TraceCallback(message); } else { System.Diagnostics.Trace.WriteLine(message); } }
public TimedHeartBeat(AmqpConnection connection, uint interval) { this.connection = connection; this.lastReceiveTime = DateTime.UtcNow; this.lastSendTime = DateTime.UtcNow; this.heartBeatInterval = (int)(interval * 7 / 8); this.heartBeatTimer = new Timer(OnHeartBeatTimer, this, this.heartBeatInterval, Timeout.Infinite); }
void OnConnectionClosed(object sender, EventArgs args) { AmqpConnection connection = (AmqpConnection)sender; lock (this.connections) { this.connections.Remove(connection); } }
/// <summary> /// Initializes the CBS link. /// </summary> /// <param name="connection">The connection in which to create the links.</param> public AmqpCbsLink(AmqpConnection connection) { this.connection = connection ?? throw new ArgumentNullException(nameof(connection)); this.linkFactory = new FaultTolerantAmqpObject <RequestResponseAmqpLink>( timeout => this.CreateCbsLinkAsync(timeout), link => CloseLink(link)); this.connection.AddExtension(this); }
/// <summary> /// Constructs a new instance /// </summary> public AmqpCbsLink(AmqpConnection connection) { this.connection = connection ?? throw new ArgumentNullException(nameof(connection)); this.linkFactory = new FaultTolerantAmqpObject <RequestResponseAmqpLink>( t => TaskHelpers.CreateTask <RequestResponseAmqpLink>((c, s) => this.BeginCreateCbsLink(t, c, s), this.EndCreateCbsLink), link => CloseLink(link)); this.connection.Extensions.Add(this); }
public TimedHeartBeat(AmqpConnection connection, uint local, uint remote) { Fx.Assert(local > 0 || remote > 0, "At least one idle timeout must be set"); this.connection = connection; this.lastReceiveTime = this.lastSendTime = DateTime.UtcNow; this.localInterval = local; this.remoteInterval = remote < uint.MaxValue ? remote * 7 / 8 : uint.MaxValue; this.heartBeatTimer = new Timer(OnHeartBeatTimer, this, GetTimerInterval(this.lastSendTime), Timeout.InfiniteTimeSpan); }
/// <summary> /// Trys to get an object from a connection's extension. /// </summary> /// <typeparam name="T">The object type.</typeparam> /// <param name="connection">The connection.</param> /// <param name="extension">The extension object.</param> /// <returns>true if the object is found or false otherwise.</returns> public static bool TryGetExtension <T>(this AmqpConnection connection, out T extension) { if (connection.Extensions.TryGetValue(typeof(T), out object obj)) { extension = (T)obj; return(true); } extension = default(T); return(false); }
public static void Trace(this object target, bool send, AmqpConnection connection, ushort channel, Performative performative, int payload) { if (AmqpDebug) { if (PerformativeTraceCallback != null) { PerformativeTraceCallback(send, connection, channel, performative, payload); } else { Trace(target, send); } } }
/// <summary> /// Constructs a new instance /// </summary> public AmqpCbsLink(AmqpConnection connection) { if (connection == null) { throw Fx.Exception.ArgumentNull("connection"); } this.connection = connection; this.FaultTolerantLink = new FaultTolerantAmqpObject <RequestResponseAmqpLink>( t => TaskHelpers.CreateTask <RequestResponseAmqpLink>((c, s) => this.BeginCreateCbsLink(t, c, s), this.EndCreateCbsLink), this.CloseLink); this.connection.Extensions.Add(this); }
internal static void Trace(this Frame frame, bool send, AmqpConnection connection) { if (!AmqpTrace.AmqpDebug) { return; } if (AmqpTrace.FrameCallback != null) { AmqpTrace.FrameCallback(send, connection, frame); } else { StringBuilder sb = new StringBuilder(1024); sb.AppendFormat( "{0} [{1:X3}.{2:X3} {3:HH:mm:ss.fff}] {4} FRM({5:X4}|{6}|{7}|{8:X2}", AppDomain.CurrentDomain.FriendlyName, Process.GetCurrentProcess().Id, Environment.CurrentManagedThreadId, DateTime.UtcNow, send ? "SEND" : "RECV", frame.Size, frame.DataOffset, frame.Type, frame.Channel); if (frame.Command != null) { sb.Append(' '); sb.Append(frame.Command); } if (frame.Payload.Count > 0) { sb.Append(' '); frame.Payload.GetString(128, sb); } sb.Append(')'); if (AmqpTrace.TraceCallback != null) { AmqpTrace.TraceCallback(sb.ToString()); } else { System.Diagnostics.Trace.WriteLine(sb.ToString()); } } }
/// <summary> /// Initializes the session object. /// </summary> /// <param name="type">A prefix to the session name for debugging purposes.</param> /// <param name="connection">The connection in which the session is created.</param> /// <param name="settings">The session settings.</param> /// <param name="linkFactory">The factory to create <see cref="AmqpLink"/> objects when an <see cref="Attach"/> frame is received.</param> protected AmqpSession(string type, AmqpConnection connection, AmqpSessionSettings settings, ILinkFactory linkFactory) : base(type) { Fx.Assert(connection != null, "connection must not be null"); Fx.Assert(settings != null, "settings must not be null"); this.connection = connection; this.settings = settings; this.linkFactory = linkFactory; this.State = AmqpObjectState.Start; this.links = new Dictionary <string, AmqpLink>(); this.linksByLocalHandle = new HandleTable <AmqpLink>(settings.HandleMax ?? AmqpConstants.DefaultMaxLinkHandles - 1); this.linksByRemoteHandle = new HandleTable <AmqpLink>(settings.HandleMax ?? AmqpConstants.DefaultMaxLinkHandles - 1); this.outgoingChannel = new OutgoingSessionChannel(this); this.incomingChannel = new IncomingSessionChannel(this); }
protected AmqpSession(string type, AmqpConnection connection, AmqpSessionSettings settings, ILinkFactory linkFactory) : base(type) { Fx.Assert(connection != null, "connection must not be null"); Fx.Assert(settings != null, "settings must not be null"); this.connection = connection; this.settings = settings; this.linkFactory = linkFactory; this.State = AmqpObjectState.Start; this.links = new Dictionary<string, AmqpLink>(); this.linksByLocalHandle = new HandleTable<AmqpLink>(settings.HandleMax ?? AmqpConstants.DefaultMaxLinkHandles - 1); this.linksByRemoteHandle = new HandleTable<AmqpLink>(settings.HandleMax ?? AmqpConstants.DefaultMaxLinkHandles - 1); this.outgoingChannel = new OutgoingSessionChannel(this); this.incomingChannel = new IncomingSessionChannel(this); }
static void OnSessionClosed(object sender, EventArgs e) { AmqpSession session = (AmqpSession)sender; AmqpConnection thisPtr = session.Connection; if (thisPtr != null) { lock (thisPtr.ThisLock) { thisPtr.sessionsByLocalHandle.Remove(session.LocalChannel); if (session.RemoteChannel.HasValue) { thisPtr.sessionsByRemoteHandle.Remove(session.RemoteChannel.Value); } } AmqpTrace.Provider.AmqpRemoveSession(thisPtr, session, session.LocalChannel, session.CachedRemoteChannel); } }
static void OnConnectionOpenComplete(IAsyncResult result) { var tuple = (Tuple <AmqpConnectionListener, TransportListener, AmqpConnection>)result.AsyncState; AmqpConnectionListener thisPtr = tuple.Item1; TransportListener innerListener = tuple.Item2; AmqpConnection connection = tuple.Item3; try { connection.EndOpen(result); lock (thisPtr.connections) { thisPtr.connections.Add(connection); } connection.SafeAddClosed(thisPtr.onConnectionClosed); } catch (Exception ex) when(!Fx.IsFatal(ex)) { AmqpTrace.Provider.AmqpLogError(connection, "EndOpen", ex); connection.SafeClose(ex); } }
AmqpSession ISessionFactory.CreateSession(AmqpConnection connection, AmqpSessionSettings sessionSettings) { return(new AmqpSession(this, sessionSettings, this.amqpSettings.RuntimeProvider)); }
async Task<AmqpSession> CreateSessionAsync(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); this.refreshTokenTimer.Cancel(); var amqpSettings = this.CreateAmqpSettings(); TransportBase transport; if (this.useWebSocketOnly) { // Try only Amqp transport over WebSocket transport = await this.CreateClientWebSocketTransport(timeoutHelper.RemainingTime()); } else { var tlsTransportSettings = this.CreateTlsTransportSettings(); var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings); 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; }
/// <summary> /// Called when a connection is closing or aborting. /// </summary> /// <param name="connection">The connection.</param> /// <param name="abort">true if the connection is aborted.</param> public virtual void AmqpCloseConnection(AmqpConnection connection, bool abort) { }
public static HeartBeat Initialize(AmqpConnection connection, uint interval) { Fx.Assert(interval < uint.MaxValue, "invalid interval"); return(new TimedHeartBeat(connection, interval)); }
/// <summary> /// Opens a connection to the specified address. /// </summary> /// <param name="addressUri">The address Uri. User info is ignored.</param> /// <param name="saslHandler">The SASL handler which determines the SASL mechanism. Null means no SASL handshake.</param> /// <param name="timeout">The operation timeout.</param> /// <returns>An AMQP connection.</returns> public async Task <AmqpConnection> OpenConnectionAsync(Uri addressUri, SaslHandler saslHandler, TimeSpan timeout) { TransportSettings transportSettings; if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqp, StringComparison.OrdinalIgnoreCase)) { transportSettings = new TcpTransportSettings() { Host = addressUri.Host, Port = addressUri.Port > -1 ? addressUri.Port : AmqpConstants.DefaultPort }; } else if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqps, StringComparison.OrdinalIgnoreCase)) { TcpTransportSettings tcpSettings = new TcpTransportSettings() { Host = addressUri.Host, Port = addressUri.Port > -1 ? addressUri.Port : AmqpConstants.DefaultSecurePort }; var tls = new TlsTransportSettings(tcpSettings) { TargetHost = addressUri.Host }; TlsTransportProvider tlsProvider = this.settings.GetTransportProvider <TlsTransportProvider>(); if (tlsProvider != null) { tls.CertificateValidationCallback = tlsProvider.Settings.CertificateValidationCallback; tls.CheckCertificateRevocation = tlsProvider.Settings.CheckCertificateRevocation; tls.Certificate = tlsProvider.Settings.Certificate; tls.Protocols = tlsProvider.Settings.Protocols; } transportSettings = tls; } else if (addressUri.Scheme.Equals(WebSocketTransportSettings.WebSockets, StringComparison.OrdinalIgnoreCase) || addressUri.Scheme.Equals(WebSocketTransportSettings.SecureWebSockets, StringComparison.OrdinalIgnoreCase)) { transportSettings = new WebSocketTransportSettings() { Uri = addressUri }; } else { throw new NotSupportedException(addressUri.Scheme); } AmqpSettings settings = this.settings.Clone(); settings.TransportProviders.Clear(); if (saslHandler != null) { // Provider for "AMQP3100" SaslTransportProvider saslProvider = new SaslTransportProvider(AmqpVersion.V100); saslProvider.AddHandler(saslHandler); settings.TransportProviders.Add(saslProvider); } // Provider for "AMQP0100" AmqpTransportProvider amqpProvider = new AmqpTransportProvider(AmqpVersion.V100); settings.TransportProviders.Add(amqpProvider); AmqpTransportInitiator initiator = new AmqpTransportInitiator(settings, transportSettings); TransportBase transport = await Task.Factory.FromAsync( (c, s) => initiator.BeginConnect(timeout, c, s), (r) => initiator.EndConnect(r), null).ConfigureAwait(false); try { AmqpConnectionSettings connectionSettings = new AmqpConnectionSettings() { ContainerId = Guid.NewGuid().ToString(), HostName = addressUri.Host }; AmqpConnection connection = new AmqpConnection(transport, settings, connectionSettings); await connection.OpenAsync(timeout).ConfigureAwait(false); return(connection); } catch { transport.Abort(); throw; } }
/// <summary> /// Adds an object to a connection's extension. /// </summary> /// <param name="connection">The connection.</param> /// <param name="extension">The extension object.</param> public static void AddExtension(this AmqpConnection connection, object extension) { connection.Extensions.Add(extension.GetType(), extension); }
/// <summary> /// Called when a channel number is not found in a connection or a link handle is not found in a session. /// </summary> /// <param name="connection">The connection.</param> /// <param name="session">Null if it is for a session channel, or the session of the missing link handle.</param> /// <param name="type">Type of the handle ("session" or "link").</param> /// <param name="handle">The session channel or the link handle.</param> public virtual void AmqpMissingHandle(AmqpConnection connection, AmqpSession session, string type, uint handle) { }
public static HeartBeat Initialize(AmqpConnection connection, uint local, uint remote) { return(new TimedHeartBeat(connection, local, remote)); }
public static HeartBeat Initialize(AmqpConnection connection, uint local, uint remote) { return new TimedHeartBeat(connection, local, remote); }
public AmqpSession(AmqpConnection connection, AmqpSessionSettings settings, ILinkFactory linkFactory) : this("session", connection, settings, linkFactory) { }
protected virtual async Task<AmqpSession> CreateSessionAsync(TimeSpan timeout) { this.OnCreateSession(); var timeoutHelper = new TimeoutHelper(timeout); AmqpSettings amqpSettings = CreateAmqpSettings(); TransportBase transport; switch (this.AmqpTransportSettings.GetTransportType()) { #if !WINDOWS_UWP 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); 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); return amqpSession; }
AmqpSession ISessionFactory.CreateSession(AmqpConnection connection, AmqpSessionSettings sessionSettings) { return new AmqpSession(this, sessionSettings, this.amqpSettings.RuntimeProvider); }
/// <summary> /// Called when a connection is opening. /// </summary> /// <param name="connection">The connection.</param> public virtual void AmqpOpenConnection(AmqpConnection connection) { }
public AmqpSession CreateSession(AmqpConnection connection, AmqpSessionSettings settings) { throw new InvalidOperationException(); }
public async Task <AmqpConnection> OpenConnectionAsync(Uri addressUri, SaslHandler saslHandler, TimeSpan timeout) { TransportSettings transportSettings; if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqp, StringComparison.OrdinalIgnoreCase)) { transportSettings = new TcpTransportSettings() { Host = addressUri.Host, Port = addressUri.Port > -1 ? addressUri.Port : AmqpConstants.DefaultPort }; } else if (addressUri.Scheme.Equals(AmqpConstants.SchemeAmqps, StringComparison.OrdinalIgnoreCase)) { TcpTransportSettings tcpSettings = new TcpTransportSettings() { Host = addressUri.Host, Port = addressUri.Port > -1 ? addressUri.Port : AmqpConstants.DefaultSecurePort }; transportSettings = new TlsTransportSettings(tcpSettings) { TargetHost = addressUri.Host }; } #if NET45 else if (addressUri.Scheme.Equals(WebSocketTransport.WebSockets, StringComparison.OrdinalIgnoreCase) || addressUri.Scheme.Equals(WebSocketTransport.SecureWebSockets, StringComparison.OrdinalIgnoreCase)) { transportSettings = new WebSocketTransportSettings() { Uri = addressUri }; } #endif else { throw new NotSupportedException(addressUri.Scheme); } AmqpSettings settings = new AmqpSettings(); if (saslHandler != null) { // Provider for "AMQP3100" SaslTransportProvider saslProvider = new SaslTransportProvider(); saslProvider.Versions.Add(new AmqpVersion(1, 0, 0)); saslProvider.AddHandler(saslHandler); settings.TransportProviders.Add(saslProvider); } // Provider for "AMQP0100" AmqpTransportProvider amqpProvider = new AmqpTransportProvider(); amqpProvider.Versions.Add(new AmqpVersion(new Version(1, 0, 0, 0))); settings.TransportProviders.Add(amqpProvider); AmqpTransportInitiator initiator = new AmqpTransportInitiator(settings, transportSettings); TransportBase transport = await Task.Factory.FromAsync( (c, s) => initiator.BeginConnect(timeout, c, s), (r) => initiator.EndConnect(r), null); try { AmqpConnectionSettings connectionSettings = new AmqpConnectionSettings() { ContainerId = Guid.NewGuid().ToString(), HostName = addressUri.Host }; AmqpConnection connection = new AmqpConnection(transport, settings, connectionSettings); await connection.OpenAsync(timeout); return(connection); } catch { transport.Abort(); throw; } }
/// <summary> /// Called when a session is being added to a connection. /// </summary> /// <param name="connection">The connection.</param> /// <param name="session">The session.</param> /// <param name="localChannel">Local channel number of the session.</param> /// <param name="remoteChannel">Remote channel number of the session.</param> public virtual void AmqpAddSession(AmqpConnection connection, AmqpSession session, ushort localChannel, ushort remoteChannel) { }
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); var transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime()); 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; }
public TimedHeartBeat(AmqpConnection connection, uint local, uint remote) { Fx.Assert(local > 0 || remote > 0, "At least one idle timeout must be set"); this.connection = connection; this.lastReceiveTime = this.lastSendTime = DateTime.UtcNow; this.localInterval = local; this.remoteInterval = remote < uint.MaxValue ? remote * 7 / 8 : uint.MaxValue; this.heartBeatTimer = new Timer(OnHeartBeatTimer, this, Timeout.Infinite, Timeout.Infinite); this.SetTimer(this.lastSendTime); }
/// <summary> /// Initializes the session object. /// </summary> /// <param name="connection">The connection in which the session is created.</param> /// <param name="settings">The session settings.</param> /// <param name="linkFactory">The factory to create <see cref="AmqpLink"/> objects when an <see cref="Attach"/> frame is received.</param> public AmqpSession(AmqpConnection connection, AmqpSessionSettings settings, ILinkFactory linkFactory) : this("session", connection, settings, linkFactory) { }
async Task<AmqpSession> CreateSessionAsync(TimeSpan timeout) { var timeoutHelper = new TimeoutHelper(timeout); this.refreshTokenTimer.Cancel(); AmqpSettings amqpSettings = this.CreateAmqpSettings(); TlsTransportSettings tlsTransportSettings = this.CreateTlsTransportSettings(); var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings); TransportBase transport; switch (this.amqpTransportSettings.GetTransportType()) { case TransportType.Amqp_WebSocket_Only: transport = await this.CreateClientWebSocketTransport(timeoutHelper.RemainingTime()); break; case TransportType.Amqp_Tcp_Only: 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.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; }