mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-21 03:01:28 +08:00
!61 fix: ddp协议
* Merge branch 'v10' of gitee.com:ThingsGateway/ThingsGateway into v10-dev * 修改通道显示字符串 * fix: ddp协议 * 更新依赖 * 10.4.6 * 通道 本地主机地址和远程主机地址 文本修改 * 注册页面位置更改 * 修复导出设备失败,注册页面位置更改 * 更新依赖 * 格式化 * 更新依赖 * 删除会话管理字段 * logo size * 更新依赖
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
@namespace ThingsGateway.Debug
|
||||
@namespace ThingsGateway.Debug
|
||||
@using Microsoft.AspNetCore.Components.Web;
|
||||
@using System.IO.Ports;
|
||||
@using ThingsGateway.Foundation
|
||||
@@ -19,8 +19,6 @@
|
||||
<div class="col-12 col-sm-6 col-md-4">
|
||||
<Select SkipValidate="true" @bind-Value="@value.ChannelType" OnSelectedItemChanged=@((a)=>
|
||||
{
|
||||
value.BindUrl = string.Empty;
|
||||
value.RemoteUrl = string.Empty;
|
||||
return InvokeAsync(StateHasChanged);
|
||||
}) />
|
||||
</div>
|
||||
|
@@ -11,6 +11,8 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO.Ports;
|
||||
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
|
||||
namespace ThingsGateway.Foundation
|
||||
{
|
||||
public abstract class ChannelOptionsBase : IValidatableObject
|
||||
@@ -142,7 +144,7 @@ namespace ThingsGateway.Foundation
|
||||
case ChannelTypeEnum.SerialPort:
|
||||
return PortName;
|
||||
case ChannelTypeEnum.UdpSession:
|
||||
return RemoteUrl;
|
||||
return BindUrl.IsNullOrEmpty() ? RemoteUrl : BindUrl;
|
||||
case ChannelTypeEnum.Other:
|
||||
return string.Empty;
|
||||
}
|
||||
|
@@ -8,12 +8,14 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public class DDPMessage : MessageBase, IResultMessage
|
||||
public abstract class DDPMessage : MessageBase, IResultMessage
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override int HeaderLength => 4;
|
||||
@@ -21,7 +23,7 @@ public class DDPMessage : MessageBase, IResultMessage
|
||||
public string Id;
|
||||
public override FilterResult CheckBody<TByteBlock>(ref TByteBlock byteBlock)
|
||||
{
|
||||
Id = byteBlock.ToString(byteBlock.Position, 11);
|
||||
Id = byteBlock.ToString(byteBlock.Position, 11).Replace("\0", "");
|
||||
OperCode = 0;
|
||||
Content = byteBlock.Span.Slice(byteBlock.Position + 11, BodyLength - 12).ToArray();
|
||||
return FilterResult.Success;
|
||||
@@ -44,4 +46,23 @@ public class DDPMessage : MessageBase, IResultMessage
|
||||
|
||||
}
|
||||
|
||||
public abstract int GetBodyLength<TByteBlock>(ref TByteBlock byteBlock) where TByteBlock : IByteBlock;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class DDPTcpMessage : DDPMessage
|
||||
{
|
||||
public override int GetBodyLength<TByteBlock>(ref TByteBlock byteBlock)
|
||||
{
|
||||
return byteBlock.ReadUInt16(EndianType.Big) - 4;
|
||||
}
|
||||
}
|
||||
|
||||
public class DDPUdpMessage : DDPMessage
|
||||
{
|
||||
public override int GetBodyLength<TByteBlock>(ref TByteBlock byteBlock)
|
||||
{
|
||||
return byteBlock.Length - 4;
|
||||
}
|
||||
}
|
@@ -23,9 +23,10 @@ public class DDPSend : ISendMessage
|
||||
ReadOnlyMemory<byte> ReadOnlyMemory;
|
||||
string Id;
|
||||
byte Command;
|
||||
public DDPSend(ReadOnlyMemory<byte> readOnlyMemory, string id, byte command = 0x89)
|
||||
bool Tcp;
|
||||
public DDPSend(ReadOnlyMemory<byte> readOnlyMemory, string id,bool tcp, byte command = 0x89)
|
||||
{
|
||||
|
||||
Tcp = tcp;
|
||||
ReadOnlyMemory = readOnlyMemory;
|
||||
Id = id;
|
||||
Command = command;
|
||||
@@ -34,11 +35,37 @@ public class DDPSend : ISendMessage
|
||||
{
|
||||
byteBlock.WriteByte(0x7b);
|
||||
byteBlock.WriteByte(Command);
|
||||
byteBlock.WriteUInt16(0x00);//len
|
||||
byteBlock.WriteNormalString(Id.Remove(0, 3), Encoding.UTF8);
|
||||
byteBlock.Write(ReadOnlyMemory.Span);
|
||||
byteBlock.WriteByte(0x7b);
|
||||
byteBlock.Position = 2;
|
||||
byteBlock.WriteUInt16((ushort)byteBlock.Length);//len
|
||||
byteBlock.WriteUInt16(0x10,EndianType.Big);//len
|
||||
byteBlock.Write(PadTo11Byte(Id.Remove(0, 3)));
|
||||
if(Tcp)
|
||||
{
|
||||
byteBlock.Write(ReadOnlyMemory.Span);
|
||||
byteBlock.WriteByte(0x7b);
|
||||
byteBlock.Position = 2;
|
||||
byteBlock.WriteUInt16((ushort)byteBlock.Length, EndianType.Big);//len
|
||||
}
|
||||
else
|
||||
{
|
||||
byteBlock.WriteByte(0x7b);
|
||||
byteBlock.Write(ReadOnlyMemory.Span);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] PadTo11Byte(string id)
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(id);
|
||||
|
||||
if(bytes.Length<11)
|
||||
{
|
||||
byte[] newBytes = new byte[11];
|
||||
Array.Copy(bytes, newBytes, bytes.Length);
|
||||
for (int i = bytes.Length; i < 11; i++)
|
||||
{
|
||||
newBytes[i] = 0;
|
||||
}
|
||||
return newBytes;
|
||||
}
|
||||
return bytes;
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -46,7 +46,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
|
||||
}
|
||||
protected Task DefaultSendAsync(ReadOnlyMemory<byte> memory)
|
||||
{
|
||||
return DDPAdapter.SendInputAsync(new DDPSend(memory, Id));
|
||||
return DDPAdapter.SendInputAsync(new DDPSend(memory, Id,true));
|
||||
}
|
||||
protected Task DDPSendAsync(ReadOnlyMemory<byte> memory)
|
||||
{
|
||||
@@ -64,7 +64,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
|
||||
|
||||
|
||||
|
||||
private DeviceSingleStreamDataHandleAdapter<DDPMessage> DDPAdapter = new();
|
||||
private DeviceSingleStreamDataHandleAdapter<DDPTcpMessage> DDPAdapter = new();
|
||||
private WaitLock _waitLock = new();
|
||||
protected override async ValueTask<bool> OnTcpReceiving(ByteBlock byteBlock)
|
||||
{
|
||||
@@ -101,13 +101,13 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
|
||||
await ResetIdAsync(id).ConfigureAwait(false);
|
||||
|
||||
//发送成功
|
||||
await DDPAdapter.SendInputAsync(new DDPSend(ReadOnlyMemory<byte>.Empty, id, 0x81)).ConfigureAwait(false);
|
||||
await DDPAdapter.SendInputAsync(new DDPSend(ReadOnlyMemory<byte>.Empty, id, true, 0x81)).ConfigureAwait(false);
|
||||
|
||||
Logger?.Info(DefaultResource.Localizer["DtuConnected", Id]);
|
||||
}
|
||||
else if (message.Type == 0x02)
|
||||
{
|
||||
await DDPAdapter.SendInputAsync(new DDPSend(ReadOnlyMemory<byte>.Empty, Id, 0x82)).ConfigureAwait(false);
|
||||
await DDPAdapter.SendInputAsync(new DDPSend(ReadOnlyMemory<byte>.Empty, Id, true, 0x82)).ConfigureAwait(false);
|
||||
Logger?.Info(DefaultResource.Localizer["DtuDisconnecting", Id]);
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
await this.CloseAsync().ConfigureAwait(false);
|
||||
|
@@ -39,7 +39,11 @@ public class DDPUdpSessionChannel : UdpSessionChannel, IClientChannel, IDtuUdpSe
|
||||
|
||||
// 将当前实例的日志记录器和加载回调设置到适配器中
|
||||
DDPAdapter.Logger = Logger;
|
||||
DDPAdapter.OnLoaded(this);
|
||||
|
||||
if (DDPAdapter.Owner != null)
|
||||
{
|
||||
DDPAdapter.OnLoaded(this);
|
||||
}
|
||||
|
||||
DDPAdapter.SendCallBackAsync = DDPSendAsync;
|
||||
DDPAdapter.ReceivedCallBack = DDPHandleReceivedData;
|
||||
@@ -52,7 +56,7 @@ public class DDPUdpSessionChannel : UdpSessionChannel, IClientChannel, IDtuUdpSe
|
||||
{
|
||||
if (TryGetId(endPoint, out var id))
|
||||
{
|
||||
return DDPAdapter.SendInputAsync(endPoint, new DDPSend(memory, id));
|
||||
return DDPAdapter.SendInputAsync(endPoint, new DDPSend(memory, id, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -77,7 +81,7 @@ public class DDPUdpSessionChannel : UdpSessionChannel, IClientChannel, IDtuUdpSe
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private DeviceUdpDataHandleAdapter<DDPMessage> DDPAdapter = new();
|
||||
private DeviceUdpDataHandleAdapter<DDPUdpMessage> DDPAdapter = new();
|
||||
|
||||
|
||||
public EndPoint DefaultEndpoint => RemoteIPHost?.EndPoint;
|
||||
@@ -145,12 +149,12 @@ public class DDPUdpSessionChannel : UdpSessionChannel, IClientChannel, IDtuUdpSe
|
||||
}
|
||||
|
||||
//发送成功
|
||||
await DDPAdapter.SendInputAsync(endPoint, new DDPSend(ReadOnlyMemory<byte>.Empty, id, 0x81)).ConfigureAwait(false);
|
||||
await DDPAdapter.SendInputAsync(endPoint, new DDPSend(ReadOnlyMemory<byte>.Empty, id, false, 0x81)).ConfigureAwait(false);
|
||||
Logger?.Info(DefaultResource.Localizer["DtuConnected", id]);
|
||||
}
|
||||
else if (message.Type == 0x02)
|
||||
{
|
||||
await DDPAdapter.SendInputAsync(endPoint, new DDPSend(ReadOnlyMemory<byte>.Empty, id, 0x82)).ConfigureAwait(false);
|
||||
await DDPAdapter.SendInputAsync(endPoint, new DDPSend(ReadOnlyMemory<byte>.Empty, id, false, 0x82)).ConfigureAwait(false);
|
||||
Logger?.Info(DefaultResource.Localizer["DtuDisconnecting", id]);
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
IdDict.TryRemove(endPoint, out _);
|
||||
|
@@ -68,7 +68,7 @@ public class DeviceUdpDataHandleAdapter<TRequest> : UdpDataHandlingAdapter where
|
||||
byteBlock.Position = 0;
|
||||
|
||||
if (Logger?.LogLevel <= LogLevel.Trace)
|
||||
Logger?.Trace($"{ToString()}- Receive:{(IsHexLog ? byteBlock.AsSegmentTake().ToHexString() : byteBlock.ToString(byteBlock.Position))}");
|
||||
Logger?.Trace($"{remoteEndPoint}- Receive:{(IsHexLog ? byteBlock.AsSegmentTake().ToHexString() : byteBlock.ToString(byteBlock.Position))}");
|
||||
|
||||
TRequest request = null;
|
||||
if (IsSingleThread)
|
||||
@@ -172,7 +172,7 @@ public class DeviceUdpDataHandleAdapter<TRequest> : UdpDataHandlingAdapter where
|
||||
{
|
||||
sendMessage.Build(ref byteBlock);
|
||||
if (Logger?.LogLevel <= LogLevel.Trace)
|
||||
Logger?.Trace($"{ToString()}- Send:{(IsHexLog ? byteBlock.Span.ToHexString() : (byteBlock.Span.ToString(Encoding.UTF8)))}");
|
||||
Logger?.Trace($"{endPoint}- Send:{(IsHexLog ? byteBlock.Span.ToHexString() : (byteBlock.Span.ToString(Encoding.UTF8)))}");
|
||||
|
||||
if (IsSingleThread)
|
||||
{
|
||||
|
@@ -1,4 +1,4 @@
|
||||
@namespace ThingsGateway.Gateway.Razor
|
||||
@namespace ThingsGateway.Gateway.Razor
|
||||
@using ThingsGateway.Admin.Application
|
||||
@using ThingsGateway.Admin.Razor
|
||||
@using ThingsGateway.Foundation
|
||||
@@ -76,8 +76,6 @@
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select SkipValidate="true" @bind-Value="@value.ChannelType" OnSelectedItemChanged=@((a)=>
|
||||
{
|
||||
value.BindUrl = string.Empty;
|
||||
value.RemoteUrl = string.Empty;
|
||||
return InvokeAsync(StateHasChanged);
|
||||
}) />
|
||||
</div>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
@namespace ThingsGateway.Gateway.Razor
|
||||
@namespace ThingsGateway.Gateway.Razor
|
||||
@using ThingsGateway.Admin.Application
|
||||
@using ThingsGateway.Admin.Razor
|
||||
@using ThingsGateway.Debug
|
||||
@@ -65,8 +65,6 @@
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<Select SkipValidate="true" @bind-Value="@value.ChannelType" OnSelectedItemChanged=@((a)=>
|
||||
{
|
||||
value.BindUrl = string.Empty;
|
||||
value.RemoteUrl = string.Empty;
|
||||
return InvokeAsync(StateHasChanged);
|
||||
}) />
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user