Exemple #1
0
 /// <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);
 }
Exemple #2
0
            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);
            }
Exemple #3
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));
            }
Exemple #4
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>
            /// <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);
            }
Exemple #5
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);
        }
Exemple #6
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();
            }
        }
Exemple #7
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 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));
 }
Exemple #8
0
 /// <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);
 }
Exemple #9
0
 public ServiceAttr(uint svsId, tagThreadApartment ta)
 {
     ServiceID = svsId;
     ThreadApartment = ta;
 }
Exemple #10
0
 internal static extern uint CreateSocketPool(SocketPoolCallback spc, uint maxSocketsPerThread, uint maxThreads, [MarshalAs(UnmanagedType.I1)]byte bAvg, tagThreadApartment ta);
Exemple #11
0
 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);
Exemple #13
0
 /// <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;
 }