Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

62 lignes
2.5 KiB

  1. using System.Collections.Concurrent;
  2. using JT808.Protocol.Interfaces;
  3. using JT808.Protocol.MessagePack;
  4. namespace JT808.Protocol.Internal
  5. {
  6. /// <summary>
  7. /// 默认分包合并实现
  8. /// </summary>
  9. public class DefaultMerger : IMerger
  10. {
  11. /// <summary>
  12. /// 分包数据缓存
  13. /// <para>key为sim卡号,value为字典,key为消息id,value为元组,结构为:(分包索引,分包元数据)</para>
  14. /// </summary>
  15. private readonly ConcurrentDictionary<string, ConcurrentDictionary<ushort, List<(ushort index, byte[] data)>>> SplitPackages = new();
  16. /// <inheritdoc/>
  17. public bool TryMerge(JT808Header header, byte[] data, IJT808Config config, out JT808Bodies body)
  18. {
  19. body = null;
  20. if (header.PackageIndex == header.PackgeCount)
  21. {
  22. if (SplitPackages.TryGetValue(header.TerminalPhoneNo, out var item) && item.TryRemove(header.MsgId, out var packages))
  23. {
  24. SplitPackages.TryRemove(header.TerminalPhoneNo, out _);
  25. var mateData = packages.OrderBy(x => x.index).SelectMany(x => x.data).Concat(data).ToArray();
  26. byte[] buffer = JT808ArrayPool.Rent(mateData.Length);
  27. try
  28. {
  29. var reader = new JT808MessagePackReader(mateData, (Enums.JT808Version)header.ProtocolVersion);
  30. if (config.MsgIdFactory.TryGetValue(header.MsgId, out var value) && value is JT808Bodies instance)
  31. {
  32. body = instance.DeserializeExt<JT808Bodies>(ref reader, config);
  33. return true;
  34. }
  35. }
  36. finally
  37. {
  38. JT808ArrayPool.Return(buffer);
  39. }
  40. }
  41. return default;
  42. }
  43. else
  44. {
  45. SplitPackages.AddOrUpdate(header.TerminalPhoneNo, new ConcurrentDictionary<ushort, List<(ushort, byte[])>>() { [header.MsgId] = new List<(ushort, byte[])> { (header.PackageIndex, data) } }, (_, value) =>
  46. {
  47. value.AddOrUpdate(header.MsgId, new List<(ushort, byte[])> { (header.PackageIndex, data) }, (_, item) =>
  48. {
  49. item.Add((header.PackageIndex, data));
  50. return item;
  51. });
  52. return value;
  53. });
  54. }
  55. return false;
  56. }
  57. }
  58. }