/// <summary>
/// Creates a new connection with a custom open frame and a callback to handle remote open frame.
/// </summary>
/// <param name="address">The address of remote endpoint to connect to.</param>
/// <param name="open">If specified, it is sent to open the connection, otherwise an open frame created from the AMQP settings property is sent.</param>
/// <param name="onOpened">If specified, it is invoked when an open frame is received from the remote peer.</param>
/// <returns>A task for the connection creation operation. On success, the result is an AMQP <see cref="Connection"/></returns>
public async Task <Connection> CreateAsync(Address address, Open open = null, OnOpened onOpened = null)
{
IAsyncTransport transport;
TransportProvider provider;
if (this.transportFactories != null && this.transportFactories.TryGetValue(address.Scheme, out provider))
{
transport = await provider.CreateAsync(address);
}
else if (TcpTransport.MatchScheme(address.Scheme))
{
TcpTransport tcpTransport = new TcpTransport(this.BufferManager);
await tcpTransport.ConnectAsync(address, this);
transport = tcpTransport;
}
#if NETFX
else if (WebSocketTransport.MatchScheme(address.Scheme))
{
WebSocketTransport wsTransport = new WebSocketTransport();
await wsTransport.ConnectAsync(address, null);
transport = wsTransport;
}
#endif
else
{
throw new NotSupportedException(address.Scheme);
}
try
{
if (address.User != null)
{
SaslPlainProfile profile = new SaslPlainProfile(address.User, address.Password);
transport = await profile.OpenAsync(address.Host, this.BufferManager, transport);
}
else if (this.saslSettings != null && this.saslSettings.Profile != null)
{
transport = await this.saslSettings.Profile.OpenAsync(address.Host, this.BufferManager, transport);
}
}
catch
{
transport.Close();
throw;
}
AsyncPump pump = new AsyncPump(this.BufferManager, transport);
Connection connection = new Connection(this.BufferManager, this.AMQP, address, transport, open, onOpened);
pump.Start(connection);
return(connection);
}