浏览代码

脑子不够用。。。

tags/old
SmallChi 6 年前
父节点
当前提交
41cf3697ac
共有 11 个文件被更改,包括 202 次插入137 次删除
  1. +1
    -0
      src/JT809Netty.Core/Handlers/JT809DecodeHandler.cs
  2. +9
    -5
      src/JT809Netty.Core/Handlers/JT809DownMasterLinkConnectionHandler.cs
  3. +12
    -4
      src/JT809Netty.Core/Handlers/JT809DownMasterLinkServiceHandler.cs
  4. +0
    -9
      src/JT809Netty.Core/Handlers/JT809DownSlaveLinkConnectionHandler.cs
  5. +27
    -5
      src/JT809Netty.Core/JT809DownMasterLinkNettyService.cs
  6. +1
    -1
      src/JT809Netty.Core/JT809DownSlaveLinkNettyService.cs
  7. +3
    -3
      src/JT809Netty.Core/JT809Netty.Core.csproj
  8. +0
    -108
      src/JT809Netty.Core/ServiceHandlers/JT809BusinessTypeHandler.cs
  9. +139
    -0
      src/JT809Netty.Core/ServiceHandlers/JT809DownMasterLinkBusinessTypeHandler.cs
  10. +9
    -1
      src/JT809Netty.DownMasterLink/Program.cs
  11. +1
    -1
      src/JT809Netty.sln

+ 1
- 0
src/JT809Netty.Core/Handlers/JT809DecodeHandler.cs 查看文件

@@ -42,6 +42,7 @@ namespace JT809Netty.Core.Handlers
if (logger.IsEnabled(LogLevel.Debug))
{
msg = ByteBufferUtil.HexDump(buffer);
logger.LogDebug("accept package <<<" + msg);
logger.LogDebug("accept package success count<<<" + MsgSuccessCounter.Count.ToString());
}
}


+ 9
- 5
src/JT809Netty.Core/Handlers/JT809DownMasterLinkConnectionHandler.cs 查看文件

@@ -10,6 +10,8 @@ using System.Threading.Tasks;
using JT809.Protocol;
using DotNetty.Buffers;
using JT809Netty.Core.ServiceHandlers;
using System.Threading;
using System;

namespace JT809Netty.Core.Handlers
{
@@ -22,20 +24,22 @@ namespace JT809Netty.Core.Handlers

private readonly IOptionsMonitor<JT809NettyOptions> optionsMonitor;

private readonly JT809BusinessTypeHandler jT809BusinessTypeHandler;
private readonly JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler;

public JT809DownMasterLinkConnectionHandler(
JT809BusinessTypeHandler jT809BusinessTypeHandler,
JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler,
IOptionsMonitor<JT809NettyOptions> optionsMonitor,
ILoggerFactory loggerFactory)
{
this.jT809BusinessTypeHandler = jT809BusinessTypeHandler;
this.jT809DownMasterLinkBusinessTypeHandler = jT809DownMasterLinkBusinessTypeHandler;
this.optionsMonitor = optionsMonitor;
logger = loggerFactory.CreateLogger<JT809DownMasterLinkConnectionHandler>();
}

public override void ChannelActive(IChannelHandlerContext context)
{
if (logger.IsEnabled(LogLevel.Debug))
logger.LogDebug(">>>Activate the channel.");
base.ChannelActive(context);
}

@@ -75,12 +79,12 @@ namespace JT809Netty.Core.Handlers
if (idleStateEvent != null)
{
string channelId = context.Channel.Id.AsShortText();
logger.LogInformation($"{idleStateEvent.State.ToString()}>>>{channelId}");
switch (idleStateEvent.State)
{
case IdleState.WriterIdle:
//发送心跳保持
jT809BusinessTypeHandler.Msg0x1005(context);
logger.LogInformation($"{idleStateEvent.State.ToString()} heartbeat>>>{channelId}");
jT809DownMasterLinkBusinessTypeHandler.Msg0x1005(context);
break;
}
}


+ 12
- 4
src/JT809Netty.Core/Handlers/JT809DownMasterLinkServiceHandler.cs 查看文件

@@ -14,17 +14,20 @@ using JT809.Protocol.JT809Exceptions;

namespace JT809Netty.Core.Handlers
{
/// <summary>
/// 下级平台主链路
/// </summary>
public class JT809DownMasterLinkServiceHandler : ChannelHandlerAdapter
{
private readonly ILogger<JT809DownMasterLinkServiceHandler> logger;

private readonly JT809BusinessTypeHandler jT809BusinessTypeHandler;
private readonly JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler;

public JT809DownMasterLinkServiceHandler(
JT809BusinessTypeHandler jT809BusinessTypeHandler,
JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler,
ILoggerFactory loggerFactory)
{
this.jT809BusinessTypeHandler = jT809BusinessTypeHandler;
this.jT809DownMasterLinkBusinessTypeHandler = jT809DownMasterLinkBusinessTypeHandler;
logger = loggerFactory.CreateLogger<JT809DownMasterLinkServiceHandler>();
}

@@ -34,7 +37,12 @@ namespace JT809Netty.Core.Handlers
string receive = string.Empty;
try
{
if (logger.IsEnabled(LogLevel.Debug))
logger.LogDebug(JsonConvert.SerializeObject(jT809Package));
if (jT809DownMasterLinkBusinessTypeHandler.ResponseHandlerDict.TryGetValue(jT809Package.Header.BusinessType,out var action))
{
action(jT809Package, context);
}
}
catch (JT809Exception ex)
{


+ 0
- 9
src/JT809Netty.Core/Handlers/JT809DownSlaveLinkConnectionHandler.cs 查看文件

@@ -73,15 +73,6 @@ namespace JT809Netty.Core.Handlers
case IdleState.ReaderIdle:
//下级平台连续 3min 未收到上级平台发送的从链路保持应答数据包,则认为上级平台的连接中断,将主动断开数据传输从链路。
context.CloseAsync();
break;
//case IdleState.WriterIdle:

// break;
//case IdleState.AllIdle:

// break;
default:

break;
}
}


+ 27
- 5
src/JT809Netty.Core/JT809DownMasterLinkNettyService.cs 查看文件

@@ -7,8 +7,10 @@ using DotNetty.Transport.Channels.Sockets;
using DotNetty.Transport.Libuv;
using JT809Netty.Core.Configs;
using JT809Netty.Core.Handlers;
using JT809Netty.Core.ServiceHandlers;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
@@ -32,10 +34,20 @@ namespace JT809Netty.Core

readonly IOptionsMonitor<JT809NettyOptions> nettyOptions;

IChannel ClientChannel;

private readonly JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler;

private readonly ILogger<JT809DownMasterLinkNettyService> logger;

public JT809DownMasterLinkNettyService(
ILoggerFactory loggerFactory,
JT809DownMasterLinkBusinessTypeHandler jT809DownMasterLinkBusinessTypeHandler,
IOptionsMonitor<JT809NettyOptions> nettyOptionsAccessor,
IServiceProvider serviceProvider)
{
logger = loggerFactory.CreateLogger<JT809DownMasterLinkNettyService>();
this.jT809DownMasterLinkBusinessTypeHandler = jT809DownMasterLinkBusinessTypeHandler;
nettyOptions = nettyOptionsAccessor;
this.serviceProvider = serviceProvider;
}
@@ -54,8 +66,10 @@ namespace JT809Netty.Core
{
InitChannel(channel);
}))
.Option(ChannelOption.SoBacklog, 1048576);
IChannel clientChannel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(nettyOptions.CurrentValue.Host), nettyOptions.CurrentValue.Port));
.Option(ChannelOption.SoBacklog, 1048576);
ClientChannel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(nettyOptions.CurrentValue.Host), nettyOptions.CurrentValue.Port));

jT809DownMasterLinkBusinessTypeHandler.Msg0x1001(ClientChannel);
}
catch (Exception ex)
{
@@ -69,11 +83,19 @@ namespace JT809Netty.Core
{
try
{
Task.WhenAll(workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)));
jT809DownMasterLinkBusinessTypeHandler.Msg0x1003(ClientChannel);
// 已发送注销请求,等待30s,待服务器响应
int sleepTime = 50000;
logger.LogInformation($">>>The logout request has been sent, waiting for {sleepTime/1000}s for the server to respond...");
Thread.Sleep(sleepTime);
logger.LogInformation($"Check Status:<<<{jT809DownMasterLinkBusinessTypeHandler.Status.ToString()}");
ClientChannel.CloseAsync().ContinueWith((state) => {
Task.WhenAll(workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)));
});
}
catch (Exception ex)
{

logger.LogError(ex,"");
}
return Task.CompletedTask;
}
@@ -84,7 +106,7 @@ namespace JT809Netty.Core
try
{
//下级平台应每 1min 发送一个主链路保持清求数据包到上级平台以保持链路连接
channel.Pipeline.AddLast("systemIdleState", new WriteTimeoutHandler(60));
channel.Pipeline.AddLast("systemIdleState", new IdleStateHandler(0, 60, 0));
channel.Pipeline.AddLast("jt809DownMasterLinkConnection", scope.ServiceProvider.GetRequiredService<JT809DownMasterLinkConnectionHandler>());
channel.Pipeline.AddLast("jt809Buffer", new DelimiterBasedFrameDecoder(int.MaxValue, Unpooled.CopiedBuffer(new byte[] { JT809.Protocol.JT809Package.BEGINFLAG }), Unpooled.CopiedBuffer(new byte[] { JT809.Protocol.JT809Package.ENDFLAG })));
channel.Pipeline.AddLast("jt809Decode", scope.ServiceProvider.GetRequiredService<JT809DecodeHandler>());


+ 1
- 1
src/JT809Netty.Core/JT809DownSlaveLinkNettyService.cs 查看文件

@@ -93,7 +93,7 @@ namespace JT809Netty.Core
{
var scope = serviceProvider.CreateScope();
//下级平台连续 3min 未收到上级平台发送的从链路保持应答数据包,则认为上级平台的连接中断,将主动断开数据传输从链路。
channel.Pipeline.AddLast("systemIdleState", new ReadTimeoutHandler(180));
channel.Pipeline.AddLast("systemIdleState", new IdleStateHandler(180, 0, 0));
channel.Pipeline.AddLast("jt809DownSlaveLinkConnection", scope.ServiceProvider.GetRequiredService<JT809DownSlaveLinkConnectionHandler>());
channel.Pipeline.AddLast("jt809Buffer", new DelimiterBasedFrameDecoder(int.MaxValue, Unpooled.CopiedBuffer(new byte[] { JT809.Protocol.JT809Package.BEGINFLAG }), Unpooled.CopiedBuffer(new byte[] { JT809.Protocol.JT809Package.ENDFLAG })));
channel.Pipeline.AddLast("jt809Decode", scope.ServiceProvider.GetRequiredService<JT809DecodeHandler>());


+ 3
- 3
src/JT809Netty.Core/JT809Netty.Core.csproj 查看文件

@@ -10,9 +10,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="DotNetty.Handlers" Version="0.5.0" />
<PackageReference Include="DotNetty.Transport.Libuv" Version="0.5.0" />
<PackageReference Include="JT809" Version="1.0.2" />
<PackageReference Include="DotNetty.Handlers" Version="0.6.0" />
<PackageReference Include="DotNetty.Transport.Libuv" Version="0.6.0" />
<PackageReference Include="JT809" Version="1.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />


+ 0
- 108
src/JT809Netty.Core/ServiceHandlers/JT809BusinessTypeHandler.cs 查看文件

@@ -1,108 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using DotNetty.Transport.Channels;
using JT809.Protocol;
using JT809.Protocol.JT809Enums;
using JT809.Protocol.JT809MessageBody;
using JT809.Protocol.JT809Extensions;
using DotNetty.Buffers;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace JT809Netty.Core.ServiceHandlers
{
public class JT809BusinessTypeHandler
{
public Dictionary<JT809BusinessType, Func<IChannelHandlerContext, JT809Package>> RequestHandlerDict { get; }

public Dictionary<JT809BusinessType, Action<JT809Package, IChannelHandlerContext>> ResponseHandlerDict { get; }

private readonly ILogger<JT809BusinessTypeHandler> logger;

/// <summary>
/// 初始化业务处理
/// </summary>
public JT809BusinessTypeHandler(
ILoggerFactory loggerFactory
)
{
logger = loggerFactory.CreateLogger<JT809BusinessTypeHandler>();
//RequestHandlerDict = new Dictionary<JT809BusinessType, Func<IChannelHandlerContext, JT809Package>>
//{
// {JT809.Protocol.JT809Enums.JT809BusinessType.UP_CONNECT_REQ, Msg0x1001},
// {JT809.Protocol.JT809Enums.JT809BusinessType.UP_DISCONNECT_REQ, Msg0x1003},
// {JT809.Protocol.JT809Enums.JT809BusinessType.UP_LINKTEST_REQ, Msg0x1005},
// //{JT809.Protocol.JT809Enums.JT809BusinessType.UP_DISCONNECT_INFORM, Msg0x1007},
// //{JT809.Protocol.JT809Enums.JT809BusinessType.UP_CLOSELINK_INFORM, Msg0x1008},
//};
ResponseHandlerDict = new Dictionary<JT809BusinessType, Action<JT809Package, IChannelHandlerContext>>
{
{JT809.Protocol.JT809Enums.JT809BusinessType.UP_CONNECT_RSP, Msg0x1002},
{JT809.Protocol.JT809Enums.JT809BusinessType.UP_DISCONNECT_RSP, Msg0x1004},
{JT809.Protocol.JT809Enums.JT809BusinessType.UP_LINKTEST_RSP, Msg0x1006},
};
}

public JT809Package Msg0x1001(IChannelHandlerContext channelHandlerContext)
{
JT809Package loginPackage = JT809BusinessType.UP_CONNECT_REQ.Create(new JT809_0x1001
{
UserId=1234,
DownLinkIP="127.0.0.1",
DownLinkPort=8091,
Password="20181009"
});
try
{
byte[] sendLoginData = JT809Serializer.Serialize(loginPackage, 1000);
channelHandlerContext.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendLoginData));
return loginPackage;
}
catch (Exception)
{

throw;
}

}

public void Msg0x1002(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext)
{
logger.LogDebug(JsonConvert.SerializeObject(jT809Package));
}

public JT809Package Msg0x1003(IChannelHandlerContext channelHandlerContext)
{
return null;
}

public void Msg0x1004(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext)
{

}

public JT809Package Msg0x1005(IChannelHandlerContext channelHandlerContext)
{
JT809Package heartbeatPackage = JT809BusinessType.UP_LINKTEST_REQ.Create(new JT809_0x1005());
byte[] sendHeartbeatData = JT809Serializer.Serialize(heartbeatPackage, 100);
channelHandlerContext.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendHeartbeatData));
return heartbeatPackage;
}

public void Msg0x1006(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext)
{

}

public JT809Package Msg0x1007(IChannelHandlerContext channelHandlerContext)
{
return null;
}

public void Msg0x1008(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext)
{

}
}
}

+ 139
- 0
src/JT809Netty.Core/ServiceHandlers/JT809DownMasterLinkBusinessTypeHandler.cs 查看文件

@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Text;
using DotNetty.Transport.Channels;
using JT809.Protocol;
using JT809.Protocol.JT809Enums;
using JT809.Protocol.JT809MessageBody;
using JT809.Protocol.JT809Extensions;
using DotNetty.Buffers;
using Microsoft.Extensions.Logging;

namespace JT809Netty.Core.ServiceHandlers
{
public class JT809DownMasterLinkBusinessTypeHandler
{
public ConnectionStatus Status { get; private set; } = ConnectionStatus.蓄势待发;

public Dictionary<JT809BusinessType, Func<IChannelHandlerContext, JT809Package>> RequestHandlerDict { get; }

public Dictionary<JT809BusinessType, Action<JT809Package, IChannelHandlerContext>> ResponseHandlerDict { get; }

private readonly ILogger<JT809DownMasterLinkBusinessTypeHandler> logger;

public JT809DownMasterLinkBusinessTypeHandler(
ILoggerFactory loggerFactory)
{
logger = loggerFactory.CreateLogger<JT809DownMasterLinkBusinessTypeHandler>();
RequestHandlerDict = new Dictionary<JT809BusinessType, Func<IChannelHandlerContext, JT809Package>>
{
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路登录请求消息, Msg0x1001},
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路注销请求消息, Msg0x1003},
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路连接保持请求消息, Msg0x1005},
//{JT809.Protocol.JT809Enums.JT809BusinessType.UP_DISCONNECT_INFORM, Msg0x1007},
//{JT809.Protocol.JT809Enums.JT809BusinessType.UP_CLOSELINK_INFORM, Msg0x1008},
};
ResponseHandlerDict = new Dictionary<JT809BusinessType, Action<JT809Package, IChannelHandlerContext>>
{
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路登录应答消息, Msg0x1002},
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路注销应答消息, Msg0x1004},
{JT809.Protocol.JT809Enums.JT809BusinessType.主链路连接保持应答消息, Msg0x1006},
};
}

public enum ConnectionStatus
{
蓄势待发=0,
下级平台主链路已发送注销请求=1,
上级级平台主链路已发送注销应答 = 2,
}

public JT809Package Msg0x1001(IChannelHandlerContext channelHandlerContext)
{
JT809Package loginPackage = JT809BusinessType.主链路登录请求消息.Create(new JT809_0x1001
{
UserId = 1234,
Password = "20181009",
DownLinkIP = "127.0.0.1",
DownLinkPort = 8091
});
byte[] sendLoginData = JT809Serializer.Serialize(loginPackage, 256);
channelHandlerContext.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendLoginData));
return loginPackage;
}

public JT809Package Msg0x1001(IChannel channel)
{
JT809Package loginPackage = JT809BusinessType.主链路登录请求消息.Create(new JT809_0x1001
{
UserId = 1234,
Password = "20181009",
DownLinkIP = "127.0.0.1",
DownLinkPort = 8091
});
byte[] sendLoginData = JT809Serializer.Serialize(loginPackage, 256);
channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendLoginData));
return loginPackage;
}

public JT809Package Msg0x1003(IChannelHandlerContext channelHandlerContext)
{
JT809Package loginPackage = JT809BusinessType.主链路登录请求消息.Create(new JT809_0x1001
{
UserId = 1234,
Password = "20181009",
DownLinkIP = "127.0.0.1",
DownLinkPort = 8091
});
byte[] sendLoginData = JT809Serializer.Serialize(loginPackage, 256);
channelHandlerContext.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendLoginData));
return loginPackage;
}

public JT809Package Msg0x1003(IChannel channel)
{
JT809Package logoutPackage = JT809BusinessType.主链路注销请求消息.Create(new JT809_0x1003
{
UserId = 1234,
Password = "20181009",
});
byte[] sendLoginData = JT809Serializer.Serialize(logoutPackage, 128);
channel.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendLoginData));
Status = ConnectionStatus.下级平台主链路已发送注销请求;
return logoutPackage;
}

public JT809Package Msg0x1005(IChannelHandlerContext channelHandlerContext)
{
JT809Package heartbeatPackage = JT809BusinessType.主链路连接保持请求消息.Create();
byte[] sendHeartbeatData = JT809Serializer.Serialize(heartbeatPackage, 100);
channelHandlerContext.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendHeartbeatData));
return heartbeatPackage;
}

public JT809Package Msg0x1007(IChannelHandlerContext channelHandlerContext)
{
return null;
}

public void Msg0x1002(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext)
{

}

public void Msg0x1004(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext)
{
Status = ConnectionStatus.上级级平台主链路已发送注销应答;
}

public void Msg0x1006(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext)
{

}

public void Msg0x1008(JT809Package jT809Package, IChannelHandlerContext channelHandlerContext)
{

}
}
}

+ 9
- 1
src/JT809Netty.DownMasterLink/Program.cs 查看文件

@@ -16,6 +16,14 @@ namespace JT809Netty.DownMasterLink
{
static async Task Main(string[] args)
{
JT809.Protocol.JT809GlobalConfig.Instance
.SetHeaderOptions(new JT809.Protocol.JT809Configs.JT809HeaderOptions
{
MsgGNSSCENTERID= 20141013,
Version=new JT809.Protocol.JT809Header_Version (2,0,0),
EncryptKey=9595
});
var serverHostBuilder = new HostBuilder()
.UseEnvironment(args[0].Split('=')[1])
.ConfigureAppConfiguration((hostingContext, config) =>
@@ -36,7 +44,7 @@ namespace JT809Netty.DownMasterLink
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.Configure<JT809NettyOptions>(hostContext.Configuration.GetSection("JT809NettyOptions"));
services.AddSingleton<JT809BusinessTypeHandler, JT809BusinessTypeHandler>();
services.AddSingleton<JT809DownMasterLinkBusinessTypeHandler, JT809DownMasterLinkBusinessTypeHandler>();
services.AddScoped<JT809DownMasterLinkConnectionHandler, JT809DownMasterLinkConnectionHandler>();
services.AddScoped<JT809DownMasterLinkServiceHandler, JT809DownMasterLinkServiceHandler>();
services.AddScoped<JT809DecodeHandler, JT809DecodeHandler>();


+ 1
- 1
src/JT809Netty.sln 查看文件

@@ -5,7 +5,7 @@ VisualStudioVersion = 15.0.28010.2016
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT809Netty.Core", "JT809Netty.Core\JT809Netty.Core.csproj", "{2054D7E6-53B6-412F-BE9D-C6DABD80A111}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT809Netty.DownMasterLink", "JT809Netty.DownMasterLink\JT809Netty.DownMasterLink.csproj", "{3BF1D40D-A17D-4FBC-B3FF-B6DF8B3F13ED}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT809Netty.DownMasterLink", "JT809Netty.DownMasterLink\JT809Netty.DownMasterLink.csproj", "{3BF1D40D-A17D-4FBC-B3FF-B6DF8B3F13ED}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution


正在加载...
取消
保存