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

📄 tcpcacheprovider.cs

📁 HeyCacher 高性能缓存方案(带源码) 1. 文件的所有权益归上传用户所有 2. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途 3. CSDN下载频道仅提供交流平台
💻 CS
📖 第 1 页 / 共 2 页
字号:
//===============================================================================
// CSDN HeyCache 
//===============================================================================
// 修改记录:[按最后修改时间倒排序]
// modify: 2007.06.14 by tangwei 
// create: 2007.06.11 by tangwei
//
// 代码来源:tangwei
//===============================================================================
namespace HeyCacher.Providers
{
    using System;
    using System.Text;
    using System.Threading;
    using System.Net.Sockets;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using HeyCacher.Components;
    using HeyCacher.Components.Scavenger;
    using HeyCacher.Components.Expirations;
    using System.Collections;
    using System.IO;

    /// <summary>
    /// 基于Tcp通讯的缓存实现
    /// </summary>
    public class TcpCacheProvider : CacheProvider
    {
        Cnlamar.Pool.ObjectPool<NetClient> pool; //连接对象池

        #region 初始化
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="name"></param>
        /// <param name="config"></param>
        public override void Initialize(string name, NameValueCollection config)
        {
            //
            int ScavengInSeconds = 10; //资源回收间隔时间,单位为秒
            int PoolCreateSize = 2;
            int PoolMaxSize = 100;
            string ServerAddress = "127.0.0.1";
            int Port = 8750;
            int ReConnectTimespan = 60;
            int SendTimeout = -1;
            int ReceiveTimeout = -1;
            int SendBufferSize = -1;

            #region 初始化配置
            base.Initialize(name, config);
            try
            {
                if (config != null)
                {
                    if (config["PoolCreateSize"] != null)
                    {
                        PoolCreateSize = int.Parse(config["PoolCreateSize"]);
                        config.Remove("PoolCreateSize");
                    }
                    if (config["PoolMaxSize"] != null)
                    {
                        PoolMaxSize = int.Parse(config["PoolMaxSize"]);
                        config.Remove("PoolMaxSize");
                    }
                    if (config["ServerAddress"] != null)
                    {
                        ServerAddress = config["ServerAddress"];
                        config.Remove("ServerAddress");
                    }
                    if (config["Port"] != null)
                    {
                        Port = int.Parse(config["Port"]);
                        config.Remove("Port");
                    }
                    if (config["ReConnectTimespan"] != null)
                    {
                        ReConnectTimespan = int.Parse(config["ReConnectTimespan"]);
                        config.Remove("ReConnectTimespan");
                    }
                    if (config["SendTimeout"] != null)
                    {
                        SendTimeout = int.Parse(config["SendTimeout"]);
                        config.Remove("SendTimeout");
                    }
                    if (config["ReceiveTimeout"] != null)
                    {
                        ReceiveTimeout = int.Parse(config["ReceiveTimeout"]);
                        config.Remove("ReceiveTimeout");
                    }
                    if (config["SendBufferSize"] != null)
                    {
                        SendBufferSize = int.Parse(config["SendBufferSize"]);
                        config.Remove("SendBufferSize");
                    }
                    if (config["ScavengInSeconds"] != null)
                    {
                        ScavengInSeconds = int.Parse(config["ScavengInSeconds"]);
                        config.Remove("ScavengInSeconds");
                    }
                }
            }
            catch
            {
            }
            #endregion

            //建立连接对象池
            try
            {
                NetClientParam netClientParam = new NetClientParam(ServerAddress, Port, ReConnectTimespan, SendTimeout, ReceiveTimeout, SendBufferSize, base.Encoding);
                pool = new Cnlamar.Pool.ObjectPool<NetClient>(netClientParam, PoolCreateSize, PoolMaxSize);
            }
            catch
            {
            }

            //建立各种回收任务与控制器对象,并启动
            ExpirationTask expirationTask = new ExpirationTask(this);
            BackgroundScheduler scheduler = new BackgroundScheduler(expirationTask);
            scheduler.Start();

            //启动回收定时器
            ScavengerTimer timer = new ScavengerTimer();
            //timer.StartPolling(new TimerCallback(scheduler.ExpirationTimeoutExpired), ScavengInSeconds); //系统线程池定时器
            timer.StartPolling(new System.Timers.ElapsedEventHandler(scheduler.ExpirationTimeoutExpired), ScavengInSeconds); //普通定时器
        }
        #endregion

        #region Count
        /// <summary>
        /// 
        /// </summary>
        public override int Count
        {
            get
            {
                string ResultString = String.Empty;
                NetClient nc = null;
                try
                {
                    nc = pool.Get();
                    ResultString = base.Encoding.GetString(nc.Send("Count", null, null, XmlSerialize, false));
                }
                catch { }
                finally
                {
                    if (nc != null)
                    {
                        pool.FreeObject(nc);
                    }
                }
                int count = -1;
                int.TryParse(ResultString, out count);
                return count;
            }
        }
        #endregion

        #region Contains
        public override bool Contains(string Key, CacheTack cacheTack)
        {
            //获取
            string ResultString = String.Empty;
            NetClient nc = null;
            try
            {
                nc = pool.Get();
                ResultString = base.Encoding.GetString(nc.SendString("Contains", Key, cacheTack, XmlSerialize, false));
            }
            catch (Exception ex)
            {
                Caches.log.Error("执行Tcp缓存客户端中的Contains方法时出现未知错误。", ex);
            }
            finally
            {
                if (nc != null)
                {
                    pool.FreeObject(nc);
                }
            }

            return ResultString[0] == 1;
        }
        #endregion

        #region Get
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Key"></param>
        /// <returns></returns>
        public override CacheItem GetCacheItem(string Key, CacheTack cacheTack)
        {
            #region 更新本地依赖
            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)
            {
                //过期
                if (expirationItemBeforeLock.HasExpired())
                {
                    expirationItemBeforeLock.TouchedByUserAction(true);

                    ExpirationItemTable.Remove(Key);

                    realRemove(Key, cacheTack);
                    return null;
                }
            }

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

            return innerGet(Key, cacheTack);
        }
        private CacheItem innerGet(string Key, CacheTack cacheTack)
        {
            //获取
            byte[] ResultBytes = null;
            NetClient nc = null;
            try
            {
                string Cmd = "Get";
                if (DataCompress)
                {
                    Cmd += "_C";
                }

                nc = pool.Get();
                ResultBytes = nc.SendString(Cmd, Key, cacheTack, XmlSerialize, DataCompress);
            }
            catch (Exception ex)
            {
                Caches.log.Error("执行Tcp缓存客户端中的innerGet方法时出现未知错误。", ex);
            }
            finally
            {
                if (nc != null)
                {
                    pool.FreeObject(nc);
                }
            }

            CacheItem ci = null;
            try
            {
                object obj = null;
                obj = Cnlamar.Serialization.Deserialize(ResultBytes, XmlSerialize, DataCompress);
                ci = obj as CacheItem;

                //解封value
                ci.DeserializeValue();
            }
            catch(Exception ex)
            {
                Caches.log.Error("执行Tcp缓存客户端中的innerGet方法,并在做反序列化操作的时候,出现未知错误。", ex);
            }
            return ci;
        }
        #endregion

        #region innerInsert
        protected override object innerInsert(bool Replace, CacheItem ci, CacheTack cacheTack, out bool Insertd)
        {
            Insertd = false; //是否被插入

            //
            string Cmd;
            if (Replace)
            {
                Cmd = "Set";
            }
            else
            {
                Cmd = "Add";
            }
            if (DataCompress)
            {
                Cmd += "_C";
            }

            //
            CacheItem resultCI = innerInsert(Cmd, ci, cacheTack);
            if (resultCI == null)
            {
                return null;
            }
            Insertd = true;

            //判断返回
            return resultCI.realValue;
        }
        private CacheItem innerInsert(string cmd, CacheItem ci, CacheTack cacheTack)
        {
            //建立缓存策略副本
            ICacheItemExpiration[] RemoteExpirations;
            InsertCacheItemExpiration(ci.Key, ci.Priority, ci.RefreshAction, ci.Expirations, out RemoteExpirations);

            //封装value
            ci.SerializeValue();

            //建立缓存项
            byte[] CacheData = Cnlamar.Serialization.Serialize(ci, XmlSerialize, DataCompress);

            //发送命令
            string ResultString = String.Empty;
            NetClient nc = null;
            try
            {
                nc = pool.Get();
                byte[] result = nc.Send(cmd, CacheData, cacheTack, XmlSerialize, DataCompress);
                if (result != null)
                {
                    ResultString = base.Encoding.GetString(result);
                }
            }
            catch (System.Net.Sockets.SocketException ex)
            {
                //套接字错误,通常是服务器无法连接
                Caches.log.Error("执行Tcp缓存客户端中的innerInsert方法时出现SocketException错误。", ex);
            }
            catch (Exception ex)
            {
                //其他错误,未知错误
                Caches.log.Error("执行Tcp缓存客户端中的innerInsert方法时出现未知错误。", ex);
            }
            finally
            {
                if (nc != null)
                {
                    pool.FreeObject(nc);
                }
            }

            //判断反馈
            if (String.IsNullOrEmpty(ResultString) || ResultString[0] != '1')
            {
                return null;
            }

            return ci;
        }
        private void InsertCacheItemExpiration(string key, HeyCacher.Components.CacheItemPriority priority, object RefreshAction, ICacheItemExpiration[] expirations, out ICacheItemExpiration[] RemoteExpirations)
        {
            RemoteExpirations = null; //远程过期策略

            //如果过期规则为空,则不建立本地本地过期策略
            if (expirations == null)
            {
                return;
            }

            //整理本地与远程过期策略
            List<ICacheItemExpiration> LocalExpirationsList = new List<ICacheItemExpiration>();
            List<ICacheItemExpiration> RemoteExpirationsList = new List<ICacheItemExpiration>();
            foreach (ICacheItemExpiration tmpExpiration in expirations)
            {
                if (tmpExpiration is INetCacheItemExpiration)
                {
                    bool IsLocal = false;
                    foreach (string DependencyMark in ((INetCacheItemExpiration)tmpExpiration).AvailableIn())
                    {
                        if (DependencyMark == AppSetting.Mark)
                        {
                            IsLocal = true;
                            break;
                        }
                    }
                    if (IsLocal)
                    {
                        LocalExpirationsList.Add(tmpExpiration);
                    }
                    else
                    {
                        RemoteExpirationsList.Add(tmpExpiration);
                    }
                }
                else if (tmpExpiration != null)
                {

⌨️ 快捷键说明

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