@@ -1,2 +1,11 @@ | |||||
# JTTools | |||||
# JTTools | |||||
JT808、JT809、JT1078、JTNE解析工具 | JT808、JT809、JT1078、JTNE解析工具 | ||||
[在线解析工具](http://jttools.smallchi.cn) | |||||
使用nodejs的PM2托管应用程序 | |||||
``` 1 | |||||
pm2 start "dotnet JTTools.dll ASPNETCORE_ENVIRONMENT=Production" -n "JTTools.18888" -o "/home/Logs/JTTools/out.log" -e "/home/Logs/JTTools/error.log" | |||||
``` |
@@ -0,0 +1,25 @@ | |||||
| |||||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||||
# Visual Studio Version 16 | |||||
VisualStudioVersion = 16.0.29123.88 | |||||
MinimumVisualStudioVersion = 10.0.40219.1 | |||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JTTools", "JTTools\JTTools.csproj", "{4F7C65A6-85D2-4F32-AC00-B43D2C296618}" | |||||
EndProject | |||||
Global | |||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||||
Debug|Any CPU = Debug|Any CPU | |||||
Release|Any CPU = Release|Any CPU | |||||
EndGlobalSection | |||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||||
{4F7C65A6-85D2-4F32-AC00-B43D2C296618}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{4F7C65A6-85D2-4F32-AC00-B43D2C296618}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{4F7C65A6-85D2-4F32-AC00-B43D2C296618}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{4F7C65A6-85D2-4F32-AC00-B43D2C296618}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
EndGlobalSection | |||||
GlobalSection(SolutionProperties) = preSolution | |||||
HideSolutionNode = FALSE | |||||
EndGlobalSection | |||||
GlobalSection(ExtensibilityGlobals) = postSolution | |||||
SolutionGuid = {3C3239D7-6A1E-4D5B-ABB5-851786B72AED} | |||||
EndGlobalSection | |||||
EndGlobal |
@@ -0,0 +1,103 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
using JTTools.Dtos; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using JT1078.Protocol; | |||||
using JT808.Protocol; | |||||
using JT809.Protocol; | |||||
using JT809.Protocol.Exceptions; | |||||
using JT808.Protocol.Extensions.JT1078; | |||||
using JT809.Protocol.Extensions.JT1078; | |||||
using JT808.Protocol.Interfaces; | |||||
using JT808.Protocol.Extensions; | |||||
using JT808.Protocol.Exceptions; | |||||
using Microsoft.AspNetCore.Cors; | |||||
namespace JTTools.Controllers | |||||
{ | |||||
[Route("api/JTTools")] | |||||
[ApiController] | |||||
[EnableCors("Domain")] | |||||
public class JTToolsController : ControllerBase | |||||
{ | |||||
private readonly IJT809Config jT809Config; | |||||
private readonly IJT808Config jT808Config; | |||||
private readonly JT808Serializer jT808Serializer; | |||||
private readonly JT809Serializer jT809Serializer; | |||||
public JTToolsController( | |||||
IJT809Config jT809Config, | |||||
IJT808Config jT808Config) | |||||
{ | |||||
this.jT809Config = jT809Config; | |||||
this.jT808Config = jT808Config; | |||||
jT808Serializer = jT808Config.GetSerializer(); | |||||
jT809Serializer = jT809Config.GetSerializer(); | |||||
} | |||||
[Route("Parse808")] | |||||
[HttpPost] | |||||
public ActionResult<JTResultDto> Parse808([FromBody]JTRequestDto parameter) | |||||
{ | |||||
JTResultDto jTResultDto = new JTResultDto(); | |||||
try | |||||
{ | |||||
jTResultDto.Code = 200; | |||||
jTResultDto.Data = jT808Serializer.Deserialize(parameter.HexData.ToHexBytes()); | |||||
} | |||||
catch(JT808Exception ex) | |||||
{ | |||||
jTResultDto.Code = 500; | |||||
jTResultDto.Message = $"{ex.ErrorCode}-{ex.Message}"; | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
jTResultDto.Code = 500; | |||||
jTResultDto.Message = ex.Message; | |||||
} | |||||
return jTResultDto; | |||||
} | |||||
[Route("Parse809")] | |||||
[HttpPost] | |||||
public ActionResult<JTResultDto> Parse809([FromBody]JTRequestDto parameter) | |||||
{ | |||||
JTResultDto jTResultDto = new JTResultDto(); | |||||
try | |||||
{ | |||||
jTResultDto.Code = 200; | |||||
jTResultDto.Data = jT809Serializer.Deserialize(parameter.HexData.ToHexBytes()); | |||||
} | |||||
catch (JT809Exception ex) | |||||
{ | |||||
jTResultDto.Code = 500; | |||||
jTResultDto.Message = $"{ex.ErrorCode}-{ex.Message}"; | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
jTResultDto.Code = 500; | |||||
jTResultDto.Message = ex.Message; | |||||
} | |||||
return jTResultDto; | |||||
} | |||||
[Route("Parse1078")] | |||||
[HttpPost] | |||||
public ActionResult<JTResultDto> Parse1078([FromBody]JTRequestDto parameter) | |||||
{ | |||||
JTResultDto jTResultDto = new JTResultDto(); | |||||
try | |||||
{ | |||||
jTResultDto.Code = 200; | |||||
jTResultDto.Data = JT1078Serializer.Deserialize(parameter.HexData.ToHexBytes()); | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
jTResultDto.Code = 500; | |||||
jTResultDto.Message = ex.Message; | |||||
} | |||||
return jTResultDto; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,14 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace JTTools.Dtos | |||||
{ | |||||
public class JTRequestDto | |||||
{ | |||||
public string HexData { get; set; } | |||||
public bool Skip { get; set; } | |||||
public bool Custom { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,14 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading.Tasks; | |||||
namespace JTTools.Dtos | |||||
{ | |||||
public class JTResultDto | |||||
{ | |||||
public int Code { get; set; } | |||||
public string Message { get; set; } | |||||
public object Data { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,29 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk.Web"> | |||||
<PropertyGroup> | |||||
<TargetFramework>netcoreapp2.2</TargetFramework> | |||||
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Content Remove="appsettings.json" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="JT1078" Version="1.0.0" /> | |||||
<PackageReference Include="JT808" Version="2.1.2" /> | |||||
<PackageReference Include="JT808.Protocol.Extensions.JT1078" Version="1.0.1" /> | |||||
<PackageReference Include="JT809" Version="2.1.0" /> | |||||
<PackageReference Include="JT809.Protocol.Extensions.JT1078" Version="1.0.0" /> | |||||
<PackageReference Include="Microsoft.AspNetCore.App" /> | |||||
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" /> | |||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.5.2" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Include="appsettings.json"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
</ItemGroup> | |||||
</Project> |
@@ -0,0 +1,29 @@ | |||||
using Newtonsoft.Json; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace JTTools | |||||
{ | |||||
public class ByteArrayHexConverter : JsonConverter | |||||
{ | |||||
public override bool CanConvert(Type objectType) => objectType == typeof(byte[]); | |||||
public override bool CanRead => false; | |||||
public override bool CanWrite => true; | |||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => throw new NotImplementedException(); | |||||
private readonly string _separator; | |||||
public ByteArrayHexConverter(string separator = " ") => _separator = separator; | |||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |||||
{ | |||||
var hexString = string.Join(_separator, ((byte[])value).Select(p => p.ToString("X2"))); | |||||
writer.WriteValue(hexString); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,72 @@ | |||||
using Microsoft.AspNetCore; | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using Microsoft.AspNetCore.Builder; | |||||
using Microsoft.AspNetCore.Mvc; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using JT808.Protocol; | |||||
using JT809.Protocol; | |||||
using JT808.Protocol.Extensions.JT1078; | |||||
using JT809.Protocol.Extensions.JT1078; | |||||
using Newtonsoft.Json.Serialization; | |||||
using System; | |||||
using Microsoft.Extensions.Logging; | |||||
using NLog.Extensions.Logging; | |||||
using Microsoft.Extensions.Configuration; | |||||
namespace JTTools | |||||
{ | |||||
public class Program | |||||
{ | |||||
public static void Main(string[] args) | |||||
{ | |||||
WebHost.CreateDefaultBuilder(args) | |||||
.ConfigureAppConfiguration((hostingContext, config) => | |||||
{ | |||||
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); | |||||
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); | |||||
}) | |||||
.ConfigureKestrel(ksOptions=> | |||||
{ | |||||
ksOptions.ListenAnyIP(18888); | |||||
}) | |||||
.ConfigureLogging((context,logging) => { | |||||
//if (Environment.OSVersion.Platform == PlatformID.Unix) | |||||
//{ | |||||
// NLog.LogManager.LoadConfiguration("Configs/nlog.unix.config"); | |||||
//} | |||||
//else | |||||
//{ | |||||
// NLog.LogManager.LoadConfiguration("Configs/nlog.win.config"); | |||||
//} | |||||
//logging.AddNLog(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true }); | |||||
//logging.SetMinimumLevel(LogLevel.Trace); | |||||
}) | |||||
.ConfigureServices(services => | |||||
{ | |||||
services.AddMvc() | |||||
.AddJsonOptions(jsonOptions => | |||||
{ | |||||
jsonOptions.SerializerSettings.Converters.Add(new ByteArrayHexConverter()); | |||||
jsonOptions.SerializerSettings.ContractResolver = new DefaultContractResolver(); | |||||
}) | |||||
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2); | |||||
services.AddCors(options => | |||||
options.AddPolicy("Domain",builder => builder.WithOrigins("http://jttools.smallchi.cn") | |||||
.AllowAnyMethod() | |||||
.AllowAnyHeader() | |||||
.AllowAnyOrigin() | |||||
.AllowCredentials())); | |||||
services.AddJT808Configure() | |||||
.AddJT1078Configure(); | |||||
services.AddJT809Configure() | |||||
.AddJT1078Configure(); | |||||
}) | |||||
.Configure(app => { | |||||
app.UseCors("Domain"); | |||||
app.UseMvc(); | |||||
}) | |||||
.Build() | |||||
.Run(); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,9 @@ | |||||
{ | |||||
"Logging": { | |||||
"LogLevel": { | |||||
"Default": "Debug", | |||||
"System": "Information", | |||||
"Microsoft": "Information" | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,8 @@ | |||||
{ | |||||
"Logging": { | |||||
"LogLevel": { | |||||
"Default": "Debug" //Warning | |||||
} | |||||
}, | |||||
"AllowedHosts": "*" | |||||
} |
@@ -0,0 +1,166 @@ | |||||
<!DOCTYPE html> | |||||
<html> | |||||
<head> | |||||
<meta charset="utf-8"> | |||||
<title>JTTools解析工具</title> | |||||
<!-- import Vue.js --> | |||||
<script src="//vuejs.org/js/vue.min.js"></script> | |||||
<!-- import stylesheet --> | |||||
<link rel="stylesheet" href="//unpkg.com/iview/dist/styles/iview.css"> | |||||
<!-- import iView --> | |||||
<script src="//unpkg.com/iview/dist/iview.min.js"></script> | |||||
<script type="text/javascript" src="https://unpkg.com/axios/dist/axios.min.js"></script> | |||||
<script src="https://cdn.bootcss.com/dayjs/1.8.14/dayjs.min.js"></script> | |||||
<style> | |||||
.pane-content{ | |||||
width: 100%; | |||||
display: flex; | |||||
display: -webkit-flex; | |||||
align-items:center; | |||||
justify-content:center; | |||||
height: calc(100vh - 60px); | |||||
padding: 10px 20px; | |||||
} | |||||
.left,.right{ | |||||
width: 45%; | |||||
height: 100%; | |||||
display: inline-block; | |||||
} | |||||
.center{ | |||||
width: 10%; | |||||
display: flex; | |||||
display: -webkit-flex; | |||||
align-items: center; | |||||
justify-content: center; | |||||
} | |||||
textarea.ivu-input { | |||||
max-height: 100%; | |||||
min-height: 32px; | |||||
height: 100%; | |||||
} | |||||
.ivu-input-wrapper{ | |||||
height: 100%; | |||||
} | |||||
@media (max-width:1024px){ | |||||
.left,.right{ | |||||
width: 40%; | |||||
} | |||||
.center{ | |||||
width: 20%; | |||||
} | |||||
} | |||||
</style> | |||||
</head> | |||||
<body> | |||||
<div id="app"> | |||||
<tabs value="name1"> | |||||
<tab-pane label="JT808解析工具" name="name1" > | |||||
<div class="pane-content" > | |||||
<div class="left" > | |||||
<i-input type="textarea" placeholder="Enter something..." /> | |||||
</div> | |||||
<div class="center" > | |||||
<i-button type="primary">Primary</i-button> | |||||
</div> | |||||
<div class="right" > | |||||
<i-input type="textarea" placeholder="Enter something..." /> | |||||
</div> | |||||
</div> | |||||
</tab-pane> | |||||
<tab-pane label="JT809解析工具" name="name2"> | |||||
<div class="pane-content" > | |||||
<div class="left" > | |||||
<i-input type="textarea" placeholder="Enter something..." /> | |||||
</div> | |||||
<div class="center" > | |||||
<i-button type="primary">Primary2</i-button> | |||||
</div> | |||||
<div class="right" > | |||||
<i-input type="textarea" placeholder="Enter something..." /> | |||||
</div> | |||||
</div> | |||||
</tab-pane> | |||||
<tab-pane label="JT1078解析工具" name="name3"> | |||||
<div class="pane-content" > | |||||
<div class="left" > | |||||
<i-input type="textarea" placeholder="Enter something..." /> | |||||
</div> | |||||
<div class="center" > | |||||
<i-button type="primary">Primary3</i-button> | |||||
</div> | |||||
<div class="right" > | |||||
<i-input type="textarea" placeholder="Enter something..." /> | |||||
</div> | |||||
</div> | |||||
</tab-pane> | |||||
</tabs> | |||||
</div> | |||||
<script> | |||||
new Vue({ | |||||
el: '#app', | |||||
data: { | |||||
loading: false, | |||||
}, | |||||
mounted:function(){ | |||||
}, | |||||
methods: { | |||||
Api:{ | |||||
parse808:function(){ | |||||
this.loading=true; | |||||
axios.post('http://jttools.smallchi.cn/api/JTTools/Parse808',this.queryParameter) | |||||
.then((response)=>{ | |||||
if(response.data=="" || response.data==null){ | |||||
this.queryData=[]; | |||||
this.loading=false; | |||||
return; | |||||
} | |||||
this.queryData=response.data; | |||||
this.loading=false; | |||||
}) | |||||
.catch((error)=>{ | |||||
this.queryError=error; | |||||
this.loading=false; | |||||
}); | |||||
}, | |||||
parse809:function(){ | |||||
this.loading=true; | |||||
axios.post('http://jttools.smallchi.cn/api/JTTools/Parse809',this.queryParameter) | |||||
.then((response)=>{ | |||||
if(response.data=="" || response.data==null){ | |||||
this.queryData=[]; | |||||
this.loading=false; | |||||
return; | |||||
} | |||||
this.queryData=response.data; | |||||
this.loading=false; | |||||
}) | |||||
.catch((error)=>{ | |||||
this.queryError=error; | |||||
this.loading=false; | |||||
}); | |||||
}, | |||||
parse1078:function(){ | |||||
this.loading=true; | |||||
axios.post('http://jttools.smallchi.cn/api/JTTools/Parse1078',this.queryParameter) | |||||
.then((response)=>{ | |||||
if(response.data=="" || response.data==null){ | |||||
this.queryData=[]; | |||||
this.loading=false; | |||||
return; | |||||
} | |||||
this.queryData=response.data; | |||||
this.loading=false; | |||||
}) | |||||
.catch((error)=>{ | |||||
this.queryError=error; | |||||
this.loading=false; | |||||
}); | |||||
} | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
</body> | |||||
</html> |