Ejemplo n.º 1
0
        /// <summary>
        /// 以同步的方式更新Entity
        /// </summary>
        /// <param name="entityList"></param>
        public static bool SendSync(IEnumerable <AbstractEntity> entityList)
        {
            var keyList   = new List <byte[]>();
            var valueList = new List <byte[]>();

            foreach (var entity in entityList)
            {
                if (entity == null)
                {
                    continue;
                }
                entity.TempTimeModify = MathUtils.Now;
                string key       = GetQueueFormatKey(entity);
                var    keyValues = key.Split('_', '|');
                int    id        = AbstractEntity.DecodeKeyCode(keyValues[1]).ToInt();
                string keyCode   = keyValues[2];
                string redisKey  = string.Format("{0}_{1}", keyValues[0], keyCode);
                byte[] idBytes   = BufferUtils.GetBytes(id);
                var    keyBytes  = RedisConnectionPool.ToByteKey(redisKey);
                byte[] entityBytes;
                bool   isDelete = entity.IsDelete;
                entityBytes = _serializer.Serialize(entity);
                //modify resean: set unchange status.
                entity.Reset();

                byte[] stateBytes = BufferUtils.GetBytes(isDelete ? 1 : 0);
                byte[] values     = BufferUtils.MergeBytes(BufferUtils.GetBytes(idBytes.Length + stateBytes.Length), idBytes, stateBytes, entityBytes);
                keyList.Add(keyBytes);
                valueList.Add(values);
            }
            return(ProcessRedisSyncQueue(string.Empty, keyList.ToArray(), valueList.ToArray()));
        }
Ejemplo n.º 2
0
        protected PacketMessage ParsePacketMessage(string clientAddress, string paramString, ConnectType connectType)
        {
            ParamGeter paramGeter = new ParamGeter(paramString);
            PacketHead head       = new PacketHead(connectType, PacketMsgType.Request);

            head.Address  = clientAddress;
            head.MsgId    = paramGeter.GetInt("msgid");
            head.Uid      = paramGeter.GetInt("uid");
            head.ActionId = paramGeter.GetInt("actionId");
            string[] sidArray = paramGeter.GetString("sid").Split('|');
            if (sidArray.Length > 2)
            {
                head.GameId   = sidArray[1].ToInt();
                head.ServerId = sidArray[2].ToInt();
            }
            else
            {
                head.GameId   = paramGeter.GetInt("gametype");
                head.ServerId = paramGeter.GetInt("serverid");
            }
            head.EnableGzip = false;
            PacketMessage packet = new PacketMessage();

            packet.Head    = head;
            packet.Content = BufferUtils.GetBytes(paramString);
            return(packet);
        }
Ejemplo n.º 3
0
        public override void WriteResponse(BaseGameResponse response)
        {
            SetResponseHead();
            byte[] headBytes    = ProtoBufUtils.Serialize(_responseHead);
            byte[] contentBytes = BuildResponsePack();
            byte[] buffer       = null;
            if (contentBytes == null || contentBytes.Length == 0)
            {
                buffer = BufferUtils.AppendHeadBytes(headBytes);
            }
            else
            {
                if (actionId != 2502 &&
                    actionId != 4000)
                {
                    buffer = BufferUtils.MergeBytes(
                        BufferUtils.AppendHeadBytes(headBytes),
                        contentBytes
                        );
                }
                else
                {
                    buffer = BufferUtils.GetBytes(contentBytes);
                }
            }
            //需要对字节数据加密处理,这里跳过

            response.BinaryWrite(buffer);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Send to queue pool
        /// </summary>
        /// <param name="entityList"></param>
        public static void Send(AbstractEntity[] entityList)
        {
            string key = "";

            try
            {
                if (entityList == null || entityList.Length == 0)
                {
                    return;
                }
                var groupList = entityList.GroupBy(t => t.GetIdentityId());
                foreach (var g in groupList)
                {
                    var      valueList  = g.ToList();
                    byte[][] keyBytes   = new byte[valueList.Count][];
                    byte[][] valueBytes = new byte[valueList.Count][];
                    string   queueKey   = GetRedisSyncQueueKey(g.Key);
                    byte[]   idBytes    = BufferUtils.GetBytes(g.Key);

                    int index = 0;
                    foreach (var entity in valueList)
                    {
                        key             = string.Format("{0}_{1}", entity.GetType().FullName, entity.GetKeyCode());
                        keyBytes[index] = RedisConnectionPool.ToByteKey(key);
                        byte[] stateBytes = BufferUtils.GetBytes(entity.IsDelete ? 1 : 0);
                        valueBytes[index] = BufferUtils.MergeBytes(
                            BufferUtils.GetBytes(idBytes.Length + stateBytes.Length),
                            idBytes,
                            stateBytes,
                            ProtoBufUtils.Serialize(entity));
                        index++;
                    }
                    RedisConnectionPool.Process(client => client.HMSet(queueKey, keyBytes, valueBytes));
                }
            }
            catch (Exception ex)
            {
                TraceLog.WriteError("Post changed key:{0} error:{1}", key, ex);
            }
        }
Ejemplo n.º 5
0
        private static void OnEntitySyncQueue(object state)
        {
            if (Interlocked.CompareExchange(ref _entityQueueRunning, 1, 0) == 0)
            {
                try
                {
                    var tempRemove = Interlocked.Exchange(ref _entityRemoteSet, new HashSet <string>());
                    var temp       = Interlocked.Exchange(ref _entitySet, new HashSet <string>());
                    if (temp.Count == 0 || _queueWatchTimers == null)
                    {
                        return;
                    }
                    TraceLog.WriteWarn("OnEntitySyncQueue execute count:{0}, success:{1}/total {2}, fail:{3} start...", temp.Count, ExecuteSuccessCount, SendWaitCount, ExecuteFailCount);

                    RedisConnectionPool.Process(client =>
                    {
                        while (temp.Count > 0)
                        {
                            var dumpSet  = temp.Take(ExecuteCount).ToArray();
                            var pipeline = client.CreatePipeline();
                            try
                            {
                                bool hasPost = false;
                                foreach (var key in dumpSet)
                                {
                                    var keyValues = key.Split('_', '|');
                                    if (keyValues.Length != 3)
                                    {
                                        TraceLog.WriteWarn("OnEntitySyncQueue:{0}", key);
                                        ExecuteFailCount++;
                                        continue;
                                    }

                                    AbstractEntity entity = CacheFactory.GetPersonalEntity(key) as AbstractEntity;
                                    int id          = keyValues[1].ToInt();
                                    string keyCode  = keyValues[2];
                                    string redisKey = string.Format("{0}_{1}", keyValues[0], keyCode);
                                    string hashId   = GetRedisSyncQueueKey(id);
                                    byte[] idBytes  = BufferUtils.GetBytes(id);
                                    var keyBytes    = RedisConnectionPool.ToByteKey(redisKey);
                                    bool isDelete;
                                    byte[] entityBytes;
                                    if (entity != null)
                                    {
                                        isDelete    = entity.IsDelete;
                                        entityBytes = _serializer.Serialize(entity);
                                        //modify resean: set unchange status.
                                        entity.Reset();
                                    }
                                    else if (tempRemove.Contains(key))
                                    {
                                        entityBytes = new byte[0];
                                        isDelete    = true;
                                    }
                                    else
                                    {
                                        ExecuteFailCount++;
                                        TraceLog.WriteError("EntitySync queue key {0} faild object is null.", key);
                                        continue;
                                    }
                                    byte[] stateBytes = BufferUtils.GetBytes(isDelete ? 1 : 0);
                                    byte[] values     =
                                        BufferUtils.MergeBytes(BufferUtils.GetBytes(idBytes.Length + stateBytes.Length),
                                                               idBytes, stateBytes, entityBytes);
                                    pipeline.QueueCommand(c =>
                                    {
                                        ((RedisClient)c).HSet(hashId, keyBytes, values);
                                    });
                                    hasPost = true;
                                    ExecuteSuccessCount++;
                                }
                                if (hasPost)
                                {
                                    pipeline.Flush();
                                }
                            }
                            finally
                            {
                                pipeline.Dispose();
                            }
                            try
                            {
                                foreach (var key in dumpSet)
                                {
                                    temp.Remove(key);
                                }
                            }
                            catch (Exception)
                            {
                            }
                        }
                    });
                }
                catch (Exception ex)
                {
                    TraceLog.WriteError("EntitySync queue {0}", ex);
                }
                finally
                {
                    Interlocked.Exchange(ref _entityQueueRunning, 0);
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="dataToken"></param>
        /// <param name="buffer"></param>
        /// <param name="messageList"></param>
        /// <returns></returns>
        public override bool TryReadMeaage(DataToken dataToken, byte[] buffer, out List <DataMessage> messageList)
        {
            messageList = new List <DataMessage>();

            int  remainingBytesToProcess = buffer.Length;
            bool needPostAnother         = true;

            do
            {
                if (dataToken.prefixBytesDone < 4)
                {
                    remainingBytesToProcess = HandlePrefix(buffer, dataToken.bufferSkip, dataToken, remainingBytesToProcess);
                    if (dataToken.prefixBytesDone == 4 && (dataToken.messageLength > 10 * 1024 * 1024 || dataToken.messageLength <= 0))
                    {
                        byte[] bufferBytes = dataToken.byteArrayForMessage == null?
                                             BufferUtils.MergeBytes(dataToken.byteArrayForPrefix, BufferUtils.GetBytes(buffer, dataToken.bufferSkip, buffer.Length - dataToken.bufferSkip)) :
                                                 BufferUtils.MergeBytes(dataToken.byteArrayForPrefix, dataToken.byteArrayForMessage, buffer);

                        string data = Encoding.UTF8.GetString(bufferBytes);
                        //消息头已接收完毕,并且接收到的消息长度大于10M,socket传输的数据已紊乱,关闭掉
                        TraceLog.Write("The host[{0}] request parser head byte error, byte len={1}\r\ndata:{2}",
                                       dataToken.Socket.RemoteEndPoint.ToNotNullString(),
                                       dataToken.messageLength,
                                       data);
                        needPostAnother = false;
                        break;
                    }
                    //if (logger.IsDebugEnabled) logger.Debug("处理消息头,消息长度[{0}],剩余字节[{1}]", dataToken.messageLength, remainingBytesToProcess);
                    if (remainingBytesToProcess == 0)
                    {
                        break;
                    }
                }

                remainingBytesToProcess = HandleMessage(buffer, dataToken.bufferSkip, dataToken, remainingBytesToProcess);

                if (dataToken.IsMessageReady)
                {
                    //if (logger.IsDebugEnabled) logger.Debug("完整封包 长度[{0}],总传输[{1}],剩余[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, remainingBytesToProcess);
                    messageList.Add(new DataMessage()
                    {
                        Data = dataToken.byteArrayForMessage, OpCode = OpCode.Binary
                    });
                    if (remainingBytesToProcess != 0)
                    {
                        //if (logger.IsDebugEnabled) logger.Debug("重置缓冲区,buffskip指针[{0}]。", dataToken.bufferSkip);
                        dataToken.Reset(false);
                    }
                }
                else
                {
                    //if (logger.IsDebugEnabled) logger.Debug("不完整封包 长度[{0}],总传输[{1}],已接收[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, dataToken.messageBytesDone);
                }
            } while (remainingBytesToProcess != 0);


            if (needPostAnother)
            {
                //继续处理下个请求包
                if (dataToken.prefixBytesDone == 4 && dataToken.IsMessageReady)
                {
                    dataToken.Reset(true);
                }
                dataToken.bufferSkip = 0;
            }
            return(needPostAnother);
        }
Ejemplo n.º 7
0
        private static void OnEntitySyncQueue(object state)
        {
            if (Interlocked.CompareExchange(ref _entityQueueRunning, 1, 0) == 0)
            {
                try
                {
                    var tempRemove = Interlocked.Exchange(ref _entityRemoteSet, new HashSet <string>());
                    var temp       = Interlocked.Exchange(ref _entitySet, new HashSet <string>());
                    if (temp.Count == 0)
                    {
                        return;
                    }
                    using (var client = RedisConnectionPool.GetClient())
                    {
                        var pipeline = client.CreatePipeline();
                        try
                        {
                            bool hasPost = false;
                            foreach (var key in temp)
                            {
                                var keyValues = key.Split('_', '|');
                                if (keyValues.Length != 3)
                                {
                                    continue;
                                }

                                AbstractEntity entity   = CacheFactory.GetPersonalEntity(key) as AbstractEntity;
                                int            id       = keyValues[1].ToInt();
                                string         keyCode  = keyValues[2];
                                string         redisKey = string.Format("{0}_{1}", keyValues[0], keyCode);
                                string         hashId   = GetRedisSyncQueueKey(id);
                                byte[]         idBytes  = BufferUtils.GetBytes(id);
                                var            keyBytes = RedisConnectionPool.ToByteKey(redisKey);
                                bool           isDelete;
                                byte[]         entityBytes;
                                if (entity != null)
                                {
                                    isDelete    = entity.IsDelete;
                                    entityBytes = _serializer.Serialize(entity);
                                }
                                else if (tempRemove.Contains(key))
                                {
                                    entityBytes = new byte[0];
                                    isDelete    = true;
                                }
                                else
                                {
                                    TraceLog.WriteError("EntitySync queue key {0} faild object is null.", key);
                                    continue;
                                }
                                byte[] stateBytes = BufferUtils.GetBytes(isDelete ? 1 : 0);
                                byte[] values     =
                                    BufferUtils.MergeBytes(BufferUtils.GetBytes(idBytes.Length + stateBytes.Length),
                                                           idBytes, stateBytes, entityBytes);
                                pipeline.QueueCommand(c => ((RedisClient)c).HSet(hashId, keyBytes, values));
                                hasPost = true;
                            }
                            if (hasPost)
                            {
                                pipeline.Flush();
                            }
                        }
                        finally
                        {
                            pipeline.Dispose();
                        }
                    }
                }
                catch (Exception ex)
                {
                    TraceLog.WriteError("EntitySync queue {0}", ex);
                }
                finally
                {
                    Interlocked.Exchange(ref _entityQueueRunning, 0);
                }
            }
        }