/// <summary> /// 判读是否可以发送数据,不能发送的原因 0表示超时, 1表示缓冲区不够, 2表示大指令数据由于缓冲区被填充过半,不再发送 /// 拆分操作发送缓冲区和异步发送调用的锁的优化版本 /// </summary> /// <param name="s"></param> /// <param name="tcpOutPacket"></param> /// <param name="canNotSendReason"></param> /// <returns></returns> public bool CanSend2(TMSKSocket s, TCPOutPacket tcpOutPacket, ref int canNotSendReason) { int cmdID = tcpOutPacket.PacketCmdID; long ticks = TimeUtil.NOW(); byte[] buffer = tcpOutPacket.GetPacketBytes(); int count = tcpOutPacket.PacketDataSize; if (null == buffer || count > buffer.Length) { return(false); } TCPManager.RecordCmdOutputDataSize(cmdID, count); int needRemainSize = _MaxBufferSize - count; bool isLargePackge = ((int)(TCPGameServerCmds.CMD_OTHER_ROLE) == cmdID); lock (BufferLock) { //判读剩下空间是否足够 if (_CurrentBufferSize >= needRemainSize) { canNotSendReason = FullBufferManager.Error_BufferFull; return(false); } else if (0 == _CurrentBufferSize) { _AddFirstPacketTicks = ticks; } if (GameManager.FlagOptimizeLock2) { //判断是否超时 if (ticks > Interlocked.Read(ref _SendTimeoutTickCount) && CanDiscardCmd(cmdID)) { canNotSendReason = FullBufferManager.Error_SendTimeOut; return(false); } } else { //判断是否超时 if (IsSendTimeOut() && CanDiscardCmd(cmdID)) { canNotSendReason = FullBufferManager.Error_SendTimeOut; return(false); } } //对于地图特效指令,当网络延迟较大时,可以不再发送 //if (_CurrentBufferSize > 1024) //{ // if ((int)(TCPGameServerCmds.CMD_SPR_NEWDECO) == cmdID) // { // canNotSendReason = FullBufferManager.Error_DiscardBigPacket; // return false; // } //} //对于 CMD_OTHER_ROLE_DATA 这种大数据指令,如果缓冲区只剩下一半,则不再发送 if (isLargePackge) { if (_CurrentBufferSize >= MaxBufferSizeForLargePackge) { canNotSendReason = FullBufferManager.Error_DiscardBigPacket; return(false); } } //改写内容的时候,锁住 DataHelper.CopyBytes(_Buffer, _CurrentBufferSize, buffer, 0, count); _CurrentBufferSize += count; //System.Diagnostics.Debug.WriteLine(String.Format("SendBufferManager add Size == {0}, _CurrentBufferSize = {1}", count, _CurrentBufferSize)); } //尝试发送 if (!GameManager.FlagSkipAddBuffCall) { if (Monitor.TryEnter(SendLock)) { bool force = (_CurrentBufferSize > ConstMinSendSize); try { //立刻尝试发送,无延迟,对于网络条件较好时,不需要等待发送 if (!GameManager.FlagSkipTrySendCall) { TrySend2(s, ticks, force); } } finally { Monitor.Exit(SendLock); } } } return(true); }
public bool CanSend2(TMSKSocket s, TCPOutPacket tcpOutPacket, ref int canNotSendReason) { int cmdID = (int)tcpOutPacket.PacketCmdID; long ticks = TimeUtil.NOW(); byte[] buffer = tcpOutPacket.GetPacketBytes(); int count = tcpOutPacket.PacketDataSize; bool result; if (buffer == null || count > buffer.Length) { result = false; } else { TCPManager.RecordCmdOutputDataSize(cmdID, (long)count); int needRemainSize = this._MaxBufferSize - count; bool isLargePackge = 110 == cmdID; lock (this.BufferLock) { if (this._CurrentBufferSize >= needRemainSize) { canNotSendReason = 1; return(false); } if (0 == this._CurrentBufferSize) { this._AddFirstPacketTicks = ticks; } if (ticks > Interlocked.Read(ref this._SendTimeoutTickCount) && this.CanDiscardCmd(cmdID)) { canNotSendReason = 0; return(false); } if (isLargePackge) { if (this._CurrentBufferSize >= SendBuffer.MaxBufferSizeForLargePackge) { canNotSendReason = 2; return(false); } } DataHelper.CopyBytes(this._Buffer, this._CurrentBufferSize, buffer, 0, count); this._CurrentBufferSize += count; } if (Monitor.TryEnter(this.SendLock)) { bool force = this._CurrentBufferSize > SendBuffer.ConstMinSendSize; try { this.TrySend2(s, ticks, force); } finally { Monitor.Exit(this.SendLock); } } result = true; } return(result); }