Example #1
0
        /*
         * public bool IsAckMessage(Stream stream, out Ack ack)
         * {
         *  var position = stream.Position;
         *  if (IsAckMessageInner(stream, out ack))
         *  {
         *      return true;
         *  }
         *
         *  stream.Position = position;
         *  return false;
         * }
         *
         * /// <summary>
         * /// 后续不单独发送 ACK 了,因此就不再需要这个信息了
         * /// </summary>
         * [Obsolete(DebugContext.DoNotUseAck)]
         * public byte[] BuildAckMessage(Ack receivedAck)
         * {
         *  const int ackLength = sizeof(ulong) + sizeof(ulong);
         *  byte[] buffer = new byte[AckHeader.Length + ackLength];
         *
         *  Array.Copy(AckHeader, buffer, AckHeader.Length);
         *
         *  var memoryStream = new MemoryStream(buffer)
         *  {
         *      Position = AckHeader.Length
         *  };
         *  var binaryWriter = new BinaryWriter(memoryStream);
         *  binaryWriter.Write(receivedAck.Value);
         *  lock (Locker)
         *  {
         *      CurrentAck = Math.Max(CurrentAck.Value, receivedAck.Value);
         *  }
         *
         *  CurrentAck = CurrentAck.Value + 1;
         *  binaryWriter.Write(CurrentAck.Value);
         *
         *  return buffer;
         * }
         *
         * private bool IsAckMessageInner(Stream stream, out Ack ack)
         * {
         *  /*
         * AckHeader
         * 回复的 ACK ulong
         * 推荐的下一次使用的Ack ulong
         #1#
         *  ack = 0;
         *  const int ackLength = sizeof(ulong) + sizeof(ulong);
         *  if (stream.Length - stream.Position != AckHeader.Length + ackLength) return false;
         *
         *  if (!IsAckHeader(stream)) return false;
         *
         *  var binaryReader = new BinaryReader(stream);
         *  ack = binaryReader.ReadUInt64();
         *  var nextAck = binaryReader.ReadUInt64();
         *
         *  lock (Locker)
         *  {
         *      CurrentAck = Math.Max(CurrentAck.Value, nextAck);
         *  }
         *
         *  return true;
         * }
         *
         * private bool IsAckHeader(Stream stream)
         * {
         *  foreach (var ack in AckHeader)
         *  {
         *      if (stream.ReadByte() != ack)
         *      {
         *          return false;
         *      }
         *  }
         *
         *  return true;
         * }
         *
         * /// <summary>
         * /// 执行任务,直到收到回复才返回或超时等
         * /// </summary>
         * /// <param name="task"></param>
         * /// <param name="peerName"></param>
         * /// <param name="timeout"></param>
         * /// <param name="maxRetryCount"></param>
         * /// <param name="summary"></param>
         * /// <param name="logger"></param>
         * /// <returns></returns>
         * [Obsolete(DebugContext.DoNotUseAck)]
         * internal async Task<bool> DoWillReceivedAck(Func<Ack, Task> task, string peerName, TimeSpan timeout,
         *  uint maxRetryCount, string summary, ILogger logger)
         * {
         *  for (uint i = 0; i < maxRetryCount; i++)
         *  {
         *      var ack = GetAck();
         *      var taskCompletionSource = new TaskCompletionSource<bool>();
         *
         *      logger.Debug($"[{nameof(AckManager)}.{nameof(DoWillReceivedAck)}] StartSend Count={i} {ack} Summary={summary} PeerName={peerName}");
         *
         *      var ackTask = new AckTask(peerName, ack, taskCompletionSource, summary);
         *      RegisterAckTask(ackTask);
         *
         *      // 先注册,然后执行任务,解决任务速度太快,收到消息然后再注册
         *      await task(ack);
         *
         *      await Task.WhenAny(taskCompletionSource.Task, Task.Delay(timeout));
         *      taskCompletionSource.TrySetResult(false);
         *      if (await taskCompletionSource.Task)
         *      {
         *          logger.Debug($"[{nameof(AckManager)}.{nameof(DoWillReceivedAck)}] Finish Send Count={i} {ack} Summary={summary} PeerName={peerName}");
         *
         *          // 执行完成
         *          return true;
         *      }
         *      else
         *      {
         *          logger.Debug($"[{nameof(AckManager)}.{nameof(DoWillReceivedAck)}] Fail Send Count={i} {ack} Summary={summary} PeerName={peerName}");
         *      }
         *  }
         *
         *  logger.Debug($"[{nameof(AckManager)}.{nameof(DoWillReceivedAck)}] Cannot Send Summary={summary} PeerName={peerName}");
         *
         *  // 执行失败
         *  return false;
         * }
         *
         *
         * [Obsolete(DebugContext.DoNotUseAck)]
         * internal void RegisterAckTask(AckTask ackTask)
         * {
         *  AddToAckTaskList();
         *
         *  WaitForTask();
         *
         *  async void WaitForTask()
         *  {
         *      await ackTask.Task.Task;
         *
         *      lock (Locker)
         *      {
         *          if (AckTaskList.Remove(ackTask.Ack.Value, out var removedTask))
         *          {
         *              Debug.Assert(ReferenceEquals(removedTask, ackTask));
         *          }
         *          else
         *          {
         *              Debug.Assert(false, "收到的一定存在");
         *          }
         *      }
         *  }
         *
         *  void AddToAckTaskList()
         *  {
         *      lock (Locker)
         *      {
         *          if (AckTaskList.TryAdd(ackTask.Ack.Value, ackTask))
         *          {
         *          }
         *          else
         *          {
         *              // 理论上是找不到的
         *              throw new ArgumentException(
         *                  $"传入的消息的 ack 已经存在 Ack={ackTask.Ack.Value} Summary={ackTask.Summary}");
         *          }
         *      }
         *  }
         * }
         *
         * private Dictionary<ulong, AckTask> AckTaskList { get; } = new Dictionary<ulong, AckTask>();
         *
         */
        internal void OnAckReceived(object?sender, AckArgs e)
        {
            CurrentAck = e.Ack;

            /*
             * // 其他的也不用干了
             *
             * AckTask ackTask;
             *
             * lock (Locker)
             * {
             *  if (!AckTaskList.TryGetValue(e.Ack.Value, out ackTask!))
             *  {
             *      // 被干掉了,也许是因为等待太久
             *      return;
             *  }
             * }
             *
             * if (ackTask.PeerName.Equals(e.PeerName))
             * {
             *  // 此时也许是等待太久,因此需要使用 Try 方法
             *  ackTask.Task.TrySetResult(true);
             * }
             * else
             * {
             *  // 不是发生给这个客户端的,只是 ack 相同,这个类被改错
             * }
             */
        }
Example #2
0
        internal void OnAckReceived(object?sender, AckArgs e)
        {
            AckTask ackTask;

            lock (Locker)
            {
                if (!AckTaskList.TryGetValue(e.Ack.Value, out ackTask !))
                {
                    // 被干掉了,也许是因为等待太久
                    return;
                }
            }

            if (ackTask.PeerName.Equals(e.PeerName))
            {
                // 此时也许是等待太久
                ackTask.Task.TrySetResult(true);
            }
            else
            {
                // 不是发生给这个客户端的,只是 ack 相同,这个类被改错
            }
        }