/// <summary> /// Register a service /// </summary> /// <param name="svsId">A service id</param> /// <param name="ta">Thread apartment for windows default to tagThreadApartment.taNone. It is ignored on non-windows platforms</param> /// <returns>True if successful. Otherwise false if failed</returns> public virtual bool AddMe(uint svsId, tagThreadApartment ta) { m_sc.m_OnBaseRequestCame = new DOnBaseRequestCame(OnBaseCame); m_sc.m_OnChatRequestCame = new DOnChatRequestCame(OnChatCame); m_sc.m_OnChatRequestComing = new DOnChatRequestComing(OnChatComing); m_sc.m_OnClose = new DOnClose(OnClose); m_sc.m_OnFastRequestArrive = new DOnFastRequestArrive(OnFast); m_sc.m_OnHttpAuthentication = new DOnHttpAuthentication(OnHttpAuthentication); m_sc.m_OnRequestArrive = new DOnRequestArrive(OnReqArrive); m_sc.m_OnRequestProcessed = new DOnRequestProcessed(OnSRProcessed); m_sc.m_OnSwitchTo = new DOnSwitchTo(OnSwitch); m_sc.m_SlowProcess = new DSLOW_PROCESS(OnSlow); m_sc.m_OnResultsSent = new DOnResultsSent(OnResultsSent); m_sc.m_ta = ta; if (svsId > 0 && ServerCoreLoader.AddSvsContext(svsId, m_sc)) { m_svsId = svsId; lock (m_csService) { if (!m_bRegEvent) { ServerCoreLoader.SetThreadEvent(CSocketProServer.te); m_bRegEvent = true; } m_lstService.Add(this); } return(true); } return(false); }
bool StartSocketPool(uint socketsPerThread, uint threads, bool avg, tagThreadApartment ta) { if (Started) { return(true); } byte b = (byte)(avg ? 1 : 0); uint id = ClientCoreLoader.CreateSocketPool(m_spc, socketsPerThread, threads, b, ta); return(id != 0); }
/// <summary> /// Start a pool of sockets with one connection context /// </summary> /// <param name="cc">A connection context structure</param> /// <param name="socketsPerThread">The number of socket connections per thread</param> /// <param name="threads">The number of threads in a pool which defaults to the number of CPU cores</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 bool StartSocketPool(CConnectionContext cc, uint socketsPerThread, uint threads, bool avg, tagThreadApartment ta) { if (threads == 0) #if WINCE { threads = 1; } #else { threads = (uint)Environment.ProcessorCount; } #endif CConnectionContext[,] mcc = new CConnectionContext[threads, socketsPerThread]; for (uint m = 0; m < socketsPerThread; ++m) { for (uint n = 0; n < threads; ++n) { mcc[n, m] = cc; } } return(StartSocketPool(mcc, avg, ta)); }
/// <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 socket pool for replication /// </summary> /// <param name="mapQueueConn">A dictionary for message queue name and connecting context. a unique name must be specified for each of connecting contexts</param> /// <param name="rootQueueName">A string for root replication queue name. It is ignored if it is not replicable</param> /// <param name="ta">COM thread apartment; and it defaults to taNone. It is ignored on non-window platforms</param> /// <returns>True if there is at least one connection established; and false if there is no connection</returns> public virtual bool Start(Dictionary <string, CConnectionContext> mapQueueConn, string rootQueueName, tagThreadApartment ta) { CheckConnQueueName(mapQueueConn); uint n = 0; bool secure = false; int all = m_mapQueueConn.Count; if (all > 1) { ++all; } if (rootQueueName == null) { rootQueueName = ""; } rootQueueName = rootQueueName.Trim(); rootQueueName = rootQueueName.Trim(DIR_SEP); if (rootQueueName.Length == 0) { string appName = System.AppDomain.CurrentDomain.FriendlyName; int dot = appName.LastIndexOf('.'); if (dot == -1) { rootQueueName = appName; } else { rootQueueName = appName.Substring(0, dot); } } string[] vDbFullName = new string[all]; CConnectionContext[,] mcc = new CConnectionContext[1, all]; foreach (string key in m_mapQueueConn.Keys) { mcc[0, n] = m_mapQueueConn[key]; if (!secure && mcc[0, n].EncrytionMethod == tagEncryptionMethod.TLSv1) { secure = true; } vDbFullName[n] = m_rs.QueueDir + key; ++n; } if (all > 1) { CConnectionContext last = new CConnectionContext("127.0.0.1", ushort.MaxValue, "UReplication", ""); last.EncrytionMethod = secure ? tagEncryptionMethod.TLSv1 : tagEncryptionMethod.NoEncryption; mcc[0, n] = last; vDbFullName[n] = m_rs.QueueDir + rootQueueName; } EndProcess(vDbFullName, secure, mcc, ta); return(m_pool.ConnectedSockets > 0); }
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(); } }
/// <summary> /// Start a pool of sockets with one connection context /// </summary> /// <param name="cc">A connection context structure</param> /// <param name="socketsPerThread">The number of socket connections per thread</param> /// <param name="threads">The number of threads in a pool which defaults to 1</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 bool StartSocketPool(CConnectionContext cc, uint socketsPerThread, uint threads, bool avg, tagThreadApartment ta) { if (threads == 0) { threads = 1; } CConnectionContext[,] mcc = new CConnectionContext[threads, socketsPerThread]; for (uint m = 0; m < socketsPerThread; ++m) { for (uint n = 0; n < threads; ++n) { mcc[n, m] = cc; } } return(StartSocketPool(mcc, avg, ta)); }
/// <summary> /// Construct a CSqlReplication instance /// </summary> /// <param name="qms">A structure for setting its underlying socket pool and message queue directory as well as password for source queue</param> /// <param name="mapQueueConn">A dictionary for message queue name and connecting context. a unique name must be specified for each of connecting contexts</param> /// <param name="ta">COM thread apartment; and it defaults to taNone. It is ignored on non-window platforms</param> public CSqlReplication(ReplicationSetting qms, Dictionary <string, CConnectionContext> mapQueueConn, tagThreadApartment ta) : base(qms) { string[] parts = Utilities.GetObjectParts(Utilities.GetDbFullName()); Start(mapQueueConn, parts[2] + "_qroot", ta); }
public ServiceAttr(uint svsId, tagThreadApartment ta) { ServiceID = svsId; ThreadApartment = ta; }
internal static extern uint CreateSocketPool(SocketPoolCallback spc, uint maxSocketsPerThread, uint maxThreads, [MarshalAs(UnmanagedType.I1)]byte bAvg, tagThreadApartment ta);
internal static extern uint CreateSocketPool(SocketPoolCallback spc, uint maxSocketsPerThread, uint maxThreads, [MarshalAs(UnmanagedType.I1)] byte bAvg, tagThreadApartment ta);
/// <summary> /// Register a service /// </summary> /// <param name="svsId">A service id</param> /// <param name="ta">Thread apartment for windows default to tagThreadApartment.taNone. It is ignored on non-windows platforms</param> /// <returns>True if successful. Otherwise false if failed</returns> public virtual bool AddMe(uint svsId, tagThreadApartment ta) { m_sc.m_OnBaseRequestCame = new DOnBaseRequestCame(OnBaseCame); m_sc.m_OnChatRequestCame = new DOnChatRequestCame(OnChatCame); m_sc.m_OnChatRequestComing = new DOnChatRequestComing(OnChatComing); m_sc.m_OnClose = new DOnClose(OnClose); m_sc.m_OnFastRequestArrive = new DOnFastRequestArrive(OnFast); m_sc.m_OnHttpAuthentication = new DOnHttpAuthentication(OnHttpAuthentication); m_sc.m_OnRequestArrive = new DOnRequestArrive(OnReqArrive); m_sc.m_OnRequestProcessed = new DOnRequestProcessed(OnSRProcessed); m_sc.m_OnSwitchTo = new DOnSwitchTo(OnSwitch); m_sc.m_SlowProcess = new DSLOW_PROCESS(OnSlow); m_sc.m_OnResultsSent = new DOnResultsSent(OnResultsSent); m_sc.m_ta = ta; if (svsId > 0 && ServerCoreLoader.AddSvsContext(svsId, m_sc)) { m_svsId = svsId; lock (m_csService) { m_lstService.Add(this); } return true; } return false; }