⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpcacheprovider.cs

📁 HeyCacher 高性能缓存方案(带源码) 1. 文件的所有权益归上传用户所有 2. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途 3. CSDN下载频道仅提供交流平台
💻 CS
📖 第 1 页 / 共 2 页
字号:
                    LocalExpirationsList.Add(tmpExpiration);
                }
            }
            ICacheItemExpiration[] LocalExpirations = null;
            if (LocalExpirationsList.Count > 0)
            {
                LocalExpirations = new ICacheItemExpiration[LocalExpirationsList.Count];
                LocalExpirationsList.CopyTo(LocalExpirations);
            }
            if (RemoteExpirationsList.Count > 0)
            {
                RemoteExpirations = new ICacheItemExpiration[RemoteExpirationsList.Count];
                RemoteExpirationsList.CopyTo(RemoteExpirations);
            }

            //建立本地过期依赖项
            lock (ExpirationItemTable.SyncRoot)
            {
                if (!ExpirationItemTable.ContainsKey(key))
                {
                    ExpirationItemTable.Add(key, new ExpirationItem(key, priority, RefreshAction, LocalExpirations));
                }
            }
        }
        #endregion

        #region Remove
        public override bool Remove(string Key, CacheTack cacheTack, CacheItemRemovedReason removalReason)
        {
            //
            bool flag = realRemove(Key, cacheTack);

            if (flag)
            {
                ExpirationItem expirationItemBeforeLock = null;

                //独占锁
                bool LockFlag;
                do
                {
                    lock (ExpirationItemTable.SyncRoot)
                    {
                        if (!ExpirationItemTable.ContainsKey(Key))
                        {
                            break;
                        }
                        expirationItemBeforeLock = (ExpirationItem)ExpirationItemTable[Key];
                        LockFlag = Monitor.TryEnter(expirationItemBeforeLock);
                    }
                    if (!LockFlag)
                    {
                        Thread.Sleep(0);
                    }
                } while (!LockFlag);

                //操作
                if (expirationItemBeforeLock != null)
                {
                    expirationItemBeforeLock.TouchedByUserAction(true);
                    ExpirationItemTable.Remove(Key);
                }

                //释放锁
                if (expirationItemBeforeLock != null)
                {
                    Monitor.Exit(expirationItemBeforeLock);
                }
            }

            return flag;
        }

        private bool realRemove(string Key, CacheTack cacheTack)
        {
            //发送remove命令
            string ResultString = String.Empty;
            NetClient nc = null;
            try
            {
                nc = pool.Get();
                ResultString = base.Encoding.GetString(nc.SendString("Remove", Key, cacheTack, XmlSerialize, false));
            }
            catch { }
            finally
            {
                if (nc != null)
                {
                    pool.FreeObject(nc);
                }
            }

            //返回
            if (String.IsNullOrEmpty(ResultString) || ResultString[0] != '1')
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        #endregion

        #region Flush
        public override void Flush()
        {
            string ResultString = base.Encoding.GetString(pool.Get().SendString("Flush", null, null, XmlSerialize, false));
            if (ResultString[0] != '1')
            {
                //异常
            }
            ExpirationItemTable = Hashtable.Synchronized(new Hashtable());
        }
        #endregion

        internal override System.Collections.IDictionaryEnumerator CreateEnumerator()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #region NetClient
        private class NetClient : Cnlamar.Pool.IDynamicObject<NetClient>
        {
            private object SyncLock = new object();
            private System.Net.Sockets.TcpClient m_tcpClient;
            private NetworkStream networkStream;

            #region IDynamicObject<MyTcpClient> 成员

            public bool IsValidate()
            {
                return m_IsValidate;
            }
            private bool m_IsValidate;

            private NetClientParam m_param;

            public Encoding Encoding
            {
                get { return m_Encoding; }
                set { m_Encoding = value; }
            }
            private Encoding m_Encoding;

            public void Create(object param)
            {
                if (param != null && param is NetClientParam)
                {
                    m_param = (NetClientParam)param;
                    m_IsValidate = true;
                    m_Encoding = m_param.Encoding;
                }
            }

            public NetClient GetInnerObject()
            {
                return this;
            }

            public void Release()
            {
                networkStream.Flush();
            }

            private void Connect()
            {
                if (m_tcpClient == null)
                {
                    m_tcpClient = new TcpClient();
                }

                if (!m_tcpClient.Connected && lastConnectFailTime.AddSeconds(m_param.ReConnectTimespan) < DateTime.Now)
                {
                    try
                    {
                        if (m_tcpClient == null)
                        {
                            m_tcpClient = new TcpClient();
                        }
                        m_tcpClient.Connect(m_param.ServerAddress, m_param.Port);
                    }
                    catch(Exception ex)
                    {
                        lastConnectFailTime = DateTime.Now;
                        m_tcpClient = null;
                        Caches.log.Error("无法连接到远程缓存服务器:" + m_param.ServerAddress + ":" + m_param.Port + "。", ex);
                        return;
                    }
                    networkStream = m_tcpClient.GetStream();
                }
            }
            private DateTime lastConnectFailTime;

            public byte[] SendString(string Cmd, string CacheKey, CacheTack cacheTack, bool XmlSerialize, bool DataCompress)
            {
                byte[] byteCacheKey = m_Encoding.GetBytes(CacheKey);

                byte[] result = Send(Cmd, byteCacheKey, cacheTack, XmlSerialize, DataCompress);
                return result;
            }
            public byte[] Send(string Cmd, byte[] byteCacheItem, CacheTack cacheTack, bool XmlSerialize, bool DataCompress)
            {
                //打开连接(实际上只打开一次,之后生存于对象池中)
                Connect();

                lock (SyncLock)
                {
                    //
                    int intCacheItemSize = 0; //发送对象的大小
                    int intCacheTackSize = 0; //发送对象的大小
                    int NeedReceiveSize = 0; //应当读取远程主机的数据量
                    int NowReceiveSize = 0; //已经读取的数据量
                    int BytesRead; //当次读到了多少字节的数据
                    byte[] ReceiveBytes = null; //存放接收数据的byte数组
                    byte[] ReceiveBuffer; //数据接收缓冲

                    //
                    byte[] CmdBytes = Encoding.ASCII.GetBytes(Cmd);//命令
                    byte[] byteCacheTack = null;
                    if (cacheTack != null)
                    {
                        byteCacheTack = Cnlamar.Serialization.Serialize(cacheTack, XmlSerialize, DataCompress);
                    }

                    //取发送数据的大小
                    if (byteCacheItem != null)
                    {
                        intCacheItemSize = byteCacheItem.Length;
                    }
                    if (byteCacheTack != null)
                    {
                        intCacheTackSize = byteCacheTack.Length;
                    }

                    //整理发送命令、数据的字节量,并根据此来建立realSendBytes
                    byte[] byteCmdSize = Encoding.ASCII.GetBytes(CmdBytes.Length.ToString());//命令长度,12字节
                    byte[] byteCacheItemSize = Encoding.ASCII.GetBytes(intCacheItemSize.ToString());//缓存项长度,12字节
                    byte[] byteCacheTackSize = Encoding.ASCII.GetBytes(intCacheTackSize.ToString());//附加信息长度,12字节
                    byte[] realSendBytes = new byte[36 + CmdBytes.Length + intCacheItemSize + intCacheTackSize]; //最终真正用于网络发送的数据

                    //合并出realSendBytes
                    Buffer.BlockCopy(byteCmdSize, 0, realSendBytes, 0, byteCmdSize.Length);
                    Buffer.BlockCopy(byteCacheItemSize, 0, realSendBytes, 12, byteCacheItemSize.Length);
                    Buffer.BlockCopy(byteCacheTackSize, 0, realSendBytes, 24, byteCacheTackSize.Length);
                    Buffer.BlockCopy(CmdBytes, 0, realSendBytes, 36, CmdBytes.Length);
                    if (byteCacheItem != null)
                    {
                        Buffer.BlockCopy(byteCacheItem, 0, realSendBytes, 36 + CmdBytes.Length, byteCacheItem.Length);
                    }
                    if (byteCacheTack != null)
                    {
                        Buffer.BlockCopy(byteCacheTack, 0, realSendBytes, 36 + CmdBytes.Length + intCacheItemSize, byteCacheTack.Length);
                    }

                    //发出数据
                    networkStream.Write(realSendBytes, 0, realSendBytes.Length);

                    //接收数据
                    while (true)
                    {
                        try
                        {
                            //取数据长度
                            if (NeedReceiveSize == 0)
                            {
                                ReceiveBuffer = new byte[12];
                                BytesRead = networkStream.Read(ReceiveBuffer, 0, 12);
                                if (BytesRead <= 0)
                                {
                                    continue;
                                }

                                if (!int.TryParse(Encoding.ASCII.GetString(ReceiveBuffer), out NeedReceiveSize))
                                {
                                    //失败
                                    break;
                                }
                                if (NeedReceiveSize <= 0)
                                {
                                    //不收数据了,此情况通常不应当发生,当错误处理
                                    break;
                                }
                                ReceiveBytes = new byte[NeedReceiveSize];
                            }

                            //取数据
                            ReceiveBuffer = new byte[m_tcpClient.ReceiveBufferSize];
                            BytesRead = networkStream.Read(ReceiveBuffer, 0, m_tcpClient.ReceiveBufferSize);
                            if (BytesRead > 0)
                            {
                                //
                                Buffer.BlockCopy(ReceiveBuffer, 0, ReceiveBytes, NowReceiveSize, BytesRead);
                                NowReceiveSize += BytesRead;

                                //数据全部获取到
                                if (NowReceiveSize == NeedReceiveSize)
                                {
                                    //将本次接收数据大小归零,下次好使用
                                    NeedReceiveSize = 0;
                                    NowReceiveSize = 0;

                                    //读完数据,退出
                                    break;
                                }
                            }
                        }
                        catch (IOException ex)
                        {
                            if (ex.InnerException is SocketException)
                            {
                                //内部引起的套接字错误的话,则退出监听
                                Caches.log.Error("Tcp缓存客户端的通讯组件内出现SocketException错误", ex.InnerException);
                                break;
                            }
                            Caches.log.Error("Tcp缓存客户端的通讯组件内出现IOException错误", ex);
                        }
                        catch (SocketException ex)
                        {
                            //套接字错误的话,则退出监听
                            Caches.log.Error("Tcp缓存客户端的通讯组件内出现SocketException错误", ex);
                            break;
                        }
                        catch (Exception ex)
                        {
                            //其他异常
                            Caches.log.Error("Tcp缓存客户端的通讯组件内出现未知错误", ex);
                            break;
                        }
                    }

                    return ReceiveBytes;
                }
            }

            #endregion

            #region IDisposable 成员

            public void Dispose()
            {
                Send("quit", null, null, false, false);
                networkStream.Close();
                m_tcpClient.Close();
            }

            #endregion
        }
        private class NetClientParam
        {
            public NetClientParam(string serverAddress, int port, int reConnectTimespan, int sendTimeout, int receiveTimeout, int sendBufferSize, Encoding encoding)
            {
                this.m_ServerAddress = serverAddress;
                this.m_Port = port;
                this.m_SendTimeout = sendTimeout;
                this.m_ReceiveTimeout = receiveTimeout;
                this.m_SendBufferSize = sendBufferSize;
                this.m_Encoding = encoding;
            }
            public string ServerAddress
            {
                get { return m_ServerAddress; }
            }
            private string m_ServerAddress = "127.0.0.1";

            public int Port
            {
                get { return m_Port; }
            }
            private int m_Port = 8750;

            public int ReConnectTimespan
            {
                get { return m_ReConnectTimespan; }
            }
            private int m_ReConnectTimespan = 60;

            public int SendTimeout
            {
                get { return m_SendTimeout; }
            }
            private int m_SendTimeout = -1;

            public int ReceiveTimeout
            {
                get { return m_ReceiveTimeout; }
            }
            private int m_ReceiveTimeout = -1;

            public int SendBufferSize
            {
                get { return m_SendBufferSize; }
            }
            private int m_SendBufferSize = -1;

            public Encoding Encoding
            {
                get { return m_Encoding; }
            }
            private Encoding m_Encoding = Encoding.Unicode;
        }
        #endregion
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -