private async Task ReadPipeAsync(JT1078TcpSession session, PipeReader reader) { FixedHeaderInfo fixedHeaderInfo = new FixedHeaderInfo(); while (true) { ReadResult result = await reader.ReadAsync(); if (result.IsCompleted) { break; } ReadOnlySequence <byte> buffer = result.Buffer; SequencePosition consumed = buffer.Start; SequencePosition examined = buffer.End; try { if (result.IsCanceled) { break; } if (buffer.Length > 0) { ReaderBuffer(ref buffer, fixedHeaderInfo, session, out consumed, out examined); } } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) { Logger.LogError(ex, $"[ReadPipe Error]:{session.Client.RemoteEndPoint}"); break; } #pragma warning restore CA1031 // Do not catch general exception types finally { reader.AdvanceTo(consumed, examined); } } reader.Complete(); }
private void ReaderBuffer(ref ReadOnlySequence <byte> buffer, FixedHeaderInfo fixedHeaderInfo, JT1078TcpSession session, out SequencePosition consumed, out SequencePosition examined) { consumed = buffer.Start; examined = buffer.End; SequenceReader <byte> seqReader = new SequenceReader <byte>(buffer); long totalConsumed = 0; while (!seqReader.End) { if (seqReader.Length < 30) { fixedHeaderInfo.Reset(); break; } if (!fixedHeaderInfo.FoundHeader) { var header = seqReader.Sequence.Slice(0, 4); uint headerValue = BinaryPrimitives.ReadUInt32BigEndian(header.ToArray()); if (JT1078Package.FH == headerValue) { //sim if (string.IsNullOrEmpty(fixedHeaderInfo.SIM)) { fixedHeaderInfo.SIM = ReadBCD(seqReader.Sequence.Slice(8, 6).ToArray(), 12); fixedHeaderInfo.SIM = fixedHeaderInfo.SIM ?? session.SessionID; } //根据数据类型处理对应的数据长度 fixedHeaderInfo.TotalSize += 15; var dataType = seqReader.Sequence.Slice(fixedHeaderInfo.TotalSize, 1).FirstSpan[0]; fixedHeaderInfo.TotalSize += 1; int bodyLength = GetRealDataBodyLength(dataType); fixedHeaderInfo.TotalSize += bodyLength; var bodyLengthFirstSpan = seqReader.Sequence.Slice(fixedHeaderInfo.TotalSize, 2).ToArray(); fixedHeaderInfo.TotalSize += 2; //数据体长度 bodyLength = BinaryPrimitives.ReadUInt16BigEndian(bodyLengthFirstSpan); if (bodyLength < 0) { fixedHeaderInfo.Reset(); throw new ArgumentException("jt1078 package body length Error."); } if (bodyLength == 0)//数据体长度为0 { var package1 = seqReader.Sequence.Slice(0, fixedHeaderInfo.TotalSize).ToArray(); seqReader.Advance(fixedHeaderInfo.TotalSize); if (LogLogger.IsEnabled(LogLevel.Trace)) { LogLogger.LogTrace($"{package1.ToHexString()}"); } try { SessionManager.TryLink(fixedHeaderInfo.SIM, session); jT1078MsgProducer.ProduceAsync(fixedHeaderInfo.SIM, package1.ToArray()); } catch (Exception ex) { LogLogger.LogError($"[Error Parse 1]:{package1.ToHexString()}"); Logger.LogError(ex, $"[Error Parse 1]:{package1.ToHexString()}"); } finally { totalConsumed += seqReader.Consumed; seqReader = new SequenceReader <byte>(seqReader.Sequence.Slice(fixedHeaderInfo.TotalSize)); fixedHeaderInfo.Reset(); #if DEBUG Interlocked.Increment(ref Counter); #endif } continue; } //数据体 fixedHeaderInfo.TotalSize += bodyLength; fixedHeaderInfo.FoundHeader = true; } else { fixedHeaderInfo.Reset(); throw new ArgumentException("not JT1078 package."); } } if ((seqReader.Length - fixedHeaderInfo.TotalSize) < 0) { break; } var package = seqReader.Sequence.Slice(0, fixedHeaderInfo.TotalSize).ToArray(); seqReader.Advance(fixedHeaderInfo.TotalSize); if (LogLogger.IsEnabled(LogLevel.Trace)) { LogLogger.LogTrace($"===>{package.ToHexString()}"); } try { SessionManager.TryLink(fixedHeaderInfo.SIM, session); jT1078MsgProducer.ProduceAsync(fixedHeaderInfo.SIM, package); } catch (Exception ex) { LogLogger.LogError($"[Error Parse 2]:{package.ToHexString()}"); Logger.LogError(ex, $"[Error Parse 2]:{package.ToHexString()}"); } finally { totalConsumed += seqReader.Consumed; seqReader = new SequenceReader <byte>(seqReader.Sequence.Slice(fixedHeaderInfo.TotalSize)); fixedHeaderInfo.Reset(); #if DEBUG Interlocked.Increment(ref Counter); #endif } #if DEBUG if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"======>{Counter}"); } #endif } if (seqReader.End) { examined = consumed = buffer.End; } else { consumed = buffer.GetPosition(totalConsumed); } }