/// <summary> /// 合并命令处理 /// </summary> /// <param name="data"></param> internal void Merge(ref SubArray <byte> data) { try { byte[] dataArray = data.Array; ClientCommand.Command command; int receiveIndex = data.Start, receiveCount = data.EndIndex; ReturnType type; fixed(byte *dataFixed = data.Array) { byte *start; do { int receiveSize = receiveCount - receiveIndex; if (receiveSize < sizeof(uint)) { if (receiveSize == 0) { return; } break; } CommandIndex = *(uint *)(start = dataFixed + receiveIndex); if ((type = Server.GetReturnType(ref CommandIndex)) == ReturnType.Unknown) { if (receiveSize < (sizeof(uint) + sizeof(int))) { break; } if ((dataSize = *(int *)(start + sizeof(uint))) <= 0) { break; } if (dataSize > (receiveSize -= (sizeof(uint) + sizeof(int)))) { break; } receiveIndex += (sizeof(uint) + sizeof(int)); //if ((command = CommandIndex == keepCallbackCommandIndex ? keepCallbackCommand : getCommand()) != null) if ((command = CommandPool.GetCommand((int)CommandIndex)) != null) { //if (command.CommandInfo.TaskType == ClientTaskType.Synchronous) //{ // data.Set(receiveIndex, dataSize); // command.OnReceiveSynchronous(ref data); //} //else if (command.CommandInfo.IsKeepCallback == 0) command.CopyDataRunTask(dataArray, receiveIndex, dataSize); //else new CommandKeepDataTask().CopyData(command, dataArray, receiveIndex, dataSize); data.Set(receiveIndex, dataSize); command.OnReceive(ref data); } receiveIndex += dataSize; } else { onReceive(type); receiveIndex += sizeof(uint); } }while (true); } } catch (Exception error) { Log.Add(AutoCSer.Log.LogType.Error, error); } mergeError(); }
/// <summary> /// 获取命令回调序号 /// </summary> /// <param name="count"></param> /// <returns></returns> protected bool commandIdentityAsync(int count) { START: int receiveSize = (receiveCount += count) - receiveIndex; if (receiveSize >= sizeof(uint)) { fixed(byte *receiveDataFixed = ReceiveBuffer.GetFixedBuffer()) { receiveDataStart = receiveDataFixed + ReceiveBuffer.StartIndex; byte *start = receiveDataStart + receiveIndex; CommandIndex = *(uint *)start; ReturnType type = Server.GetReturnType(ref CommandIndex); if (type == ReturnType.Unknown) { if (receiveSize >= (sizeof(uint) + sizeof(int))) { if ((compressionDataSize = *(int *)(start + sizeof(uint))) < 0) { if (receiveSize < (sizeof(uint) + sizeof(int) * 2)) { goto AGAIN; } if ((compressionDataSize = -compressionDataSize) >= (dataSize = *(int *)(start + (sizeof(uint) + sizeof(int))))) { return(false); } receiveIndex += (sizeof(uint) + sizeof(int) * 2); } else if (compressionDataSize == 0) { return(false); } else { dataSize = compressionDataSize; receiveIndex += (sizeof(uint) + sizeof(int)); } if (compressionDataSize <= receiveCount - receiveIndex) { return(isOnDataLoopFixed() && loop()); } switch (checkDataLoopFixed()) { case 0: return(true); case 1: return(loop()); default: return(false); } } } else { onReceive(type); receiveIndex += sizeof(uint); return(loop()); } } } AGAIN: if ((count = receiveCommandIdentityAgain()) > 0) { goto START; } return(count == 0); }
/// <summary> /// 循环处理命令回调 /// </summary> /// <returns></returns> private bool loop() { START: int receiveSize = receiveCount - receiveIndex; if (receiveSize < sizeof(uint)) { if (receiveSize == 0) { receiveCount = receiveIndex = 0; goto RECEIVE; } goto COPY; } #if !DOTNET2 ONRECEIVE: #endif byte *start = receiveDataStart + receiveIndex; CommandIndex = *(uint *)start; ReturnType type = Server.GetReturnType(ref CommandIndex); if (type == ReturnType.Unknown) { if (receiveSize >= (sizeof(uint) + sizeof(int))) { if ((compressionDataSize = *(int *)(start + sizeof(uint))) < 0) { if (receiveSize < (sizeof(uint) + sizeof(int) * 2)) { goto COPY; } dataSize = *(int *)(start + (sizeof(uint) + sizeof(int))); receiveIndex += (sizeof(uint) + sizeof(int) * 2); compressionDataSize = -compressionDataSize; } else { dataSize = compressionDataSize; receiveIndex += (sizeof(uint) + sizeof(int)); } if (compressionDataSize <= receiveCount - receiveIndex) { if (isOnDataLoopFixed()) { goto START; } return(false); } switch (checkDataLoopFixed()) { case 0: return(true); case 1: goto START; default: return(false); } } } else { onReceive(type); receiveIndex += sizeof(uint); goto START; } COPY: AutoCSer.Memory.Common.SimpleCopyNotNull64(receiveDataStart + receiveIndex, receiveDataStart, receiveCount = receiveSize); receiveIndex = 0; RECEIVE: Socket socket = this.Socket; if (socket != null) { ReceiveType = ClientSocketReceiveType.CommandIdentity; #if DOTNET2 socket.BeginReceive(ReceiveBuffer.Buffer, ReceiveBuffer.StartIndex + receiveCount, receiveBufferSize - receiveCount, SocketFlags.None, out socketError, onReceiveAsyncCallback, socket); if (socketError == SocketError.Success) { return(true); } #else #if !DotNetStandard receiveAsyncLock.EnterYield(); #endif receiveAsyncEventArgs.SetBuffer(ReceiveBuffer.StartIndex + receiveCount, receiveBufferSize - receiveCount); if (socket.ReceiveAsync(receiveAsyncEventArgs)) { #if !DotNetStandard receiveAsyncLock.Exit(); #endif return(true); } if (receiveAsyncEventArgs.SocketError == SocketError.Success) { if ((receiveSize = (receiveCount += receiveAsyncEventArgs.BytesTransferred) - receiveIndex) >= sizeof(uint)) { #if !DotNetStandard receiveAsyncLock.Exit(); #endif ++ReceiveCount; goto ONRECEIVE; } } else { socketError = receiveAsyncEventArgs.SocketError; } #endif } return(false); }
/// <summary> /// 获取命令回调序号 /// </summary> /// <param name="count"></param> /// <returns></returns> protected bool commandIdentityAsync(int count) { int receiveSize = (receiveCount += count) - receiveIndex; if (receiveSize >= sizeof(uint)) { fixed(byte *receiveDataFixed = ReceiveBuffer.Buffer) { receiveDataStart = receiveDataFixed + ReceiveBuffer.StartIndex; byte *start = receiveDataStart + receiveIndex; CommandIndex = *(uint *)start; ReturnType type = Server.GetReturnType(ref CommandIndex); if (type == ReturnType.Unknown) { if (receiveSize >= (sizeof(uint) + sizeof(int))) { if ((compressionDataSize = *(int *)(start + sizeof(uint))) < 0) { if (receiveSize < (sizeof(uint) + sizeof(int) * 2)) { return(false); } if ((compressionDataSize = -compressionDataSize) >= (dataSize = *(int *)(start + (sizeof(uint) + sizeof(int))))) { return(false); } receiveIndex += (sizeof(uint) + sizeof(int) * 2); } else if (compressionDataSize == 0) { return(false); } else { dataSize = compressionDataSize; receiveIndex += (sizeof(uint) + sizeof(int)); } if (compressionDataSize <= receiveCount - receiveIndex) { return(isOnDataLoopFixed() && loop()); } bool isOnData = false; if (checkDataLoopFixed(ref isOnData)) { if (isOnData) { return(loop()); } return(true); } } } else { onReceive(type); receiveIndex += sizeof(uint); return(loop()); } } } return(false); }