void EndProcess(string[] vDbFullName, bool secure, CConnectionContext[,] mcc, tagThreadApartment ta) { m_pool = new CSocketPool <THandler>(!m_rs.NoAutoConn, m_rs.RecvTimeout, m_rs.ConnTimeout); if (secure) { m_pool.DoSslServerAuthentication += (sender, cs) => { if (cs.ConnectionContext.Port == ushort.MaxValue) { return(true); } return(DoSslServerAuthentication(cs)); }; } m_pool.SocketPoolEvent += (sender, spe, handler) => { switch (spe) { case tagSocketPoolEvent.speSocketClosed: handler.CleanCallbacks(); break; case tagSocketPoolEvent.speConnecting: if (handler.AttachedClientSocket.ConnectionContext.Port == ushort.MaxValue) { handler.AttachedClientSocket.ConnectingTimeout = 500; } break; default: break; } }; bool ok = m_pool.StartSocketPool(mcc, true, ta); int n = 0; foreach (CClientSocket s in m_pool.Sockets) { string key = vDbFullName[n]; ok = s.ClientQueue.StartQueue(key, m_rs.TTL, secure); ++n; } if (Replicable) { SourceQueue.EnsureAppending(TargetQueues); } THandler[] targetHandlers = TargetHandlers; foreach (THandler h in targetHandlers) { ok = h.AttachedClientSocket.DoEcho(); } }
void CopyCC(CConnectionContext[,] cc) { int threads = cc.GetLength(0); int socketsPerThread = cc.GetLength(1); if (socketsPerThread * threads == 0) { throw new InvalidOperationException("Must set connection context argument properly"); } lock (m_cs) { m_mcc = new CConnectionContext[threads, socketsPerThread]; for (uint m = 0; m < socketsPerThread; ++m) { for (uint n = 0; n < threads; ++n) { if (cc[n, m] == null) { throw new ArgumentException("Must set connection context argument properly"); } else { CConnectionContext c = new CConnectionContext(); CConnectionContext src = cc[n, m]; c.Host = src.Host; c.Password = src.GetPassword(); c.Port = src.Port; c.EncrytionMethod = src.EncrytionMethod; c.UserId = src.UserId; c.V6 = src.V6; c.Zip = src.Zip; c.AnyData = src.AnyData; m_mcc[n, m] = c; } } } } }
/// <summary> /// Start a pool of sockets with a given two-dimensional matrix of connection contexts /// </summary> /// <param name="cc">A given two-dimensional matrix of connection contexts. Its first dimension length represents the number of threads; and the second dimension length is the number of sockets per thread</param> /// <param name="avg">A boolean value for building internal socket pool, which defaults to true.</param> /// <param name="ta">A value for COM thread apartment if there is COM object involved. It is ignored on non-window platforms, and default to tagThreadApartment.taNone</param> /// <returns>False if there is no connection established; and true as long as there is one connection started</returns> public virtual bool StartSocketPool(CConnectionContext[,] cc, bool avg, tagThreadApartment ta) { bool ok; char[] empty = { ' ', '\t', '\r', '\n' }; if (cc == null || cc.Length == 0) { throw new ArgumentException("Must set connection context argument properly"); } if (Started) { ShutdownPool(); } CopyCC(cc); bool first = true; int threads = cc.GetLength(0); int socketsPerThread = cc.GetLength(1); if (!StartSocketPool((uint)socketsPerThread, (uint)threads, avg, ta)) { return(false); } Dictionary <CClientSocket, THandler> temp = new Dictionary <CClientSocket, THandler>(); lock (m_cs) { int index = 0; foreach (CClientSocket cs in m_dicSocketHandler.Keys) { temp[cs] = m_dicSocketHandler[cs]; int m = index % threads; int n = index / threads; CConnectionContext c = m_mcc[m, n]; if (c.Host == null) { throw new InvalidOperationException("Host string can not be null"); } c.Host = c.Host.Trim(empty); if (c.Host.Length == 0) { throw new InvalidOperationException("Host string must be a valid string"); } if (c.Port == 0) { throw new InvalidOperationException("Host port can't be zero"); } cs.ConnectionContext = c; ++index; } } foreach (CClientSocket cs in temp.Keys) { if (cs.Connected) { first = false; continue; } CConnectionContext c = cs.ConnectionContext; cs.UID = c.UserId; cs.EncryptionMethod = c.EncrytionMethod; cs.Zip = c.Zip; IntPtr p = cs.Handle; unsafe { fixed(byte *data = System.Text.Encoding.ASCII.GetBytes(c.Host)) { IntPtr host = new IntPtr(data); if (first) { //we use sync connecting for the first socket connection ok = ClientCoreLoader.Connect(p, host, c.Port, 1, (byte)(c.V6 ? 1 : 0)) != 0; if (ok && ClientCoreLoader.WaitAll(cs.Handle, uint.MaxValue) != 0) { first = false; } } else { ok = ClientCoreLoader.Connect(p, host, c.Port, 0, (byte)(c.V6 ? 1 : 0)) != 0; } } } } return(ConnectedSockets > 0); }
/// <summary> /// Start a pool of sockets with a given two-dimensional matrix of connection contexts /// </summary> /// <param name="cc">A given two-dimensional matrix of connection contexts. Its first dimension length represents the number of threads; and the second dimension length is the number of sockets per thread</param> /// <param name="avg">A boolean value for building internal socket pool, which defaults to true</param> /// <returns>False if there is no connection established; and true as long as there is one connection started</returns> public bool StartSocketPool(CConnectionContext[,] cc, bool avg) { return(StartSocketPool(cc, avg, tagThreadApartment.taNone)); }