/// <summary> /// Sends a message asynchronously. /// </summary> /// <param name="message">The message to send.</param> /// <param name="timeout">The time to wait for the task to complete.</param> /// <returns>A Task for the asynchronous send operation.</returns> public async Task SendAsync(Message message, TimeSpan timeout) { DeliveryState txnState = null; #if NETFX || NETFX40 txnState = await TaskExtensions.GetTransactionalStateAsync(this); #endif try { await new SendTask(this, message, txnState, timeout).Task; } catch (TimeoutException) { this.OnTimeout(message); throw; } }
public async Task ConnectAsync(Address address, ConnectionFactory factory) { IPAddress[] ipAddresses; IPAddress ip; if (IPAddress.TryParse(address.Host, out ip)) { ipAddresses = new IPAddress[] { ip }; } else { ipAddresses = await TaskExtensions.GetHostAddressesAsync(address.Host); } // need to handle both IPv4 and IPv6 Socket socket = null; Exception exception = null; for (int i = 0; i < ipAddresses.Length; i++) { if (ipAddresses[i] == null || (ipAddresses[i].AddressFamily == AddressFamily.InterNetwork && !Socket.OSSupportsIPv4) || (ipAddresses[i].AddressFamily == AddressFamily.InterNetworkV6 && !Socket.OSSupportsIPv6)) { continue; } socket = new Socket(ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { await socket.ConnectAsync(ipAddresses[i], address.Port); exception = null; break; } catch (Exception e) { exception = e; socket.Dispose(); socket = null; } } if (socket == null) { throw exception ?? new SocketException((int)SocketError.AddressNotAvailable); } if (factory.tcpSettings != null) { factory.tcpSettings.Configure(socket); } IAsyncTransport transport; if (address.UseSsl) { SslStream sslStream; var ssl = factory.SslInternal; if (ssl == null) { sslStream = new SslStream(new NetworkStream(socket)); await sslStream.AuthenticateAsClientAsync(address.Host); } else { sslStream = new SslStream(new NetworkStream(socket), false, ssl.RemoteCertificateValidationCallback, ssl.LocalCertificateSelectionCallback); await sslStream.AuthenticateAsClientAsync(address.Host, ssl.ClientCertificates, ssl.Protocols, ssl.CheckCertificateRevocation); } transport = new SslSocket(this, sslStream); } else { transport = new TcpSocket(this, socket); } this.socketTransport = transport; this.writer = new Writer(this, this.socketTransport); }