/// <summary> /// 更改指定索引的负载 /// </summary> /// <param name="nIndex">m_ThreadLoad's Index</param> /// <param name="newWeight">新权重</param> /// <returns></returns> public int ChangeWeight(int idxHeap, long newWeight) { //lock (m_lock) { int ret = 0; try { _elements[idxHeap].Weight = newWeight; if (idxHeap > HEAP0 && _elements[idxHeap].Weight <= _elements[idxHeap >> 1].Weight) { ret = UpHeap(idxHeap); } else { ret = DownHeap(idxHeap); } } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "MinHeap::ChangeWeight(", idxHeap.ToString(), ",", newWeight.ToString(), "):", ex.Message); } return(ret); } }
/// <summary> /// 发送完毕后处理 /// </summary> /// <param name="e"></param> public void ProcessSend(SocketAsyncEventArgs e) { try { e.SetBuffer(null, 0, 0);// 清理发送缓冲区 this.waitSendLen = 0; #region 发送速度检测 long timeSpanTicks = DateTime.Now.Ticks - this.sendBeginTicks; if (timeSpanTicks > CommuEngine.MAX_WAIT_SEND_COMPLETE_TIME)//10s { this.Break(CommuBreak.CLIENT_PROC_SLOW); } else { CommuEngine.Instance.AddEvent(this.commuParam.socketId, EventType.Event_SendComplet); } #endregion } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, ex.ToString()); } }
public int Push(T t) { if (this._capacity <= this._sizeUse) { this._capacity <<= 1;//扩容 T[] newElements = new T[this._capacity]; this._elements.CopyTo(newElements, 0); this._elements = newElements; #if PROFILE LogEngine.Write(LOGTYPE.INFO, "MinHeap Push:", this._capacity.ToString()); #endif } int idxNew = this._sizeUse++; this._elements[idxNew] = t; t.HeapIndex = idxNew; if (idxNew > HEAP0) { //TODO:临时加日志和校验,确定没有问题了,要去掉 int ret = UpHeap(idxNew); if (ret < 1) { LogEngine.Write(LOGTYPE.ERROR, "Push Fail"); } return(ret); } else { return(idxNew); } }
public static bool Prepend(string poolName, string key, string value, int liveSecs = UnExpired, bool compress = false) { try { if (liveSecs < 0) { return(false); } if (liveSecs == 0) { liveSecs = UnExpired; } DateTime expired = DateTime.Now.AddSeconds(liveSecs); MemcachedClient mc = MemcacheItem.GetInstance(poolName); mc.PoolName = poolName; mc.EnableCompression = compress; return(mc.Prepend(key, value, expired)); } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "MemcacheItem Prepend ex:", ex.ToString()); return(false); } }
/// <summary> /// 处理连接 /// </summary> /// <param name="e"></param> private void ProcessAccept(SocketAsyncEventArgs e) { try { if (e.AcceptSocket != null && e.AcceptSocket.Connected) { try { IPEndPoint ipepAcceptAddress = (IPEndPoint)e.AcceptSocket.RemoteEndPoint; if (CommuEngine.Instance.WhiteIps != null && !CommuEngine.Instance.WhiteIps.Contains(ipepAcceptAddress.Address.ToString())) { e.AcceptSocket.Close(); LogEngine.Write(LOGTYPE.DEBUG, "Reject Client Connect:", ipepAcceptAddress.Address.ToString()); } else { DuplexSocketEvent duplexSocket = CommuEngine.Instance.GetFreeDuplexSocket(); if (duplexSocket != null) { duplexSocket.eReceive.AcceptSocket = duplexSocket.eSend.AcceptSocket = e.AcceptSocket; duplexSocket.commuParam.ip = ipepAcceptAddress.Address.ToString(); duplexSocket.commuParam.port = ipepAcceptAddress.Port; CommuEngine.Instance.AddEvent(duplexSocket.commuParam.socketId, EventType.Event_New); LogEngine.Write(LOGTYPE.DEBUG, "Client Connect:", duplexSocket.commuParam.ip); } else { //e.AcceptSocket.Shutdown(SocketShutdown.Both); e.AcceptSocket.Close(); LogEngine.Write(LOGTYPE.DEBUG, "Server Full"); } } e.AcceptSocket = null; } catch (Exception) { //LogEngine.Write(LOGTYPE.ERROR, ex.ToString()); } } } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "ProcessAccept:", ex.ToString()); } finally { this.StartAccept(ref e); } }
public static bool Delete(string poolName, string key) { try { MemcachedClient mc = MemcacheItem.GetInstance(poolName); mc.PoolName = poolName; return(mc.Delete(key)); } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "MemcacheItem Delete ex:", ex.ToString()); return(false); } }
public static bool DeleteAferExpire(string poolName, string key, int expireSecs) { try { MemcachedClient mc = MemcacheItem.GetInstance(poolName); mc.PoolName = poolName; return(mc.Delete(key, DateTime.Now.AddSeconds(expireSecs))); } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "MemcacheItem DeleteAferExpire ex:", ex.ToString()); return(false); } }
public static Dictionary <string, byte[]> Gets_Bytes(string poolName, ref Dictionary <string, long> cass, params string[] keys) { try { MemcachedClient mc = MemcacheItem.GetInstance(poolName); mc.EnableCompression = false; mc.PoolName = poolName; return(mc.Gets_Bytes(keys, ref cass)); } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "MemcacheItem Gets_Bytes ex:", ex.ToString()); return(null); } }
public static byte[] Get_Bytes(string poolName, string key, bool compress = false) { try { MemcachedClient mc = MemcacheItem.GetInstance(poolName); mc.EnableCompression = compress; mc.PoolName = poolName; return(mc.Get_Bytes(key)); } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "MemcacheItem Get_Bytes ex:", ex.ToString()); return(null); } }
/// <summary> /// @brief 将指定的二进制数据放在request中Post到指定的uri中 /// @return /// 非null:已二进制数组方式返回response body中的数据 /// null:response body没有返回数据 /// </summary> /// <param name="uri"></param> /// <param name="requestData"></param> /// <param name="keepAlive"> /// true:Connection:Keep-Alive /// false:Connection:Close /// </param> /// <returns></returns> public static byte[] PostHttpRequest(string uri, byte[] requestData, bool keepAlive = false) { if (string.IsNullOrEmpty(uri) || requestData == null || requestData.Length < 1) { throw new Exception("uri\requestData must not be null"); } System.Net.HttpWebRequest request = null; byte[] ret = null; try { request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri); request.Method = "POST"; request.KeepAlive = keepAlive; request.ContentType = "application/octet-stream"; request.ServicePoint.Expect100Continue = false; request.UserAgent = "WLLibrary"; request.ContentLength = requestData.Length; System.IO.Stream streamRequest = request.GetRequestStream(); streamRequest.Write(requestData, 0, requestData.Length); streamRequest.Close(); //回复 System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse(); System.IO.Stream responseStream = response.GetResponseStream(); BinaryReader binaryReader = new BinaryReader(responseStream); if (response.ContentLength > 0) { ret = new byte[response.ContentLength]; responseStream.Read(ret, 0, ret.Length); } responseStream.Close(); response.Close(); } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "PostHttpRequest:", ex.ToString()); } finally { if (request != null) { request.Abort(); } } return(ret); }
/// <summary> /// 接收数据 /// </summary> /// <param name="e"></param> public void ProcessReceive(SocketAsyncEventArgs e) { try { if (e.SocketError != SocketError.Success || e.BytesTransferred < 1) { if (e.SocketError == SocketError.ConnectionReset) { this.Break(CommuBreak.CLIENT_RST); } else if (e.SocketError == SocketError.OperationAborted) { //do nothing } else { this.Break(CommuBreak.CLIENT); } } else { if (!this._isReceived) { this._isReceived = true; } if ((this._idxFreeRecv + e.BytesTransferred) > this._offsetRecv) { this.Break(CommuBreak.SERVER_PROC_SLOW); } else { if (AfterReceive(e.BytesTransferred)) { if (e.AcceptSocket != null && !e.AcceptSocket.ReceiveAsync(e)) { this.ProcessReceive(e); } } } } } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, ex.ToString()); } }
/// <summary> /// 接收数据 /// </summary> /// <param name="e"></param> public void ProcessReceive(SocketAsyncEventArgs e) { try { if (e.SocketError != SocketError.Success || e.BytesTransferred < 1) { if (e.SocketError == SocketError.ConnectionReset) { this.Break(CommuBreak.CLIENT_RST); } else if (e.SocketError == SocketError.OperationAborted) { //do nothing } else { this.Break(CommuBreak.CLIENT); LogEngine.Write(LOGTYPE.DEBUG, "Http(", this.commuParam.socketId.ToString(), ") Receive Close:", e.SocketError.ToString()); } } else { if (!this._isReceived) { this._isReceived = true; } if (AfterReceive(e.BytesTransferred)) { if (e.AcceptSocket != null && !e.AcceptSocket.ReceiveAsync(e)) { this.ProcessReceive(e); } } } } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, ex.ToString()); } }
public bool PopRoot() { if (this._sizeUse <= HEAP0) { return(true); } if (this._sizeUse - HEAP0 > 1) { this._elements[HEAP0] = this._elements[--this._sizeUse]; if (DownHeap(HEAP0) < 1) { //TODO:临时加日志和校验,确定没有问题了,要去掉 LogEngine.Write(LOGTYPE.ERROR, "PopRoot Fail"); return(false); } } else { this._sizeUse--; } return(true); }
public static DataRow DeSerialToDataRow(byte[] src) { //table name length(1 bytes) //table name //columns num(2 bytes) //row num(4 bytes) //each column type(1 bytes) //each column name length(1 bytes) //each column name //注意:datetime 使用ticks但是只保留秒部分的数据,精确度只到秒 //each data length(4 bytes only for string,other type don't have this) //each data byte tableLen = 0, columnLen = 0, columnType = 0; Int16 columnNum = 0; int rowNum = 0; string tableName = string.Empty, columnName = string.Empty; DataTable dtNew = null; DataRow drNew = null; byte[] columnTypes = null; try { int idxRead = 0; tableLen = src[idxRead++]; tableName = Encoding.UTF8.GetString(src, idxRead, tableLen); idxRead += tableLen; dtNew = new DataTable(); dtNew.TableName = tableName; columnNum = BitConverter.ToInt16(src, idxRead); idxRead += 2; rowNum = BitConverter.ToInt32(src, idxRead); idxRead += 4; #region 列信息拆包 columnTypes = new byte[columnNum]; for (int i = 0; i < columnNum; i++) { columnType = src[idxRead++]; columnTypes[i] = columnType; columnLen = src[idxRead++]; columnName = Encoding.UTF8.GetString(src, idxRead, columnLen); idxRead += columnLen; dtNew.Columns.Add(columnName, GetColumnType(columnType)); } #endregion #region 数据拆包 for (int j = 0; j < rowNum; j++) { drNew = dtNew.NewRow(); for (int i = 0; i < columnNum; i++) { SetColumnDataByTypeBinary(columnTypes[i], drNew, i, src, ref idxRead); } dtNew.Rows.Add(drNew); } #endregion return(dtNew.Rows[0]); } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "DeSerialToDataTable:", ex.ToString()); } return(null); }
/// <summary> /// 接纳新连接,启动接收,发送,断开处理线程主体 /// </summary> public void MainLoop(object state) { int idxEngine = Convert.ToInt32(state); int numCurLoop = 0, numMaxLoop = 0; Socket socket = null; byte[] sockSendBuf = null; DuplexSocketEvent sockDup = null; UInt64 eventsOuterData = 0uL; int socketId = 0; int events = 0; byte[] sendEachBuffer = null; AsyncQueue <UInt64> eventsOuter = CommuEngine._s_CommuEngineEvents[idxEngine]; UInt64[] dataPoolOnce = new UInt64[CommuEngine.POOL_MAX_LOOP]; MinHeap <OnTimer> timerHeap = this._timerHeaps[idxEngine]; int idxBegin = idxEngine * this._ConnNumPerEngine; if (idxBegin == 0) { idxBegin = 1; } int idxEnd = (idxEngine + 1) * this._ConnNumPerEngine - 1; if (idxEnd > this._MaxConnectNum - 1) { idxEnd = this._MaxConnectNum - 1; } while (this._systemRun) { socket = null; try { numCurLoop = 0; numMaxLoop = eventsOuter.DequeueToArray(dataPoolOnce); while (numCurLoop < numMaxLoop) { eventsOuterData = dataPoolOnce[numCurLoop++]; socketId = (int)(eventsOuterData & 0x00000000FFFFFFFFL); CommuEngine._s_EventsPerSocket[socketId] |= (int)(eventsOuterData >> 32); } for (int i = idxBegin; i <= idxEnd; i++) { events = CommuEngine._s_EventsPerSocket[i]; if (events < 1) { continue; } socketId = i; CommuEngine._s_EventsPerSocket[i] = 0; sockDup = CommuEngine._s_DuplexSocketEvents[socketId]; if ((events & (int)EventType.Event_New) > 0) { #region New Connect socket = sockDup.eReceive.AcceptSocket; try { if (socket != null && !socket.ReceiveAsync(sockDup.eReceive)) { sockDup.ProcessReceive(sockDup.eReceive); } } catch (System.InvalidOperationException) { LogEngine.Write(LOGTYPE.ERROR, sockDup.SocketID.ToString(), "/s,", idxEngine.ToString(), "/idx,", sockDup.eReceive.LastOperation.ToString()); } catch (Exception ex2) { LogEngine.Write(LOGTYPE.ERROR, sockDup.SocketID.ToString(), "/s,", idxEngine.ToString(), "/idx,", ex2.Message); } OnTimer timer = new OnTimer(OnTimer.TimerHeapType.ONCE, 10 * 1000, sockDup.ConnectOnTimer); timerHeap.Push(timer); #endregion } else if ((events & (int)EventType.Event_StopCommu) > 0) { #region Stop if (sockDup.IsBreak) { continue; } try { socket = sockDup.eReceive.AcceptSocket; if (socket != null) { //socket.Shutdown(SocketShutdown.Both); socket.Close(); } } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "Event_StopCommu:", ex.ToString()); } finally { sockDup.eReceive.AcceptSocket = sockDup.eSend.AcceptSocket = null; sockDup.SetBreak(); if (sockDup.BreakCallBack != null) { sockDup.BreakCallBack(sockDup.commuParam); } } #endregion } else if ((events & (int)EventType.Event_Close) > 0) { #region Close //回收 this._DuplexSocketEventPool.Push(sockDup);//second if (!sockDup.IsBreak) { LogEngine.Write(LOGTYPE.ERROR, "Get Event_StopCommu,But Target Not Break:", sockDup.SocketID.ToString(), "/sid"); } #endregion } else { sockDup = CommuEngine._s_DuplexSocketEvents[socketId]; if (sockDup.IsBreak) { continue; } //if ((events & Event_Receive) > 0) //{ // #region Receive // #endregion //} if ((events & (int)EventType.Event_SendComplet) > 0) { #region SendComplet if (sockDup.SendPool.Count > 0) { events |= (int)EventType.Event_Send; } #endregion } if ((events & (int)EventType.Event_Send) > 0) { #region 处理发放 sockSendBuf = sockDup.SendBuffer; while (sockDup.SendPool.Count > 0) { sendEachBuffer = sockDup.SendPool.First(); #region Concat bytes if (sendEachBuffer.Length <= sockSendBuf.Length) { if (sendEachBuffer.Length <= (sockSendBuf.Length - sockDup.waitSendLen)) { sendEachBuffer = sockDup.SendPool.Dequeue(); Buffer.BlockCopy(sendEachBuffer, 0, sockSendBuf, sockDup.waitSendLen, sendEachBuffer.Length); sockDup.waitSendLen += sendEachBuffer.Length; if (sockDup.waitSendLen >= CommuEngine.MTU_SEND) { break; } } else { break; } } else { sockDup.SendPool.Dequeue();//drop data //LogEngine.Write(LOGTYPE.ERROR, "ProtocolData TooLong Max:", sockSendBuf.Length.ToString(), ",", sockDup.Profile); } #endregion } #region ProcessSend if (sockDup.waitSendLen > 0) { sockDup.eSend.SetBuffer(sockSendBuf, 0, sockDup.waitSendLen); sockDup.sendBeginTicks = DateTime.Now.Ticks; socket = sockDup.eSend.AcceptSocket; try { if (socket != null && socket.Connected && !socket.SendAsync(sockDup.eSend)) { sockDup.ProcessSend(sockDup.eSend); } } catch (SocketException) { if (sockDup.eSend.SocketError == SocketError.MessageSize) { sockDup.Break(CommuBreak.SERVER_SEND_DATA_SIZE); } else { sockDup.Break(CommuBreak.SERVER_SEND_EXPECT); } } } #endregion #endregion } } } //OnTimer while (timerHeap.Count > 0 && timerHeap.Root.Weight <= DateTime.Now.Ticks) { if (timerHeap.Root.TimeOutCallBack != null) { timerHeap.Root.TimeOutCallBack(null); } if (timerHeap.Root.Type == OnTimer.TimerHeapType.ALWAYS) { timerHeap.ChangeWeight(timerHeap.Root.HeapIndex, timerHeap.Root.RefreshWeight()); } else { timerHeap.PopRoot(); } } } catch (System.Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "CommuEngine MainLoop:", ex.ToString()); } finally { Thread.Sleep(1); } } }
/// <summary> /// @brief:关闭Socket /// @invariant:内部对Socket==null,Connected进行判断 /// </summary> public void Break(CommuBreak offline) { CommuEngine.Instance.AddEvent(this.commuParam.socketId, EventType.Event_StopCommu); LogEngine.Write(LOGTYPE.DEBUG, "Break Because:", offline.ToString(), ",", this.commuParam.socketId.ToString(), "/sid"); }
/// <summary> /// 解析接收的数据,提取核心数据和关键属性,加入缓冲 /// </summary> public bool AfterReceive(int bytesTransferred) { LogEngine.Write(LOGTYPE.DEBUG, "HTTP Request Come,SocketId:", this.commuParam.socketId.ToString(), ",bytesTransfer:", bytesTransferred.ToString()); int idxProcBg = 0, idxProcEnd = 0; if (this._idxRecvEnd > 0) { LogEngine.Write(LOGTYPE.DEBUG, "HTTP Request Come Again,SocketId:", this.commuParam.socketId.ToString(), ",bytesTransfer:", bytesTransferred.ToString()); idxProcBg = 0; Buffer.BlockCopy(this._RecvBuffer, this._RecvBuffer.Length / 2, this._RecvBuffer, this._idxRecvEnd, bytesTransferred); this._idxRecvEnd += bytesTransferred; idxProcEnd = this._idxRecvEnd; } else { idxProcBg = this._RecvBuffer.Length / 2; idxProcEnd = idxProcBg + bytesTransferred; } int lenLast = 0;//剩余等待分析的报文长度 try { if (idxProcEnd <= idxProcBg) { LogEngine.Write(LOGTYPE.DEBUG, "Http(", this.commuParam.socketId.ToString(), ") Receive Trigger,But Not Find Data,idxBg:", idxProcBg.ToString(), ",idxEd:", idxProcEnd.ToString()); return(true); } lenLast = idxProcEnd - idxProcBg; if (lenLast >= this._RecvBuffer.Length / 2) { LogEngine.Write(LOGTYPE.DEBUG, "Http(", this.commuParam.socketId.ToString(), ") Receive Datagram Too Long Than:", (this._RecvBuffer.Length / 2).ToString()); this.Break(CommuBreak.CLIENT_DATAGRAM_TOOLONG); return(false); } #region Analyse ContentLength string httpRequest = Encoding.UTF8.GetString(this._RecvBuffer, idxProcBg, lenLast); //Check \r\n\r\n int idxSplit = httpRequest.IndexOf("\r\n\r\n"); if (idxSplit >= 0) { //header may be not complet,wait for next receive string[] headerItems = httpRequest.Split(new char[] { '\r', '\n' }); int contentLength = -1; foreach (string headerItem in headerItems) { //分析出ContentType,ContentLength if (!headerItem.Equals(string.Empty)) { if ((contentLength = headerItem.ToLower().IndexOf("content-length")) > -1) { string[] contentLengths = headerItem.Split(':'); if (contentLengths.Length > 1) { contentLength = Convert.ToInt32(contentLengths[1].Trim()); if (contentLength > 0 && contentLength > this._RecvBuffer.Length / 2) { //LogEngine.Write(LOGTYPE.DEBUG, "Http(", this.commuParam.socketId.ToString(), ") Content-Length Too Long Than:", // (this._RecvBuffer.Length / 2).ToString()); this.Break(CommuBreak.CLIENT_DATAGRAM_TOOLONG); return(false); } } else { //LogEngine.Write(LOGTYPE.DEBUG, "Http(", this.commuParam.socketId.ToString(), ") AfterReceive Content-Length Not Complete:", httpRequest); } break; } } } if (contentLength == -1) { //can't find content-length sign,set length=0 contentLength = 0; } #endregion if (contentLength >= 0) { int idxRequestBodyEnd = idxProcBg + idxSplit + 3 + contentLength;//point to end index of request body if (idxRequestBodyEnd < idxProcEnd) { //LogEngine.Write(LOGTYPE.DEBUG, "Http(", this.commuParam.socketId.ToString(), ") After Receive:", httpRequest, ",Content-Length:", contentLength.ToString()); #region Build MessageData try { CommuEngine.ReceiveBuffParam receiveBuffParam = new CommuEngine.ReceiveBuffParam(); receiveBuffParam.recvBuffer = this._RecvBuffer; receiveBuffParam.idxRequestBody = idxProcBg + idxSplit + 4; receiveBuffParam.lengthRequestBody = contentLength; //this._waitHttpResponse = true; if (!AfterReceiveCallBack(this.commuParam, receiveBuffParam)) { this.Break(CommuBreak.SERVER_ANALYSE_EXPECT); return(false); } } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "AfterReceive BuildMessageData:", ex.ToString()); this.Break(CommuBreak.SERVER_ANALYSE_EXPECT); return(false); } #endregion this._idxRecvEnd = 0; lenLast = 0; } else { //LogEngine.Write(LOGTYPE.DEBUG, "Http(", this.commuParam.socketId.ToString(), ") AfterReceive Request Data Body Not Complete:", httpRequest); } } } //移动不完整的已接收数据 if (this._idxRecvEnd < 1 && lenLast > 0) { //Data Copy To RecvBuff's Cache Range Buffer.BlockCopy(this._RecvBuffer, idxProcBg, this._RecvBuffer, this._idxRecvEnd, lenLast); this._idxRecvEnd += lenLast; } } catch (Exception ex) { LogEngine.Write(LOGTYPE.ERROR, "AfterReceive:", ex.ToString()); this.Break(CommuBreak.SERVER_ANALYSE_EXPECT); return(false); } return(true); }