public void TestAcceptLast() { string xml = "<remote-addresses xmlns=\"http://schemas.tangosol.com/cache\"><socket-address><address>127.0.0.1</address><port>80</port></socket-address><socket-address><address>127.0.0.1</address><port>81</port></socket-address></remote-addresses>"; IXmlDocument config = XmlHelper.LoadXml(new StringReader(xml)); Assert.IsNotNull(config); ConfigurableAddressProviderFactory factory = new ConfigurableAddressProviderFactory(); factory.Config = config; IAddressProvider addrProvider = factory.CreateAddressProvider(); Assert.IsNotNull(addrProvider); Assert.IsInstanceOf(typeof(ConfigurableAddressProvider), addrProvider); string addrProviderString = addrProvider.ToString(); Assert.IsTrue(addrProviderString.Equals("[127.0.0.1:81,127.0.0.1:80]") || addrProviderString.Equals("[127.0.0.1:80,127.0.0.1:81]")); IPEndPoint addr = addrProvider.NextAddress; Assert.IsNotNull(addr); addrProvider.Reject(null); addr = addrProvider.NextAddress; Assert.IsNotNull(addr); addrProvider.Accept(); addr = addrProvider.NextAddress; Assert.IsNotNull(addr); }
/// <summary> /// Open and return a new Connection. /// </summary> /// <returns> /// A newly opened Connection. /// </returns> protected override Connection OpenConnection() { IAddressProvider provider = RemoteAddressProvider; Debug.Assert(provider != null); // Default value for Coherence is 0, which is an infinite timeout. // Default value for .NET IAsyncResult.WaitOne infinite timeout is -1. // So, convert the Coherence infinite value to .NET Timeout.Infinite. Int32 cMillis = (Int32)ConnectTimeout; cMillis = cMillis <= 0 ? Timeout.Infinite : cMillis; // open a new connection var addresses = new StringBuilder().Append('['); IEnumerator enmrRedirect = null; IEnumerator enmrSubport = null; IPEndPoint addrNext = null; Int32 subportNext = -1; Exception cause = null; for ( ; ;) { var connection = (TcpConnection)InstantiateConnection(); IPEndPoint addr; Int32 subport; if (enmrRedirect == null || addrNext == null) { addr = provider.NextAddress; subport = Subport; // reset redirection information enmrRedirect = null; enmrSubport = null; } else { addr = addrNext; addrNext = enmrRedirect.MoveNext() ? (IPEndPoint)enmrRedirect.Current : null; subport = subportNext; subportNext = enmrSubport.MoveNext() ? (Int32)enmrSubport.Current : -1; // update redirection information connection.IsRedirect = true; } if (addr == null) { break; } string address = NetworkUtils.ToString(addr, subport); if (RemoteAddressProvider is ConfigurableAddressProvider) { StreamProvider.RemoteAddress = ((ConfigurableAddressProvider)RemoteAddressProvider).RemoteHostAddress; } if (addresses.Length > 1) { addresses.Append(", "); } addresses.Append(address); // create and configure a new client TcpClient client = InstantiateClient(); try { if (enmrRedirect == null) { CacheFactory.Log("Connecting Socket to " + address, CacheFactory.LogLevel.Debug); } else { CacheFactory.Log("Redirecting Socket to " + address, CacheFactory.LogLevel.Debug); } IAsyncResult result = client.BeginConnect(addr.Address, addr.Port, null, null); result.AsyncWaitHandle.WaitOne(cMillis); if (!client.Connected) { CacheFactory.Log("Error connecting TcpClient to " + address + ": connection timeout", CacheFactory.LogLevel.Info); NetworkUtils.Close(client); continue; } CacheFactory.Log("Connected TcpClient to " + address, CacheFactory.LogLevel.Info); connection.Client = client; } catch (Exception e) { cause = e; CacheFactory.Log("Error connecting TcpClient to " + address + ": " + e, CacheFactory.LogLevel.Info); NetworkUtils.Close(client); // if we aren't current redirecting, or we've tried the last redirect // address, reject the last address supplied by the address provider if (enmrRedirect == null || addrNext == null) { provider.Reject(e); } continue; } // write out subport info if (subport != -1) { bool secure = connection.IsSecure; Stream stream = connection.Stream = StreamProvider.GetStream(client); if (secure) { Monitor.Enter(stream); } try { NetworkUtils.WriteSubport(stream, subport); } catch (Exception e) { CacheFactory.Log("Error connecting TcpClient to " + address + ": " + e, CacheFactory.LogLevel.Info); throw new ConnectionException(e); } finally { if (secure) { Monitor.Exit(stream); } } } try { connection.Open(); } catch (Exception e) { if (enmrRedirect == null && connection.IsRedirect) { IList list = connection.RedirectList; // create an IPEndPoint list from from the redirect list var listRedirect = new ArrayList(list.Count); var listSubport = new ArrayList(list.Count); foreach (var o in list) { var ao = (Object[])o; var s = (String)ao[0]; var port32 = new Port32((Int32)ao[1]); try { listRedirect.Add(new IPEndPoint(NetworkUtils.GetHostAddress(s, ConnectTimeout), port32.Baseport)); listSubport.Add(port32.Subport); } catch (Exception) { // invalid or unresolvable address CacheFactory.Log("Skipping unresolvable address \"" + s + "\".", CacheFactory.LogLevel.Info); } } enmrRedirect = listRedirect.GetEnumerator(); enmrSubport = listSubport.GetEnumerator(); if (enmrRedirect.MoveNext() && enmrSubport.MoveNext()) { addrNext = (IPEndPoint)enmrRedirect.Current; subportNext = (Int32)enmrSubport.Current; } else { addrNext = null; subportNext = -1; } } else { CacheFactory.Log("Error establishing a connection with " + address + ": " + e, CacheFactory.LogLevel.Info); // if we aren't current redirecting, or we've tried the last redirect // address, reject the last address supplied by the address provider if (enmrRedirect == null || addrNext == null) { provider.Reject(e); } } continue; } provider.Accept(); return(connection); } addresses.Append(']'); String message = "could not establish a connection " + "to one of the following addresses: " + addresses + "; make sure the \"remote-addresses\" configuration " + "element contains an address and port of a running " + "TcpAcceptor"; throw cause == null ? new ConnectionException(message) : new ConnectionException(message, cause); }