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();
        }
Beispiel #2
0
 /// <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);
 }
Beispiel #3
0
        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);
        }
Beispiel #8
0
        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();
        }
Beispiel #12
0
        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);
            }
        }