예제 #1
0
        public virtual bool Download(string localFile, string remoteFile, DDownload dl, DTransferring trans, DDiscarded discarded, uint flags)
        {
            if (localFile == null || localFile.Length == 0)
            {
                return(false);
            }
            if (remoteFile == null || remoteFile.Length == 0)
            {
                return(false);
            }
            CContext context = new CContext(false, flags);

            context.Download     = dl;
            context.Transferring = trans;
            context.Discarded    = discarded;
            context.FilePath     = remoteFile;
            context.LocalFile    = localFile;
            lock (m_csFile) {
                m_vContext.AddToBack(context);
                if (m_vContext.Count == 1)
                {
                    ClientCoreLoader.PostProcessing(AttachedClientSocket.Handle, 0, 0);
                    AttachedClientSocket.DoEcho(); //make sure WaitAll works correctly
                }
            }
            return(true);
        }
예제 #2
0
        protected override void OnPostProcessing(uint hint, ulong data)
        {
            CContext      ctx = null;
            CClientSocket cs  = AttachedClientSocket;

            lock (m_csFile) {
                if (m_vContext.Count > 0)
                {
                    CContext context = m_vContext[0];
                    if (context.Uploading)
                    {
                        OpenLocalRead(context);
                    }
                    else
                    {
                        OpenLocalWrite(context);
                    }
                    DAsyncResultHandler    rh = null;
                    DOnExceptionFromServer se = null;
                    if (context.HasError)
                    {
                        ctx = context;
                    }
                    else if (context.Uploading)
                    {
                        if (!SendRequest(idUpload, context.FilePath, context.Flags, context.FileSize, rh, context.Discarded, se))
                        {
                            ctx             = context;
                            context.ErrCode = cs.ErrorCode;
                            context.ErrMsg  = cs.ErrorMsg;
                        }
                    }
                    else
                    {
                        if (!SendRequest(idDownload, context.LocalFile, context.FilePath, context.Flags, context.InitSize, rh, context.Discarded, se))
                        {
                            ctx             = context;
                            context.ErrCode = cs.ErrorCode;
                            context.ErrMsg  = cs.ErrorMsg;
                        }
                    }
                }
            }
            if (ctx == null)
            {
                return;
            }
            if (ctx.Download != null)
            {
                ctx.Download(this, ctx.ErrCode, ctx.ErrMsg);
            }
            lock (m_csFile) {
                CloseFile(m_vContext.RemoveFromFront());
                if (m_vContext.Count > 0)
                {
                    ClientCoreLoader.PostProcessing(AttachedClientSocket.Handle, 0, 0);
                    AttachedClientSocket.DoEcho(); //make sure WaitAll works correctly
                }
            }
        }
예제 #3
0
        public virtual bool Download(string localFile, string remoteFile, DDownload dl, DTransferring trans, DDiscarded discarded, uint flags, DOnExceptionFromServer se)
        {
            if (localFile == null || localFile.Length == 0)
            {
                throw new ArgumentException("localFile cannot be empty");
            }
            if (remoteFile == null || remoteFile.Length == 0)
            {
                throw new ArgumentException("remoteFile cannot be empty");
            }
            CContext context = new CContext(false, flags);

            context.Download     = dl;
            context.Transferring = trans;
            context.Discarded    = discarded;
            context.FilePath     = remoteFile;
            context.LocalFile    = localFile;
            context.Se           = se;
            lock (m_csFile)
            {
                m_vContext.AddToBack(context);
                uint filesOpened = GetFilesOpened();
                if (m_MaxDownloading > filesOpened)
                {
                    ClientCoreLoader.PostProcessing(Socket.Handle, 0, 0);
                    if (filesOpened == 0)
                    {
                        Socket.DoEcho(); //make sure WaitAll works correctly
                    }
                }
            }
            return(true);
        }
예제 #4
0
            /// <summary>
            /// Seek an async handler on the min number of requests queued and its associated socket connection
            /// </summary>
            /// <returns>An async handler if found; and null or nothing if no proper queue is available</returns>
            public virtual THandler SeekByQueue()
            {
                THandler h = null;

                lock (m_cs)
                {
                    bool automerge = (ClientCoreLoader.GetQueueAutoMergeByPool(m_nPoolId) > 0);
                    foreach (CClientSocket cs in m_dicSocketHandler.Keys)
                    {
                        if (automerge && cs.ConnectionState < tagConnectionState.csSwitched)
                        {
                            continue;
                        }
                        IClientQueue cq = cs.ClientQueue;
                        if (!cq.Available || cq.JobSize > 0 /*queue is in transaction at this time*/)
                        {
                            continue;
                        }
                        if (h == null)
                        {
                            h = m_dicSocketHandler[cs];
                        }
                        else if ((cq.MessageCount < h.AttachedClientSocket.ClientQueue.MessageCount) || (cs.Connected && !h.AttachedClientSocket.Connected))
                        {
                            h = m_dicSocketHandler[cs];
                        }
                    }
                }
                return(h);
            }
예제 #5
0
            /// <summary>
            /// Seek an async handler on the min number of requests queued and its associated socket connection
            /// </summary>
            /// <returns>An async handler if found; and null or nothing if no queue is available</returns>
            public virtual THandler SeekByQueue()
            {
                THandler h = null;

                lock (m_cs)
                {
                    bool automerge = (ClientCoreLoader.GetQueueAutoMergeByPool(m_nPoolId) > 0);
                    foreach (CClientSocket cs in m_dicSocketHandler.Keys)
                    {
                        if (automerge && h != null && !cs.Connected)
                        {
                            continue;
                        }
                        if (!cs.ClientQueue.Available)
                        {
                            continue;
                        }
                        if (h == null)
                        {
                            h = m_dicSocketHandler[cs];
                        }
                        else if ((cs.ClientQueue.MessageCount < h.AttachedClientSocket.ClientQueue.MessageCount) || (cs.Connected && !h.AttachedClientSocket.Connected))
                        {
                            h = m_dicSocketHandler[cs];
                        }
                    }
                }
                return(h);
            }
예제 #6
0
        protected override void OnMergeTo(CAsyncServiceHandler to)
        {
            CStreamingFile fTo = (CStreamingFile)to;

            lock (fTo.m_csFile)
            {
                int pos   = 0;
                int count = fTo.m_vContext.Count;
                foreach (CContext cxt in fTo.m_vContext)
                {
                    if (cxt.ErrCode == 0 && cxt.ErrMsg.Length == 0 && cxt.File == null)
                    {
                        break;
                    }
                    ++pos;
                }
                lock (m_csFile)
                {
                    fTo.m_vContext.InsertRange(pos, m_vContext);
                    m_vContext.Clear();
                }
                if (count == 0 && fTo.m_vContext.Count > 0)
                {
                    ClientCoreLoader.PostProcessing(fTo.Socket.Handle, 0, 0);
                    fTo.Socket.DoEcho(); //make sure WaitAll works correctly
                }
            }
        }
예제 #7
0
            public virtual bool StartBatching()
            {
                if (m_ClientSocket == null)
                {
                    return(false);
                }
                IntPtr h = m_ClientSocket.Handle;

                return(ClientCoreLoader.StartBatching(h) != 0);
            }
예제 #8
0
            /// <summary>
            /// Lock an async handler on a given timeout.
            /// </summary>
            /// <param name="timeout">A timeout in milliseconds</param>
            /// <returns>An async handler if successful; and null or nothing if failed</returns>
            /// <remarks>You must also call the method Unlock to unlock the handler and its assocaited socket connection for reuse.</remarks>
            public virtual THandler Lock(uint timeout)
            {
                uint poolId;

                lock (m_cs)
                {
                    poolId = m_nPoolId;
                }
                return(MapToHandler(ClientCoreLoader.LockASocket(poolId, timeout, IntPtr.Zero)));
            }
예제 #9
0
            /// <summary>
            /// Lock an async handler on given thread handle and timeout.
            /// </summary>
            /// <param name="sameThreadHandle">A handle to a thread</param>
            /// <param name="timeout">A timeout in milliseconds</param>
            /// <returns>An async handler if successful; and null or nothing if failed</returns>
            /// <remarks>You must also call the method Unlock to unlock the handler and its associated socket connection for reuse.</remarks>
            public virtual THandler Lock(IntPtr sameThreadHandle, uint timeout)
            {
                uint poolId;

                lock (m_cs)
                {
                    poolId = m_nPoolId;
                }
                return(MapToHandler(ClientCoreLoader.LockASocket(poolId, timeout, sameThreadHandle)));
            }
예제 #10
0
            public virtual void AbortDequeuedMessage()
            {
                if (m_ClientSocket == null)
                {
                    return;
                }
                IntPtr h = m_ClientSocket.Handle;

                ClientCoreLoader.AbortDequeuedMessage(h);
            }
예제 #11
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);
            }
예제 #12
0
            public virtual bool Interrupt(ulong options)
            {
                if (m_ClientSocket == null)
                {
                    return(false);
                }
                IntPtr h = m_ClientSocket.Handle;

#if WINCE
                return(ClientCoreLoader.SendInterruptRequest(h, (uint)options) != 0);
#else
                return(ClientCoreLoader.SendInterruptRequest(h, options) != 0);
#endif
            }
예제 #13
0
            /// <summary>
            /// Unlock a previously locked socket to pool for reuse.
            /// </summary>
            /// <param name="handler">A previously locked socket</param>
            public virtual void Unlock(CClientSocket cs)
            {
                uint poolId;

                if (cs == null)
                {
                    return;
                }
                lock (m_cs)
                {
                    poolId = m_nPoolId;
                }
                ClientCoreLoader.UnlockASocket(poolId, cs.Handle);
            }
예제 #14
0
            /// <summary>
            /// Disconnect all connections
            /// </summary>
            /// <returns>The method always returns true.</returns>
            public bool DisconnectAll()
            {
                uint poolId;

                lock (m_cs)
                {
                    poolId = m_nPoolId;
                }
                if (poolId != 0)
                {
                    return(ClientCoreLoader.DisconnectAll(poolId) != 0);
                }
                return(true);
            }
예제 #15
0
            public virtual bool CommitBatching(bool bBatchingAtServerSide)
            {
                if (m_ClientSocket == null)
                {
                    return(false);
                }
                IntPtr h = m_ClientSocket.Handle;

                lock (m_cs)
                {
                    m_kvCallback.InsertRange(m_kvCallback.Count, m_kvBatching);
                    m_kvBatching.Clear();
                }
                return(ClientCoreLoader.CommitBatching(h, (byte)(bBatchingAtServerSide ? 1 : 0)) != 0);
            }
예제 #16
0
            /// <summary>
            /// Shut down the socket pool after all connections are disconnected.
            /// </summary>
            public virtual void ShutdownPool()
            {
                uint poolId;

                lock (m_cs)
                {
                    poolId      = m_nPoolId;
                    m_nPoolId   = 0;
                    m_ServiceId = 0;
                }
                if (poolId != 0)
                {
                    ClientCoreLoader.DestroySocketPool(poolId);
                }
            }
예제 #17
0
            static ClientCoreLoader()
            {
                switch (System.Environment.OSVersion.Platform)
                {
                case PlatformID.Win32S:
                case PlatformID.Win32NT:
                case PlatformID.Win32Windows:
                case PlatformID.WinCE:
                case PlatformID.Xbox:
                    break;

                default:
                    ClientCoreLoader.UseUTF16();
                    break;
                }
            }
예제 #18
0
            public virtual bool WaitAll(uint timeOut)
            {
                if (m_ClientSocket == null)
                {
                    return(false);
                }
                IntPtr h = m_ClientSocket.Handle;

                if (ClientCoreLoader.IsBatching(h) != 0)
                {
                    throw new InvalidOperationException("Can't call the method WaitAll during batching requests");
                }
                if (ClientCoreLoader.IsQueueStarted(h) != 0 && ClientCoreLoader.GetJobSize(h) > 0)
                {
                    throw new InvalidOperationException("Can't call the method WaitAll during enqueuing transactional requests");
                }
                return(ClientCoreLoader.WaitAll(h, timeOut) != 0);
            }
예제 #19
0
            public virtual bool AbortBatching()
            {
                if (m_ClientSocket == null)
                {
                    return(false);
                }
                IntPtr h = m_ClientSocket.Handle;

                lock (m_cs)
                {
                    foreach (MyKeyValue <ushort, CResultCb> p in m_kvBatching)
                    {
                        if (p.Value.Discarded != null)
                        {
                            p.Value.Discarded.Invoke(this, true);
                        }
                    }
                    m_kvBatching.Clear();
                }
                return(ClientCoreLoader.AbortBatching(h) != 0);
            }
예제 #20
0
            protected virtual bool SendRouteeResult(byte[] data, uint len, ushort reqId)
            {
                if (m_ClientSocket == null)
                {
                    return(false);
                }
                IntPtr h = m_ClientSocket.Handle;

                if (reqId == 0)
                {
                    reqId = m_ClientSocket.CurrentRequestID;
                }
                unsafe
                {
                    if (data != null && len > (uint)data.Length)
                        len = (uint)data.Length;
                    fixed(byte *buffer = data)
                    {
                        return(ClientCoreLoader.SendRouteeResult(h, reqId, buffer, len) != 0);
                    }
                }
            }
예제 #21
0
        public virtual Task <ErrInfo> upload(string localFile, string remoteFile, DTransferring trans = null, uint flags = FILE_OPEN_TRUNCACTED)
        {
            if (localFile == null || localFile.Length == 0)
            {
                throw new ArgumentException("localFile cannot be empty");
            }
            if (remoteFile == null || remoteFile.Length == 0)
            {
                throw new ArgumentException("remoteFile cannot be empty");
            }
            TaskCompletionSource <ErrInfo> tcs = new TaskCompletionSource <ErrInfo>();
            CContext context = new CContext(false, flags);

            context.Download = (file, res, em) =>
            {
                tcs.TrySetResult(new ErrInfo(res, em));
            };
            context.Transferring = trans;
            context.Discarded    = get_aborted(tcs, idUpload);
            context.FilePath     = remoteFile;
            context.LocalFile    = localFile;
            context.Se           = get_se(tcs);
            context.Fut          = tcs;
            lock (m_csFile)
            {
                m_vContext.AddToBack(context);
                uint filesOpened = GetFilesOpened();
                if (m_MaxDownloading > filesOpened)
                {
                    ClientCoreLoader.PostProcessing(Socket.Handle, 0, 0);
                    if (filesOpened == 0)
                    {
                        Socket.DoEcho(); //make sure WaitAll works correctly
                    }
                }
            }
            return(tcs.Task);
        }
예제 #22
0
            private void OnSPEvent(uint poolId, tagSocketPoolEvent spe, IntPtr h)
            {
                THandler handler = MapToHandler(h);

                switch (spe)
                {
                case tagSocketPoolEvent.speTimer:
                    if (CScopeUQueue.MemoryConsumed / 1024 > CScopeUQueue.SHARED_BUFFER_CLEAN_SIZE)
                    {
                        CScopeUQueue.DestroyUQueuePool();
                    }
                    break;

                case tagSocketPoolEvent.speStarted:
                    lock (m_cs)
                    {
                        m_nPoolId = poolId;
                    }
                    break;

                case tagSocketPoolEvent.speShutdown:
                    lock (m_cs)
                    {
                        m_dicSocketHandler.Clear();
                    }
                    break;

                case tagSocketPoolEvent.speUSocketCreated:
                {
                    CClientSocket cs = new CClientSocket();
                    cs.Set(h);
                    ClientCoreLoader.SetRecvTimeout(h, m_recvTimeout);
                    ClientCoreLoader.SetConnTimeout(h, m_connTimeout);
                    ClientCoreLoader.SetAutoConn(h, (byte)(m_autoConn ? 1 : 0));
                    handler = new THandler();
                    if (handler.SvsID == 0)
                    {
                        handler.m_nServiceId = m_ServiceId;
                    }
                    if (handler.SvsID <= SocketProAdapter.BaseServiceID.sidStartup)
                    {
                        throw new InvalidOperationException("Service id must be larger than SocketProAdapter.BaseServiceID.sidStartup");
                    }
                    handler.Attach(cs);
                    lock (m_cs)
                    {
                        m_dicSocketHandler[cs] = handler;
                    }
                }
                break;

                case tagSocketPoolEvent.speUSocketKilled:
                    if (handler != null)
                    {
                        lock (m_cs)
                        {
                            m_dicSocketHandler.Remove(handler.AttachedClientSocket);
                        }
                    }
                    break;

                case tagSocketPoolEvent.speConnecting:
                    break;

                case tagSocketPoolEvent.speConnected:
                    if (ClientCoreLoader.IsOpened(h) != 0)
                    {
                        CClientSocket cs = handler.AttachedClientSocket;
                        if (DoSslServerAuthentication != null && cs.EncryptionMethod == tagEncryptionMethod.TLSv1 && !DoSslServerAuthentication.Invoke(this, cs))
                        {
                            return;     //don't set password or call SwitchTo in case failure of ssl server authentication on certificate from server
                        }
                        ClientCoreLoader.SetSockOpt(h, tagSocketOption.soRcvBuf, 116800, tagSocketLevel.slSocket);
                        ClientCoreLoader.SetSockOpt(h, tagSocketOption.soSndBuf, 116800, tagSocketLevel.slSocket);
                        ClientCoreLoader.SetSockOpt(h, tagSocketOption.soTcpNoDelay, 1, tagSocketLevel.slTcp);
                        ClientCoreLoader.SetPassword(h, cs.ConnectionContext.GetPassword());
                        bool ok = ClientCoreLoader.StartBatching(h) != 0;
                        ok = ClientCoreLoader.SwitchTo(h, handler.SvsID) != 0;
                        ok = ClientCoreLoader.TurnOnZipAtSvr(h, (byte)(cs.ConnectionContext.Zip ? 1 : 0)) != 0;
                        ok = ClientCoreLoader.SetSockOptAtSvr(h, tagSocketOption.soRcvBuf, 116800, tagSocketLevel.slSocket) != 0;
                        ok = ClientCoreLoader.SetSockOptAtSvr(h, tagSocketOption.soSndBuf, 116800, tagSocketLevel.slSocket) != 0;
                        ok = ClientCoreLoader.SetSockOptAtSvr(h, tagSocketOption.soTcpNoDelay, 1, tagSocketLevel.slTcp) != 0;
                        ok = (ClientCoreLoader.CommitBatching(h, (byte)0) != 0);
                    }
                    break;

                case tagSocketPoolEvent.speQueueMergedFrom:
                    m_pHFrom = MapToHandler(h);
#if DEBUG
                    IClientQueue cq        = m_pHFrom.AttachedClientSocket.ClientQueue;
                    uint         remaining = (uint)m_pHFrom.RequestsQueued;
                    if (cq.MessageCount != remaining)
                    {
                        Console.WriteLine("From: Messages = {0}, remaining requests = {1}", cq.MessageCount, remaining);
                    }
#endif
                    break;

                case tagSocketPoolEvent.speQueueMergedTo:
                {
                    THandler to = MapToHandler(h);
                    m_pHFrom.AppendTo(to);
                    m_pHFrom = null;
                }
                break;

                default:
                    break;
                }
                if (SocketPoolEvent != null)
                {
                    SocketPoolEvent.Invoke(this, spe, handler);
                }
                OnSocketPoolEvent(spe, handler);
                if (spe == tagSocketPoolEvent.speConnected && ClientCoreLoader.IsOpened(h) != 0)
                {
                    SetQueue(handler.AttachedClientSocket);
                }
            }
예제 #23
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);
            }
예제 #24
0
            public virtual bool SendRequest(ushort reqId, byte[] data, uint len, DAsyncResultHandler ash, DDiscarded discarded, DOnExceptionFromServer exception)
            {
                bool sent;
                byte batching;
                MyKeyValue <ushort, CResultCb> kv;

                if (reqId <= (ushort)tagBaseRequestID.idReservedTwo)
                {
                    throw new ArgumentException("Request id must be larger than 0x2001");
                }
                if (null == m_ClientSocket)
                {
                    return(false);
                }
                IntPtr h = m_ClientSocket.Handle;

                if (data != null && len > (uint)data.Length)
                {
                    len = (uint)data.Length;
                }
                if (ash != null || discarded != null || exception != null)
                {
                    CResultCb rcb = new CResultCb(ash, discarded, exception);
                    kv       = new MyKeyValue <ushort, CResultCb>(reqId, rcb);
                    batching = ClientCoreLoader.IsBatching(h);
                    lock (m_csSend)
                    {
                        lock (m_cs)
                        {
                            if (batching != 0)
                            {
                                m_kvBatching.AddToBack(kv);
                            }
                            else
                            {
                                m_kvCallback.AddToBack(kv);
                            }
                        }
                        unsafe
                        {
                            fixed(byte *buffer = data)
                            {
                                sent = (ClientCoreLoader.SendRequest(h, reqId, buffer, len) != 0);
                            }
                        }
                    }
                }
                else
                {
                    kv       = null;
                    batching = 0;
                    unsafe
                    {
                        fixed(byte *buffer = data)
                        {
                            sent = (ClientCoreLoader.SendRequest(h, reqId, buffer, len) != 0);
                        }
                    }
                }
                if (sent)
                {
                    return(true);
                }
                if (kv != null)
                {
                    lock (m_cs)
                    {
                        if (batching > 0)
                        {
                            m_kvBatching.Clear();
                        }
                        else
                        {
                            m_kvCallback.Clear();
                        }
                    }
                }
                return(false);
            }
예제 #25
0
            private void OnSPEvent(uint poolId, tagSocketPoolEvent spe, IntPtr h)
            {
                THandler handler = MapToHandler(h);

                switch (spe)
                {
                case tagSocketPoolEvent.speTimer:
                    //Console.WriteLine("Timer running = " + poolId + ", thread id = " + System.Threading.Thread.CurrentThread.ManagedThreadId);
                    break;

                case tagSocketPoolEvent.speStarted:
                    lock (m_cs)
                    {
                        m_nPoolId = poolId;
                    }
                    break;

                case tagSocketPoolEvent.speShutdown:
                    lock (m_cs)
                    {
                        m_dicSocketHandler.Clear();
                    }
                    break;

                case tagSocketPoolEvent.speUSocketCreated:
                {
                    CClientSocket cs = new CClientSocket();
                    cs.Set(h);
                    ClientCoreLoader.SetRecvTimeout(h, m_recvTimeout);
                    ClientCoreLoader.SetConnTimeout(h, m_connTimeout);
                    ClientCoreLoader.SetAutoConn(h, (byte)(m_autoConn ? 1 : 0));
                    handler = new THandler();
                    if (handler.SvsID == 0)
                    {
                        handler.m_nServiceId = m_ServiceId;
                    }
                    if (handler.SvsID <= SocketProAdapter.BaseServiceID.sidStartup)
                    {
                        throw new InvalidOperationException("Service id must be larger than SocketProAdapter.BaseServiceID.sidStartup");
                    }
                    handler.Attach(cs);
                    lock (m_cs)
                    {
                        m_dicSocketHandler[cs] = handler;
                    }
                }
                break;

                case tagSocketPoolEvent.speUSocketKilled:
                    if (handler != null)
                    {
                        lock (m_cs)
                        {
                            m_dicSocketHandler.Remove(handler.AttachedClientSocket);
                        }
                    }
                    break;

                case tagSocketPoolEvent.speConnecting:
                    break;

                case tagSocketPoolEvent.speConnected:
                    if (ClientCoreLoader.IsOpened(h) != 0)
                    {
                        CClientSocket cs = handler.AttachedClientSocket;
                        if (DoSslServerAuthentication != null && cs.EncryptionMethod == tagEncryptionMethod.TLSv1 && !DoSslServerAuthentication.Invoke(this, cs))
                        {
                            return;     //don't set password or call SwitchTo in case failure of ssl server authentication on certificate from server
                        }
                        ClientCoreLoader.SetSockOpt(h, tagSocketOption.soRcvBuf, 116800, tagSocketLevel.slSocket);
                        ClientCoreLoader.SetSockOpt(h, tagSocketOption.soSndBuf, 116800, tagSocketLevel.slSocket);
                        ClientCoreLoader.SetSockOpt(h, tagSocketOption.soTcpNoDelay, 1, tagSocketLevel.slTcp);
                        ClientCoreLoader.SetPassword(h, cs.ConnectionContext.GetPassword());
                        bool ok = ClientCoreLoader.StartBatching(h) != 0;
                        ok = ClientCoreLoader.SwitchTo(h, handler.SvsID) != 0;
                        if (ok)
                        {
                            ok = ClientCoreLoader.TurnOnZipAtSvr(h, (byte)(cs.ConnectionContext.Zip ? 1 : 0)) != 0;
                            ok = ClientCoreLoader.SetSockOptAtSvr(h, tagSocketOption.soRcvBuf, 116800, tagSocketLevel.slSocket) != 0;
                            ok = ClientCoreLoader.SetSockOptAtSvr(h, tagSocketOption.soSndBuf, 116800, tagSocketLevel.slSocket) != 0;
                            ok = ClientCoreLoader.SetSockOptAtSvr(h, tagSocketOption.soTcpNoDelay, 1, tagSocketLevel.slTcp) != 0;
                        }
                        ok = ClientCoreLoader.CommitBatching(h, (byte)0) != 0;
                    }
                    break;

                case tagSocketPoolEvent.speQueueMergedFrom:
                    m_pHFrom = MapToHandler(h);
                    break;

                case tagSocketPoolEvent.speQueueMergedTo:
                {
                    THandler to = MapToHandler(h);
                    m_pHFrom.AppendTo(to);
                    m_pHFrom = null;
                }
                break;

                default:
                    break;
                }
                lock (m_cs)
                {
                    if (SocketPoolEvent != null)
                    {
                        SocketPoolEvent.Invoke(this, spe, handler);
                    }
                }
                OnSocketPoolEvent(spe, handler);
            }
예제 #26
0
            /// <summary>
            /// Seek an async handler by its associated queue file full path or raw name.
            /// </summary>
            /// <param name="queueName">queue file full path or raw name</param>
            /// <returns>An async handler if found; and null or nothing if none is found</returns>
            public virtual THandler SeekByQueue(string queueName)
            {
                THandler h = null;

                if (queueName == null || queueName.Length == 0)
                {
                    return(null);
                }
                char[] empty = { ' ', '\t', '\r', '\n' };
                queueName = queueName.Trim(empty);
                switch (System.Environment.OSVersion.Platform)
                {
                case PlatformID.Win32S:
                case PlatformID.Win32NT:
                case PlatformID.Win32Windows:
                case PlatformID.WinCE:
                case PlatformID.Xbox:
                    queueName = queueName.ToLower();
                    break;

                default:
                    break;
                }
                lock (m_cs)
                {
                    string rawName;
                    string appName;
                    unsafe
                    {
                        appName = new string((sbyte *)ClientCoreLoader.GetClientWorkDirectory());
                    }
                    foreach (CClientSocket cs in m_dicSocketHandler.Keys)
                    {
                        if (!cs.ClientQueue.Available)
                        {
                            continue;
                        }
                        if (cs.ClientQueue.Secure)
                        {
                            rawName = queueName + "_" + appName + "_1.mqc";
                        }
                        else
                        {
                            rawName = queueName + "_" + appName + "_0.mqc";
                        }
                        string queueFileName = cs.ClientQueue.QueueFileName;

                        int len    = queueFileName.Length;
                        int lenRaw = rawName.Length;
                        if (lenRaw > len)
                        {
                            continue;
                        }
                        int pos = queueFileName.LastIndexOf(rawName);

                        //queue file name with full path
                        if (pos == 0)
                        {
                            return(m_dicSocketHandler[cs]);
                        }

                        //queue raw name only
                        if ((pos + lenRaw) == len)
                        {
                            return(m_dicSocketHandler[cs]);
                        }
                    }
                }
                return(h);
            }