Explorar el Código

1.完善http接口处理程序

2.添加http接口认证
3.添加http客户端DI测试
tags/pipeline-1.1.0
SmallChi(Koike) hace 4 años
padre
commit
a619bd382c
Se han modificado 13 ficheros con 215 adiciones y 84 borrados
  1. +0
    -60
      api/README.md
  2. +9
    -8
      src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Program.cs
  3. +9
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj
  4. +50
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808HttpClientTest.cs
  5. +6
    -0
      src/JT808.Gateway.Tests/JT808.Gateway.Test/appsettings.json
  6. +3
    -0
      src/JT808.Gateway.WebApiClientTool/JT808.Gateway.WebApiClientTool.csproj
  7. +34
    -0
      src/JT808.Gateway.WebApiClientTool/JT808.Gateway.WebApiClientTool.xml
  8. +4
    -4
      src/JT808.Gateway.WebApiClientTool/JT808HttpClient.cs
  9. +4
    -2
      src/JT808.Gateway.WebApiClientTool/JT808HttpClientExtensions.cs
  10. +48
    -0
      src/JT808.Gateway/Authorization/JT808AuthorizationDefault.cs
  11. +9
    -0
      src/JT808.Gateway/Extensions/JT808HttpContextExtensions.cs
  12. +3
    -0
      src/JT808.Gateway/JT808GatewayExtensions.cs
  13. +36
    -10
      src/JT808.Gateway/JT808HttpServer.cs

+ 0
- 60
api/README.md Ver fichero

@@ -18,12 +18,6 @@

[基于Udp管理会话服务](#udp_session)

## 4.消息包计数服务

[基于Tcp消息包计数服务](#tcp_counter)

[基于Udp消息包计数服务](#udp_counter)

## 接口请求对照表

### 公共接口请求
@@ -39,7 +33,6 @@
| 127.0.0.1:828/jt808api/Tcp/Session/GetAll| GET| 基于Tcp管理会话服务-获取会话集合|
| 127.0.0.1:828/jt808api/Tcp/Session/QueryTcpSessionByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号查询对应会话|
| 127.0.0.1:828/jt808api/Tcp/Session/RemoveByTerminalPhoneNo| POST| 基于Tcp管理会话服务-通过设备终端号移除对应会话|
| 127.0.0.1:828/jt808api/Tcp/GetAtomicCounter| GET| 基于Tcp消息包计数服务|

### 基于Udp接口请求

@@ -47,7 +40,6 @@
|:------|:------|:------|
| 127.0.0.1:828/jt808api/Udp/Session/GetAll| GET| 基于Udp管理会话服务-获取会话集合|
| 127.0.0.1:828/jt808api/Udp/Session/RemoveByTerminalPhoneNo| POST| 基于Udp管理会话服务-通过设备终端号移除对应会话|
| 127.0.0.1:828/jt808api/Udp/GetAtomicCounter| GET| 基于Udp消息包计数服务|

### 统一对象返回 JT808ResultDto\<T>

@@ -240,55 +232,3 @@
"Data":true
}
```

### <span id="tcp_counter">基于Tcp消息包计数服务</span>

请求地址:Tcp/GetAtomicCounter

请求方式:GET

返回数据:

|属性|数据类型|参数说明|
|------|:------:|:------|
| MsgSuccessCount| long| 消息包成功数|
| MsgFailCount| long| 消息包失败数|

返回结果:

``` counter
{
"Message":"",
"Code":200,
"Data":{
"MsgSuccessCount":10000,
"MsgFailCount":0
}
}
```

### <span id="udp_counter">基于Udp消息包计数服务</span>

请求地址:Udp/GetAtomicCounter

请求方式:GET

返回数据:

|属性|数据类型|参数说明|
|------|:------:|:------|
| MsgSuccessCount| long| 消息包成功数|
| MsgFailCount| long| 消息包失败数|

返回结果:

``` counter
{
"Message":"",
"Code":200,
"Data":{
"MsgSuccessCount":1000,
"MsgFailCount":0
}
}
```

+ 9
- 8
src/JT808.Gateway.Tests/JT808.Gateway.NormalHosting/Program.cs Ver fichero

@@ -53,20 +53,21 @@ namespace JT808.Gateway.NormalHosting
//// options.UdpPort = 808;
////})
.AddNormalGateway(hostContext.Configuration)
.ReplaceNormalReplyMessageHandler<JT808NormalReplyMessageHandlerImpl>()
.AddMsgLogging<JT808MsgLogging>()
.AddTraffic()
.AddSessionNotice()
.AddTransmit(hostContext.Configuration)
//.ReplaceNormalReplyMessageHandler<JT808NormalReplyMessageHandlerImpl>()
//.AddMsgLogging<JT808MsgLogging>()
//.AddTraffic()
//.AddSessionNotice()
//.AddTransmit(hostContext.Configuration)
.AddTcp()
.AddUdp()
//.AddUdp()
.AddHttp()
;
//流量统计
services.AddHostedService<TrafficJob>();
//services.AddHostedService<TrafficJob>();
//grpc客户端调用
//services.AddHostedService<CallGrpcClientJob>();
//客户端测试 依赖AddClient()服务
services.AddHostedService<UpJob>();
//services.AddHostedService<UpJob>();
});

await serverHostBuilder.RunConsoleAsync();


+ 9
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808.Gateway.Test.csproj Ver fichero

@@ -7,6 +7,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.7" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.7" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.7" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="System.IO.Pipelines" Version="4.7.2" />
@@ -22,7 +24,14 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\JT808.Gateway.WebApiClientTool\JT808.Gateway.WebApiClientTool.csproj" />
<ProjectReference Include="..\..\JT808.Gateway\JT808.Gateway.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

+ 50
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Test/JT808HttpClientTest.cs Ver fichero

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using JT808.Gateway.WebApiClientTool;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Xunit;

namespace JT808.Gateway.Test
{
public class JT808HttpClientTest
{
[Fact(DisplayName="客户端DI测试配置文件1")]
public void Test()
{
IServiceCollection serviceDescriptors = new ServiceCollection();
serviceDescriptors.AddJT808WebApiClientTool(new Uri("http://localhost/"), "123456");
}

[Fact(DisplayName = "客户端DI测试配置文件2")]
public void Test1()
{
var builder = new ConfigurationBuilder();
builder.AddJsonFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json"));
IServiceCollection serviceDescriptors = new ServiceCollection();
var configuration = builder.Build();
var token = configuration.GetSection("JT808WebApiClientToolConfig:Token").Get<string>();
var uri = configuration.GetSection("JT808WebApiClientToolConfig:Uri").Get<string>();
Assert.Equal("123456", token);
Assert.Equal("http://localhost/", uri);
serviceDescriptors.AddJT808WebApiClientTool(builder.Build());
}

[Fact(DisplayName = "使用postman测试")]
public void Test2()
{
//头部添加或者url参数带有token=123456
//TCP
//http://127.0.0.1:828/jt808api/Tcp/Session/GetAll
//http://127.0.0.1:828/jt808api/Tcp/Session/QueryTcpSessionByTerminalPhoneNo
//123456789
//http://127.0.0.1:828/jt808api/Tcp/Session/RemoveByTerminalPhoneNo
//123456789
///http://127.0.0.1:828/jt808api/UnificationSend
//{"TerminalPhoneNo":"123456789","Data":"7e 01 02 7e"}
//{"TerminalPhoneNo":"123456789","Data":"7e01027e"}
}
}
}

+ 6
- 0
src/JT808.Gateway.Tests/JT808.Gateway.Test/appsettings.json Ver fichero

@@ -0,0 +1,6 @@
{
"JT808WebApiClientToolConfig": {
"Token": "123456",
"Uri": "http://localhost/"
}
}

+ 3
- 0
src/JT808.Gateway.WebApiClientTool/JT808.Gateway.WebApiClientTool.csproj Ver fichero

@@ -22,6 +22,9 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>JT808.Gateway.WebApiClientTool.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>JT808.Gateway.WebApiClientTool.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\LICENSE" Pack="true" PackagePath="" />
</ItemGroup>


+ 34
- 0
src/JT808.Gateway.WebApiClientTool/JT808.Gateway.WebApiClientTool.xml Ver fichero

@@ -0,0 +1,34 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>JT808.Gateway.WebApiClientTool</name>
</assembly>
<members>
<member name="M:JT808.Gateway.WebApiClientTool.JT808HttpClient.GetTcpSessionAll">
<summary>
会话服务集合
</summary>
<returns></returns>
</member>
<member name="M:JT808.Gateway.WebApiClientTool.JT808HttpClient.RemoveByTerminalPhoneNo(System.String)">
<summary>
会话服务-通过设备终端号移除对应会话
</summary>
<param name="terminalPhoneNo"></param>
<returns></returns>
</member>
<member name="M:JT808.Gateway.WebApiClientTool.JT808HttpClient.UnificationSend(JT808.Gateway.Abstractions.Dtos.JT808UnificationSendRequestDto)">
<summary>
统一下发信息
</summary>
<param name="jT808UnificationSendRequestDto"></param>
<returns></returns>
</member>
<member name="M:JT808.Gateway.WebApiClientTool.JT808HttpClient.GetUdpSessionAll">
<summary>
会话服务集合
</summary>
<returns></returns>
</member>
</members>
</doc>

+ 4
- 4
src/JT808.Gateway.WebApiClientTool/JT808HttpClient.cs Ver fichero

@@ -25,7 +25,7 @@ namespace JT808.Gateway.WebApiClientTool
public async ValueTask<JT808ResultDto<List<JT808TcpSessionInfoDto>>> GetTcpSessionAll()
{
var request = new HttpRequestMessage(HttpMethod.Get, JT808GatewayConstants.JT808WebApiRouteTable.SessionTcpGetAll);
var response = HttpClient.SendAsync(request).Result;
var response = await HttpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var data = await response.Content.ReadAsStreamAsync();
var value = await JsonSerializer.DeserializeAsync<JT808ResultDto<List<JT808TcpSessionInfoDto>>>(data);
@@ -41,7 +41,7 @@ namespace JT808.Gateway.WebApiClientTool
{
var request = new HttpRequestMessage(HttpMethod.Post, JT808GatewayConstants.JT808WebApiRouteTable.SessionRemoveByTerminalPhoneNo);
request.Content = new StringContent(terminalPhoneNo);
var response = HttpClient.SendAsync(request).Result;
var response = await HttpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var data = await response.Content.ReadAsStreamAsync();
var value = await JsonSerializer.DeserializeAsync<JT808ResultDto<bool>>(data);
@@ -57,7 +57,7 @@ namespace JT808.Gateway.WebApiClientTool
{
var request = new HttpRequestMessage(HttpMethod.Post, JT808GatewayConstants.JT808WebApiRouteTable.UnificationSend);
request.Content = new StringContent(JsonSerializer.Serialize(jT808UnificationSendRequestDto));
var response = HttpClient.SendAsync(request).Result;
var response = await HttpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var data = await response.Content.ReadAsStreamAsync();
var value = await JsonSerializer.DeserializeAsync<JT808ResultDto<bool>>(data);
@@ -71,7 +71,7 @@ namespace JT808.Gateway.WebApiClientTool
public async ValueTask<JT808ResultDto<List<JT808UdpSessionInfoDto>>> GetUdpSessionAll()
{
var request = new HttpRequestMessage(HttpMethod.Get, JT808GatewayConstants.JT808WebApiRouteTable.SessionUdpGetAll);
var response = HttpClient.SendAsync(request).Result;
var response = await HttpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var data = await response.Content.ReadAsStreamAsync();
var value = await JsonSerializer.DeserializeAsync<JT808ResultDto<List<JT808UdpSessionInfoDto>>>(data);


+ 4
- 2
src/JT808.Gateway.WebApiClientTool/JT808HttpClientExtensions.cs Ver fichero

@@ -8,10 +8,11 @@ namespace JT808.Gateway.WebApiClientTool
{
public static class JT808HttpClientExtensions
{
public static IServiceCollection AddJT808WebApiClientTool(this IServiceCollection serviceDescriptors, Uri webapiUri)
public static IServiceCollection AddJT808WebApiClientTool(this IServiceCollection serviceDescriptors, Uri webapiUri,string token)
{
serviceDescriptors.AddHttpClient("JT808WebApiClientTool", c =>
{
c.DefaultRequestHeaders.Add("token", token);
c.BaseAddress = webapiUri;
c.Timeout = TimeSpan.FromSeconds(3);
})
@@ -23,7 +24,8 @@ namespace JT808.Gateway.WebApiClientTool
{
serviceDescriptors.AddHttpClient("JT808WebApiClientTool", c =>
{
c.BaseAddress = new Uri(configuration.GetSection("JT808WebApiClientToolConfig").Get<string>());
c.DefaultRequestHeaders.Add("token", configuration.GetSection("JT808WebApiClientToolConfig:Token").Get<string>());
c.BaseAddress = new Uri(configuration.GetSection("JT808WebApiClientToolConfig:Uri").Get<string>());
c.Timeout = TimeSpan.FromSeconds(3);
})
.AddTypedClient<JT808HttpClient>();


+ 48
- 0
src/JT808.Gateway/Authorization/JT808AuthorizationDefault.cs Ver fichero

@@ -0,0 +1,48 @@
using JT808.Gateway.Abstractions;
using JT808.Gateway.Configurations;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Claims;
using System.Security.Principal;
using System.Text;

namespace JT808.Gateway.Authorization
{
class JT808AuthorizationDefault : IJT808Authorization
{
private IOptionsMonitor<JT808Configuration> optionsMonitor;
public JT808AuthorizationDefault(IOptionsMonitor<JT808Configuration> optionsMonitor)
{
this.optionsMonitor = optionsMonitor;
}
public bool Authorization(HttpListenerContext context, out IPrincipal principal)
{
var uriSpan = context.Request.Url.AbsoluteUri.AsSpan();
var uriParamStr = uriSpan.Slice(uriSpan.IndexOf('?')+1).ToString().ToLower();
var uriParams = uriParamStr.Split('&');
var tokenParam = uriParams.FirstOrDefault(m => m.Contains("token"));
string tokenValue = string.Empty;
if (!string.IsNullOrEmpty(tokenParam))
{
tokenValue = tokenParam.Split('=')[1];
}
else
{
tokenValue = context.Request.Headers.Get("token");
}
if (optionsMonitor.CurrentValue.WebApiToken == tokenValue)
{
principal = new ClaimsPrincipal(new GenericIdentity(tokenValue));
return true;
}
else
{
principal = null;
return false;
}
}
}
}

+ 9
- 0
src/JT808.Gateway/Extensions/JT808HttpContextExtensions.cs Ver fichero

@@ -46,6 +46,15 @@ namespace JT808.Gateway.Extensions
context.Response.Close();
}

public static void Http405(this HttpListenerContext context)
{
context.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed;
context.Response.KeepAlive = false;
context.Response.ContentType = jsonType;
context.Response.OutputStream.Close();
context.Response.Close();
}

public static async ValueTask Http500(this HttpListenerContext context)
{
byte[] b = Encoding.UTF8.GetBytes("inner error");


+ 3
- 0
src/JT808.Gateway/JT808GatewayExtensions.cs Ver fichero

@@ -1,4 +1,5 @@
using JT808.Gateway.Abstractions;
using JT808.Gateway.Authorization;
using JT808.Gateway.Configurations;
using JT808.Gateway.Enums;
using JT808.Gateway.Handlers;
@@ -77,6 +78,7 @@ namespace JT808.Gateway

public static IJT808GatewayBuilder AddHttp(this IJT808GatewayBuilder config)
{
config.JT808Builder.Services.AddSingleton<IJT808Authorization, JT808AuthorizationDefault>();
config.JT808Builder.Services.AddSingleton<JT808MsgIdDefaultWebApiHandler>();
config.JT808Builder.Services.AddHostedService<JT808HttpServer>();
return config;
@@ -85,6 +87,7 @@ namespace JT808.Gateway
public static IJT808GatewayBuilder AddHttp<TJT808MsgIdDefaultWebApiHandler>(this IJT808GatewayBuilder config)
where TJT808MsgIdDefaultWebApiHandler: JT808MsgIdDefaultWebApiHandler
{
config.JT808Builder.Services.AddSingleton<IJT808Authorization, JT808AuthorizationDefault>();
config.JT808Builder.Services.AddSingleton(typeof(JT808MsgIdDefaultWebApiHandler),typeof(TJT808MsgIdDefaultWebApiHandler));
config.JT808Builder.Services.AddHostedService<JT808HttpServer>();
return config;


+ 36
- 10
src/JT808.Gateway/JT808HttpServer.cs Ver fichero

@@ -10,7 +10,9 @@ using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.WebSockets;
using System.Security.Principal;
using System.Text;
@@ -62,14 +64,19 @@ namespace JT808.Gateway
Logger.LogWarning(ex, $"{ex.Message}:使用cmd命令[netsh http add urlacl url=http://*:{Configuration.WebApiPort}/ user=Everyone]");
}
Logger.LogInformation($"JT808 Http Server start at {IPAddress.Any}:{Configuration.WebApiPort}.");
Task.Factory.StartNew(async() =>
Task.Factory.StartNew(async () =>
{
while (listener.IsListening)
{
var context = await listener.GetContextAsync();
try
{
if (authorization.Authorization(context,out var principal))
if (context.Request.RawUrl.StartsWith("/favicon.ico"))
{
context.Http404();
continue;
}
if (authorization.Authorization(context, out var principal))
{
await ProcessRequestAsync(context, principal);
}
@@ -90,18 +97,37 @@ namespace JT808.Gateway

private async ValueTask ProcessRequestAsync(HttpListenerContext context, IPrincipal principal)
{
if(context.Request.RawUrl.StartsWith("/favicon.ico"))
var router = MsgIdDefaultWebApiHandler.HandlerDict.FirstOrDefault(f => context.Request.RawUrl.StartsWith(f.Key));
if (router.Key == null)
{
context.Http404();
return;
}
var uri = new Uri(context.Request.RawUrl);
//todo: 处理对应的handler
string url = uri.AbsolutePath;
var queryParams = uri.Query.Substring(1, uri.Query.Length - 1).Split('&');
if (queryParams.Length < 2) {
context.Http404();
return;
if(context.Request.HttpMethod == HttpMethod.Get.Method)
{
var index = context.Request.Url.AbsoluteUri.IndexOf('?');
if (index > 0)
{
var uriParamStr = context.Request.Url.AbsoluteUri.Substring(index + 1).ToString();
await context.HttpSend(router.Value(uriParamStr));
}
else
{
await context.HttpSend(router.Value(""));
}
}
else if(context.Request.HttpMethod == HttpMethod.Post.Method)
{
string json = string.Empty;
using (var reader = new StreamReader(context.Request.InputStream,context.Request.ContentEncoding))
{
json = reader.ReadToEnd();
}
await context.HttpSend(router.Value(json));
}
else
{
context.Http405();
}
}



Cargando…
Cancelar
Guardar