/// <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())); }
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); }
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); }
/// <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); } }
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); } } }
/// <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); }
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); } } }