📄 tcpcacheprovider.cs
字号:
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 + -