Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        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);
        }