Browse Source

1.增加消息序列号的分布式接口及对应默认实现;

2.修改对应序列化BufferSize的大小可根据实际组包调整;
3.增加业务类型创建包的扩展;
4.增加全局配置:头部及序列号配置.
5.修改文档
tags/v1.3.0
SmallChi 6 years ago
parent
commit
c1a70fd44d
13 changed files with 293 additions and 13 deletions
  1. +37
    -1
      README.md
  2. +16
    -0
      src/JT809.Protocol.Test/JT809HeaderTest.cs
  3. +1
    -1
      src/JT809.Protocol.Test/JT809Packages/JT809_0x1001EncryptPackageTest.cs
  4. +31
    -0
      src/JT809.Protocol.Test/JT809Packages/JT809_0x9400_0x9401PackageTest.cs
  5. +11
    -0
      src/JT809.Protocol/IMsgSNDistributed.cs
  6. +1
    -0
      src/JT809.Protocol/JT809.Protocol.csproj
  7. +28
    -0
      src/JT809.Protocol/JT809Configs/JT809HeaderOptions.cs
  8. +1
    -0
      src/JT809.Protocol/JT809Extensions/JT809HexExtensions.cs
  9. +117
    -0
      src/JT809.Protocol/JT809Extensions/JT809PackageExtensions.cs
  10. +2
    -2
      src/JT809.Protocol/JT809Formatters/JT809PackageFormatter.cs
  11. +27
    -5
      src/JT809.Protocol/JT809GlobalConfig.cs
  12. +17
    -0
      src/JT809.Protocol/JT809Internal/DefaultMsgSNDistributedImpl.cs
  13. +4
    -4
      src/JT809.Protocol/JT809Serializer.cs

+ 37
- 1
README.md View File

@@ -54,11 +54,12 @@

反转义的原因:确认JT809协议的TCP消息边界。

### 举个栗子
### 举个栗子1

#### 1.组包:

> 业务数据类型 MsgID:从链路报警信息交互消息
>
> 子业务类型标识 SubBusinessType:报警督办请求消息

``` code
@@ -183,8 +184,43 @@ Assert.Equal("123456@qq.com", jT809_0x9400_0x9401.SupervisorEmail);

```

### 举个栗子3
``` data2
// 设置全局配置
JT809GlobalConfig.Instance.SetHeaderOptions(new JT809Configs.JT809HeaderOptions
{
EncryptKey= 9999,
MsgGNSSCENTERID= 20180920
});

// 根据业务类型创建对应包
JT809Package jT809Package = JT809BusinessType.DOWN_WARN_MSG.Create(new JT809_0x9400
{
VehicleNo = "粤A12345",
VehicleColor = JT809Enums.JT809VehicleColorType.黄色,
SubBusinessType = JT809Enums.JT809SubBusinessType.DOWN_WARN_MSG_URGE_TODO_REQ,
JT809SubBodies = new JT809_0x9400_0x9401
{
WarnSrc = JT809WarnSrc.车载终端,
WarnType = JT809WarnType.疲劳驾驶报警,
WarnTime = DateTime.Parse("2018-09-27 10:24:00"),
SupervisionID = "123FFAA1",
SupervisionEndTime = DateTime.Parse("2018-09-27 11:24:00"),
SupervisionLevel = 3,
Supervisor = "smallchi",
SupervisorTel = "12345678901",
SupervisorEmail = "123456@qq.com"
}
});
var hex = JT809Serializer.Serialize(jT809Package);
```

## NuGet安装

| Package Name | Version | Downloads
|--------------| ------- | ----
| JT809 | ![](https://img.shields.io/nuget/v/JT809.svg) | ![](https://img.shields.io/nuget/dt/JT809.svg)

Install-Package JT809

## 使用BenchmarkDotNet性能测试报告(只是玩玩,不能当真)


+ 16
- 0
src/JT809.Protocol.Test/JT809HeaderTest.cs View File

@@ -4,6 +4,8 @@ using System.Text;
using Xunit;
using JT809.Protocol;
using JT809.Protocol.JT809Extensions;
using System.Threading.Tasks;
using System.Diagnostics;

namespace JT809.Protocol.Test
{
@@ -37,5 +39,19 @@ namespace JT809.Protocol.Test
Assert.Equal(JT809Header_Encrypt.None, jT809Header.EncryptFlag);
Assert.Equal((uint)0, jT809Header.EncryptKey);
}

[Fact]
public void Test3()
{
Parallel.For(0, 1000, (i) =>
{
JT809GlobalConfig.Instance.MsgSNDistributed.Increment();
});
Parallel.For(0, 1000, (i) =>
{
JT809GlobalConfig.Instance.MsgSNDistributed.Increment();
});
var sn = JT809GlobalConfig.Instance.MsgSNDistributed.Increment();
}
}
}

+ 1
- 1
src/JT809.Protocol.Test/JT809Packages/JT809_0x1001EncryptPackageTest.cs View File

@@ -13,7 +13,7 @@ namespace JT809.Protocol.Test.JT809Packages
{
public JT809_0x1001EncryptPackageTest()
{
JT809GlobalConfig.Instance.SetJT809Encrypt(new JT809EncryptImpl(new JT809Configs.JT809EncryptOptions()
JT809GlobalConfig.Instance.SetEncrypt(new JT809EncryptImpl(new JT809Configs.JT809EncryptOptions()
{
IA1 = 20000000,
IC1 = 20000000,


+ 31
- 0
src/JT809.Protocol.Test/JT809Packages/JT809_0x9400_0x9401PackageTest.cs View File

@@ -83,5 +83,36 @@ namespace JT809.Protocol.Test.JT809Packages
Assert.Equal("12345678901", jT809_0x9400_0x9401.SupervisorTel);
Assert.Equal("123456@qq.com", jT809_0x9400_0x9401.SupervisorEmail);
}

[Fact]
public void Test3()
{
JT809GlobalConfig.Instance.SetHeaderOptions(new JT809Configs.JT809HeaderOptions
{
EncryptKey= 9999,
MsgGNSSCENTERID= 20180920
});
JT809Package jT809Package = JT809BusinessType.DOWN_WARN_MSG.Create(new JT809_0x9400
{
VehicleNo = "粤A12345",
VehicleColor = JT809Enums.JT809VehicleColorType.黄色,
SubBusinessType = JT809Enums.JT809SubBusinessType.DOWN_WARN_MSG_URGE_TODO_REQ,
JT809SubBodies = new JT809_0x9400_0x9401
{
WarnSrc = JT809WarnSrc.车载终端,
WarnType = JT809WarnType.疲劳驾驶报警,
WarnTime = DateTime.Parse("2018-09-27 10:24:00"),
SupervisionID = "123FFAA1",
SupervisionEndTime = DateTime.Parse("2018-09-27 11:24:00"),
SupervisionLevel = 3,
Supervisor = "smallchi",
SupervisorTel = "12345678901",
SupervisorEmail = "123456@qq.com"
}
});
jT809Package.Header.MsgSN = 1666;
var hex = JT809Serializer.Serialize(jT809Package).ToHexString();
//"5B000000920000068294000133EFB8010000000000270FD4C1413132333435000000000000000000000000000294010000005C010002000000005A01AC3F40123FFAA1000000005A01AC4D5003736D616C6C636869000000000000000031323334353637383930310000000000000000003132333435364071712E636F6D00000000000000000000000000000000000000BAD85D"
}
}
}

+ 11
- 0
src/JT809.Protocol/IMsgSNDistributed.cs View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol
{
public interface IMsgSNDistributed
{
uint Increment();
}
}

+ 1
- 0
src/JT809.Protocol/JT809.Protocol.csproj View File

@@ -54,6 +54,7 @@
<ItemGroup>
<Compile Include="JT809Configs\JT809EncryptOptions.cs" />
<Compile Include="JT809Configs\JT809HeaderOptions.cs" />
<Compile Include="JT809Enums\JT808_Alarm.cs" />
<Compile Include="JT809Enums\JT808_Status.cs" />
<Compile Include="JT809Enums\JT809CommandType.cs" />


+ 28
- 0
src/JT809.Protocol/JT809Configs/JT809HeaderOptions.cs View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.JT809Configs
{
public class JT809HeaderOptions
{
/// <summary>
/// 下级平台接入码,上级平台给下级平台分配唯一标识码。
/// </summary>
public uint MsgGNSSCENTERID { get; set; }
/// <summary>
/// 协议版本号标识,上下级平台之间采用的标准协议版
/// 编号;长度为 3 个字节来表示,0x01 0x02 0x0F 标识
/// 的版本号是 v1.2.15,以此类推。
/// </summary>
public JT809Header_Version Version { get; set; } = new JT809Header_Version();
/// <summary>
/// 报文加密标识位 b: 0 表示报文不加密,1 表示报文加密。
/// </summary>
public JT809Header_Encrypt EncryptFlag { get; set; } = JT809Header_Encrypt.None;
/// <summary>
/// 数据加密的密匙,长度为 4 个字节
/// </summary>
public uint EncryptKey { get; set; }
}
}

+ 1
- 0
src/JT809.Protocol/JT809Extensions/JT809HexExtensions.cs View File

@@ -79,6 +79,7 @@ namespace JT809.Protocol.JT809Extensions

public static string ToHexString(this byte[] source)
{
//return string.Join(separator, source.Select(s => s.ToString("X2")));
return ToHexString(source, false);
}



+ 117
- 0
src/JT809.Protocol/JT809Extensions/JT809PackageExtensions.cs View File

@@ -0,0 +1,117 @@
using JT809.Protocol.JT809Enums;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.JT809Extensions
{
public static class JT809PackageExtensions
{
/// <summary>
/// 创建JT809Package对应的数据体:
/// <list type="TJT809Bodies">
/// <item>
/// <description>JT809_0x1001</description>
/// </item>
/// <item>
/// <description>JT809_0x1002</description>
/// </item>
/// <item>
/// <description>JT809_0x1003</description>
/// </item>
/// <item>
/// <description>JT809_0x1004</description>
/// </item>
/// <item>
/// <description>JT809_0x1005</description>
/// </item>
/// <item>
/// <description>JT809_0x1006</description>
/// </item>
/// <item>
/// <description>JT809_0x1007</description>
/// </item>
/// <item>
/// <description>JT809_0x1008</description>
/// </item>
/// <item>
/// <description>JT809_0x1200</description>
/// </item>
/// <item>
/// <description>JT809_0x1300</description>
/// </item>
/// <item>
/// <description>JT809_0x1400</description>
/// </item>
/// <item>
/// <description>JT809_0x1500</description>
/// </item>
/// <item>
/// <description>JT809_0x1600</description>
/// </item>
/// <item>
/// <description>JT809_0x9001</description>
/// </item>
/// <item>
/// <description>JT809_0x9002</description>
/// </item>
/// <item>
/// <description>JT809_0x9003</description>
/// </item>
/// <item>
/// <description>JT809_0x9004</description>
/// </item>
/// <item>
/// <description>JT809_0x9005</description>
/// </item>
/// <item>
/// <description>JT809_0x9006</description>
/// </item>
/// <item>
/// <description>JT809_0x9007</description>
/// </item>
/// <item>
/// <description>JT809_0x9008</description>
/// </item>
/// <item>
/// <description>JT809_0x9101</description>
/// </item>
/// <item>
/// <description>JT809_0x9200</description>
/// </item>
/// <item>
/// <description>JT809_0x9300</description>
/// </item>
/// <item>
/// <description>JT809_0x9400</description>
/// </item>
/// <item>
/// <description>JT809_0x9500</description>
/// </item>
/// <item>
/// <description>JT809_0x9600</description>
/// </item>
/// </list>
/// </summary>
/// <typeparam name="TJT809Bodies"></typeparam>
/// <param name="msgID"></param>
/// <param name="jT809Bodies"></param>
/// <returns></returns>
public static JT809Package Create<TJT809Bodies>(this JT809BusinessType msgID, TJT809Bodies jT809Bodies)
where TJT809Bodies: JT809Bodies
{
JT809Package jT809Package = new JT809Package();
jT809Package.Bodies = jT809Bodies;
jT809Package.Header = new JT809Header()
{
MsgID = msgID,
MsgSN = JT809GlobalConfig.Instance.MsgSNDistributed.Increment(),
EncryptFlag = JT809GlobalConfig.Instance.HeaderOptions.EncryptFlag,
EncryptKey = JT809GlobalConfig.Instance.HeaderOptions.EncryptKey,
MsgGNSSCENTERID = JT809GlobalConfig.Instance.HeaderOptions.MsgGNSSCENTERID,
Version = JT809GlobalConfig.Instance.HeaderOptions.Version
};
return jT809Package;
}
}
}

+ 2
- 2
src/JT809.Protocol/JT809Formatters/JT809PackageFormatter.cs View File

@@ -62,7 +62,7 @@ namespace JT809.Protocol.JT809Formatters
jT809Package.Bodies = JT809FormatterResolverExtensions.JT809DynamicDeserialize(JT809FormatterExtensions.GetFormatter(jT809BodiesTypeAttribute.JT809BodiesType), buffer.Slice(offset, checkIndex - offset), out readSize);
break;
case JT809Header_Encrypt.Common:
byte[] bodiesData = JT809GlobalConfig.Instance.JT809Encrypt.Decrypt(buffer.Slice(offset, checkIndex - offset).ToArray());
byte[] bodiesData = JT809GlobalConfig.Instance.Encrypt.Decrypt(buffer.Slice(offset, checkIndex - offset).ToArray());
jT809Package.Bodies = JT809FormatterResolverExtensions.JT809DynamicDeserialize(JT809FormatterExtensions.GetFormatter(jT809BodiesTypeAttribute.JT809BodiesType), bodiesData, out readSize);
break;
}
@@ -101,7 +101,7 @@ namespace JT809.Protocol.JT809Formatters
case JT809Header_Encrypt.None:
break;
case JT809Header_Encrypt.Common:
messageBodyData = JT809GlobalConfig.Instance.JT809Encrypt.Encrypt(messageBodyData);
messageBodyData = JT809GlobalConfig.Instance.Encrypt.Encrypt(messageBodyData);
break;
}
}


+ 27
- 5
src/JT809.Protocol/JT809GlobalConfig.cs View File

@@ -1,4 +1,6 @@
using System;
using JT809.Protocol.JT809Configs;
using JT809.Protocol.JT809Internal;
using System;
using System.Collections.Generic;
using System.Text;

@@ -8,7 +10,11 @@ namespace JT809.Protocol
{
private static readonly Lazy<JT809GlobalConfig> instance = new Lazy<JT809GlobalConfig>(() => new JT809GlobalConfig());

private JT809GlobalConfig(){}
private JT809GlobalConfig()
{
MsgSNDistributed = new DefaultMsgSNDistributedImpl();
HeaderOptions = new JT809HeaderOptions();
}

public static JT809GlobalConfig Instance
{
@@ -18,11 +24,27 @@ namespace JT809.Protocol
}
}

public IJT809Encrypt JT809Encrypt { get; private set; }
public IJT809Encrypt Encrypt { get; private set; }

public IMsgSNDistributed MsgSNDistributed {get;private set;}

public JT809HeaderOptions HeaderOptions { get; private set; }

public JT809GlobalConfig SetEncrypt(IJT809Encrypt jT809Encrypt)
{
instance.Value.Encrypt = jT809Encrypt;
return instance.Value;
}

public JT809GlobalConfig SetMsgSNDistributed(IMsgSNDistributed msgSNDistributed)
{
instance.Value.MsgSNDistributed = msgSNDistributed;
return instance.Value;
}

public JT809GlobalConfig SetJT809Encrypt(IJT809Encrypt jT809Encrypt)
public JT809GlobalConfig SetHeaderOptions(JT809HeaderOptions jT809HeaderOptions)
{
instance.Value.JT809Encrypt = jT809Encrypt;
instance.Value.HeaderOptions = jT809HeaderOptions;
return instance.Value;
}
}


+ 17
- 0
src/JT809.Protocol/JT809Internal/DefaultMsgSNDistributedImpl.cs View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace JT809.Protocol.JT809Internal
{
internal class DefaultMsgSNDistributedImpl : IMsgSNDistributed
{
int _counter = 0;

public uint Increment()
{
return (uint)Interlocked.Increment(ref _counter);
}
}
}

+ 4
- 4
src/JT809.Protocol/JT809Serializer.cs View File

@@ -10,11 +10,11 @@ namespace JT809.Protocol
{
public static class JT809Serializer
{
public static byte[] Serialize(JT809Package jT809Package)
public static byte[] Serialize(JT809Package jT809Package, int minBufferSize = 4096)
{
var formatter = JT809FormatterExtensions.GetFormatter<JT809Package>();
var pool = MemoryPool<byte>.Shared;
IMemoryOwner<byte> buffer = pool.Rent(4096);
IMemoryOwner<byte> buffer = pool.Rent(minBufferSize);
try
{
var len = formatter.Serialize(buffer, 0, jT809Package);
@@ -35,11 +35,11 @@ namespace JT809.Protocol
return formatter.Deserialize(bytes, out int readSize);
}

public static byte[] Serialize<T>(T obj)
public static byte[] Serialize<T>(T obj, int minBufferSize = 4096)
{
var formatter = JT809FormatterExtensions.GetFormatter<T>();
var pool = MemoryPool<byte>.Shared;
IMemoryOwner<byte> buffer = pool.Rent(4096);
IMemoryOwner<byte> buffer = pool.Rent(minBufferSize);
try
{
var len = formatter.Serialize(buffer, 0, obj);


Loading…
Cancel
Save