private async Task FillPipeAsync(JT808TcpSession session, PipeWriter writer) { while (true) { try { Memory <byte> memory = writer.GetMemory(Configuration.MiniNumBufferSize); //设备多久没发数据就断开连接 Receive Timeout. int bytesRead = await session.Client.ReceiveAsync(memory, SocketFlags.None, session.ReceiveTimeout.Token); if (bytesRead == 0) { break; } writer.Advance(bytesRead); } catch (OperationCanceledException) { Logger.LogError($"[Receive Timeout]:{session.Client.RemoteEndPoint}"); break; } catch (Exception ex) { Logger.LogError(ex, $"[Receive Error]:{session.Client.RemoteEndPoint}"); break; } FlushResult result = await writer.FlushAsync(); if (result.IsCompleted) { break; } } writer.Complete(); }
/// <summary> /// /// </summary> /// <param name="cancellationToken"></param> /// <returns></returns> public Task StartAsync(CancellationToken cancellationToken) { Logger.LogInformation($"JT808 TCP Server start at {IPAddress.Any}:{ConfigurationMonitor.CurrentValue.TcpPort}."); Task.Factory.StartNew(async() => { while (!cancellationToken.IsCancellationRequested) { var socket = await server.AcceptAsync(); JT808TcpSession jT808TcpSession = new JT808TcpSession(socket); SessionManager.TryAdd(jT808TcpSession); await Task.Factory.StartNew(async(state) => { var session = (JT808TcpSession)state; if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation($"[Connected]:{session.Client.RemoteEndPoint}"); } var pipe = new Pipe(); Task writing = FillPipeAsync(session, pipe.Writer); Task reading = ReadPipeAsync(session, pipe.Reader); await Task.WhenAll(reading, writing); SessionManager.RemoveBySessionId(session.SessionID); }, jT808TcpSession); } }, cancellationToken); return(Task.CompletedTask); }
private void ReaderBuffer(ref ReadOnlySequence <byte> buffer, JT808TcpSession session, out SequencePosition consumed) { SequenceReader <byte> seqReader = new SequenceReader <byte>(buffer); if (seqReader.TryPeek(out byte beginMark)) { if (beginMark != JT808Package.BeginFlag) { throw new ArgumentException("Not JT808 Packages."); } } byte mark = 0; long totalConsumed = 0; while (!seqReader.End) { if (seqReader.IsNext(JT808Package.BeginFlag, advancePast: true)) { if (mark == 1) { byte[] data = null; try { data = seqReader.Sequence.Slice(totalConsumed, seqReader.Consumed - totalConsumed).ToArray(); //过滤掉不是808标准包(14) //(头)1+(消息 ID )2+(消息体属性)2+(终端手机号)6+(消息流水号)2+(检验码 )1+(尾)1 if (data != null && data.Length > 14) { var package = Serializer.HeaderDeserialize(data); if (BlacklistManager.Contains(package.Header.TerminalPhoneNo)) { if (Logger.IsEnabled(LogLevel.Warning)) { Logger.LogWarning($"[Blacklist {session.Client.RemoteEndPoint}-{session.TerminalPhoneNo}]:{package.OriginalData.ToHexString()}"); } session.ReceiveTimeout.Cancel(); break; } # if DEBUG Interlocked.Increment(ref MessageReceiveCounter); if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}-{session.TerminalPhoneNo}]:{package.OriginalData.ToHexString()},Counter:{MessageReceiveCounter}"); } #else if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}-{session.TerminalPhoneNo}]:{package.OriginalData.ToHexString()}"); } #endif SessionManager.TryLink(package.Header.TerminalPhoneNo, session); Processor(session, package); } }
public void RemoveBySessionIdTest() { JT808SessionManager jT808SessionManager = new JT808SessionManager(new LoggerFactory()); var session = new JT808TcpSession(new Socket(SocketType.Stream, ProtocolType.Tcp)); var result1 = jT808SessionManager.TryAdd(session); Assert.True(result1); Assert.Equal(1, jT808SessionManager.TotalSessionCount); jT808SessionManager.RemoveBySessionId(session.SessionID); Assert.Equal(0, jT808SessionManager.TotalSessionCount); }
public void TryLinkTest() { string tno = "123456"; JT808SessionManager jT808SessionManager = new JT808SessionManager(new LoggerFactory()); var session = new JT808TcpSession(new Socket(SocketType.Stream, ProtocolType.Tcp)); var result1 = jT808SessionManager.TryAdd(session); jT808SessionManager.TryLink(tno, session); Assert.True(result1); Assert.Equal(1, jT808SessionManager.TotalSessionCount); Assert.True(jT808SessionManager.TerminalPhoneNoSessions.ContainsKey(tno)); }
public void SendTest() { Assert.Throws <SocketException>(() => { string tno = "123456"; JT808SessionManager jT808SessionManager = new JT808SessionManager(new LoggerFactory()); var session = new JT808TcpSession(new Socket(SocketType.Stream, ProtocolType.Tcp)); var result1 = jT808SessionManager.TryAdd(session); jT808SessionManager.TryLink(tno, session); jT808SessionManager.TrySendByTerminalPhoneNoAsync(tno, new byte[] { 0x7e, 0, 0, 0x7e }).GetAwaiter().GetResult(); }); }
public void TryLinkTest2_1_N() { string tno1 = "123456"; string tno2 = "123457"; string tno3 = "123458"; JT808SessionManager jT808SessionManager = new JT808SessionManager(new LoggerFactory()); var session = new JT808TcpSession(new Socket(SocketType.Stream, ProtocolType.Tcp)); var result1 = jT808SessionManager.TryAdd(session); jT808SessionManager.TryLink(tno1, session); jT808SessionManager.TryLink(tno2, session); jT808SessionManager.TryLink(tno3, session); Assert.True(result1); Assert.Equal(1, jT808SessionManager.TotalSessionCount); Assert.Equal(3, jT808SessionManager.TerminalPhoneNoSessions.Count); jT808SessionManager.RemoveByTerminalPhoneNo(tno1); Assert.Equal(0, jT808SessionManager.TotalSessionCount); Assert.Empty(jT808SessionManager.TerminalPhoneNoSessions); }
private async Task FillPipeAsync(JT808TcpSession session, PipeWriter writer) { while (true) { try { Memory <byte> memory = writer.GetMemory(ConfigurationMonitor.CurrentValue.MiniNumBufferSize); //设备多久没发数据就断开连接 Receive Timeout. int bytesRead = await session.Client.ReceiveAsync(memory, SocketFlags.None, session.ReceiveTimeout.Token); if (bytesRead == 0) { break; } writer.Advance(bytesRead); FlushResult result = await writer.FlushAsync(session.ReceiveTimeout.Token); if (result.IsCompleted) { break; } } catch (OperationCanceledException) { Logger.LogError($"[Receive Timeout Or Operation Canceled]:{session.Client.RemoteEndPoint},{session.TerminalPhoneNo}"); break; } catch (System.Net.Sockets.SocketException ex) { Logger.LogError($"[{ex.SocketErrorCode},{ex.Message}]:{session.Client.RemoteEndPoint},{session.TerminalPhoneNo}"); break; } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) { Logger.LogError(ex, $"[Receive Error]:{session.Client.RemoteEndPoint},{session.TerminalPhoneNo}"); break; } #pragma warning restore CA1031 // Do not catch general exception types } writer.Complete(); }
public void UpdateLinkTest2_1_N() { string tno1 = "123456"; string tno2 = "123457"; string tno3 = "123458"; JT808SessionManager jT808SessionManager = new JT808SessionManager(new LoggerFactory()); var session1 = new JT808TcpSession(new Socket(SocketType.Stream, ProtocolType.Tcp)); var session2 = new JT808TcpSession(new Socket(SocketType.Stream, ProtocolType.Tcp)); var result1 = jT808SessionManager.TryAdd(session1); var result2 = jT808SessionManager.TryAdd(session2); //转发车辆 jT808SessionManager.TryLink(tno1, session1); jT808SessionManager.TryLink(tno2, session1); //直连车辆 jT808SessionManager.TryLink(tno3, session2); Assert.True(result1); Assert.True(result2); Assert.Equal(2, jT808SessionManager.TotalSessionCount); Assert.Equal(3, jT808SessionManager.TerminalPhoneNoSessions.Count); //将tno2切换为直连车辆 var session3 = new JT808TcpSession(new Socket(SocketType.Stream, ProtocolType.Tcp)); var result3 = jT808SessionManager.TryAdd(session3); jT808SessionManager.TryLink(tno2, session3); Assert.True(result3); if (jT808SessionManager.TerminalPhoneNoSessions.TryGetValue(tno2, out var sessionInfo)) { //实际的通道Id Assert.Equal(session3.SessionID, sessionInfo.SessionID); } Assert.Equal(3, jT808SessionManager.TotalSessionCount); Assert.Equal(3, jT808SessionManager.TerminalPhoneNoSessions.Count); jT808SessionManager.RemoveByTerminalPhoneNo(tno1); Assert.Equal(2, jT808SessionManager.TotalSessionCount); Assert.Equal(2, jT808SessionManager.TerminalPhoneNoSessions.Count); }
public void GetTcpAllTest() { string tno1 = "123456"; string tno2 = "123457"; JT808SessionManager jT808SessionManager = new JT808SessionManager(new LoggerFactory()); var session1 = new JT808TcpSession(new Socket(SocketType.Stream, ProtocolType.Tcp)); var session2 = new JT808TcpSession(new Socket(SocketType.Stream, ProtocolType.Tcp)); var result1 = jT808SessionManager.TryAdd(session1); var result2 = jT808SessionManager.TryAdd(session2); jT808SessionManager.TryLink(tno1, session1); jT808SessionManager.TryLink(tno2, session2); Assert.True(result1); Assert.True(result2); Assert.Equal(2, jT808SessionManager.TotalSessionCount); Assert.True(jT808SessionManager.TerminalPhoneNoSessions.ContainsKey(tno1)); Assert.True(jT808SessionManager.TerminalPhoneNoSessions.ContainsKey(tno2)); var sessions = jT808SessionManager.GetTcpAll(); Assert.Contains(sessions, (item) => item.SessionID == session1.SessionID); Assert.Contains(sessions, (item) => item.SessionID == session2.SessionID); }
private async Task ReadPipeAsync(JT808TcpSession session, PipeReader reader) { 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, 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 async Task ReadPipeAsync(JT808TcpSession session, PipeReader reader) { 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, session, out consumed); } } catch (Exception ex) { Logger.LogError(ex, $"[ReadPipe Error]:{session.Client.RemoteEndPoint},{session.TerminalPhoneNo}"); break; } finally { reader.AdvanceTo(consumed, examined); } } reader.Complete(); }
private async Task ReadPipeAsync(JT808TcpSession session, PipeReader reader) { 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, session, out consumed, out examined); } } catch (Exception ex) { SessionManager.RemoveBySessionId(session.SessionID); break; } finally { reader.AdvanceTo(consumed, examined); } } reader.Complete(); }
private void ReaderBuffer(ref ReadOnlySequence <byte> buffer, JT808TcpSession session, out SequencePosition consumed, out SequencePosition examined) { consumed = buffer.Start; examined = buffer.End; SequenceReader <byte> seqReader = new SequenceReader <byte>(buffer); if (seqReader.TryPeek(out byte beginMark)) { if (beginMark != JT808Package.BeginFlag) { throw new ArgumentException("Not JT808 Packages."); } } byte mark = 0; long totalConsumed = 0; while (!seqReader.End) { if (seqReader.IsNext(JT808Package.BeginFlag, advancePast: true)) { if (mark == 1) { try { var package = Serializer.HeaderDeserialize(seqReader.Sequence.Slice(totalConsumed, seqReader.Consumed - totalConsumed).FirstSpan); AtomicCounterService.MsgSuccessIncrement(); if (Logger.IsEnabled(LogLevel.Debug)) { Logger.LogDebug($"[Atomic Success Counter]:{AtomicCounterService.MsgSuccessCount}"); } if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}]:{package.OriginalData.ToArray().ToHexString()}"); } //设直连模式和转发模式的会话如何处理 SessionManager.TryLink(package.Header.TerminalPhoneNo, session); if (Configuration.MessageQueueType == JT808MessageQueueType.InMemory) { MsgProducer.ProduceAsync(session.SessionID, package.OriginalData.ToArray()); } else { MsgProducer.ProduceAsync(package.Header.TerminalPhoneNo, package.OriginalData.ToArray()); } } catch (JT808Exception ex) { AtomicCounterService.MsgFailIncrement(); if (Logger.IsEnabled(LogLevel.Debug)) { Logger.LogDebug($"[Atomic Fail Counter]:{AtomicCounterService.MsgFailCount}"); } Logger.LogError(ex, $"[HeaderDeserialize ErrorCode]:{ ex.ErrorCode}"); } totalConsumed += (seqReader.Consumed - totalConsumed); if (seqReader.End) { break; } seqReader.Advance(1); mark = 0; } mark++; } else { seqReader.Advance(1); } } if (seqReader.Length == totalConsumed) { examined = consumed = buffer.End; } else { consumed = buffer.GetPosition(totalConsumed); } }
private void ReaderBuffer(ref ReadOnlySequence <byte> buffer, JT808TcpSession session, out SequencePosition consumed, out SequencePosition examined) { consumed = buffer.Start; examined = buffer.End; SequenceReader <byte> seqReader = new SequenceReader <byte>(buffer); if (seqReader.TryPeek(out byte beginMark)) { if (beginMark != JT808Package.BeginFlag) { throw new ArgumentException("Not JT808 Packages."); } } byte mark = 0; long totalConsumed = 0; while (!seqReader.End) { if (seqReader.IsNext(JT808Package.BeginFlag, advancePast: true)) { if (mark == 1) { ReadOnlySpan <byte> contentSpan = ReadOnlySpan <byte> .Empty; try { contentSpan = seqReader.Sequence.Slice(totalConsumed, seqReader.Consumed - totalConsumed).FirstSpan; //过滤掉不是808标准包(14) //(头)1+(消息 ID )2+(消息体属性)2+(终端手机号)6+(消息流水号)2+(检验码 )1+(尾)1 if (contentSpan.Length > 14) { var package = Serializer.HeaderDeserialize(contentSpan, minBufferSize: 10240); if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"[Accept Hex {session.Client.RemoteEndPoint}]:{package.OriginalData.ToArray().ToHexString()}"); } SessionManager.TryLink(package.Header.TerminalPhoneNo, session); MessageHandler.Processor(package, session); } } catch (NotImplementedException ex) { Logger.LogError(ex.Message); } catch (JT808Exception ex) { Logger.LogError($"[HeaderDeserialize ErrorCode]:{ ex.ErrorCode},[ReaderBuffer]:{contentSpan.ToArray().ToHexString()}"); } totalConsumed += (seqReader.Consumed - totalConsumed); if (seqReader.End) { break; } seqReader.Advance(1); mark = 0; } mark++; } else { seqReader.Advance(1); } } if (seqReader.Length == totalConsumed) { examined = consumed = buffer.End; } else { consumed = buffer.GetPosition(totalConsumed); } }