mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-20 18:51:28 +08:00
release:6.0.3.55
This commit is contained in:
@@ -13,8 +13,8 @@
|
||||
<PackageReference Include="HslCommunication" Version="12.0.2" />
|
||||
<PackageReference Include="NModbus" Version="3.0.81" />
|
||||
<PackageReference Include="S7netplus" Version="0.20.0" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.Modbus" Version="6.0.3.51" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.SiemensS7" Version="6.0.3.51" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.Modbus" Version="6.0.3.55" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.SiemensS7" Version="6.0.3.55" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -23,7 +23,7 @@ namespace BenchmarkConsoleApp
|
||||
{
|
||||
private static int ClientCount = 1;
|
||||
public static int TaskNumberOfItems = 10;
|
||||
public static int NumberOfItems = 100;
|
||||
public static int NumberOfItems = 10;
|
||||
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
|
@@ -345,13 +345,13 @@ public abstract class ProtocolBase : DisposableObject, IProtocol
|
||||
/// </summary>
|
||||
protected virtual async ValueTask<MessageBase> GetResponsedDataAsync(ISendMessage command, IClientChannel clientChannel, WaitDataAsync<MessageBase> waitData = default, int timeout = 3000, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (IsSingleThread)
|
||||
await clientChannel.WaitLock.WaitOneAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (waitData == default)
|
||||
{
|
||||
waitData = clientChannel.WaitHandlePool.GetWaitDataAsync(out var sign);
|
||||
command.Sign = sign;
|
||||
}
|
||||
if (IsSingleThread)
|
||||
await clientChannel.WaitLock.WaitOneAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
SetDataAdapter();
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>6.0.3.52</Version>
|
||||
<Version>6.0.3.55</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -39,7 +39,7 @@ internal class ModbusMasterTest
|
||||
ModbusMaster modbusMaster = new(clientChannel)
|
||||
{
|
||||
//modbus协议格式
|
||||
ModbusType = Modbus.ModbusTypeEnum.ModbusRtu,
|
||||
ModbusType = Modbus.ModbusTypeEnum.ModbusTcp,
|
||||
//ModbusType = Modbus.ModbusTypeEnum.ModbusTcp,
|
||||
|
||||
//默认站号
|
||||
@@ -60,7 +60,18 @@ internal class ModbusMasterTest
|
||||
Console.WriteLine(modbusMaster.GetAddressDescription());
|
||||
|
||||
//读写方法都带取消令牌
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
var result = await modbusMaster.ReadAsync("400001", 100);
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await Task.Delay(70000);
|
||||
//读取并解析寄存器数据
|
||||
var data = await modbusMaster.ReadInt16Async("40001", 1, cancellationToken: CancellationToken.None);
|
||||
var data1 = await modbusMaster.ReadSingleAsync("40001");
|
||||
|
@@ -8,9 +8,9 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HslCommunication" Version="12.0.2" />
|
||||
<PackageReference Include="NModbus" Version="3.0.81" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.SiemensS7" Version="6.0.3.47" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.SiemensS7" Version="6.0.3.55" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.Variable" Version="8.6.0" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.Modbus" Version="6.0.3.47" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.Modbus" Version="6.0.3.55" />
|
||||
<PackageReference Include="TouchSocket.Modbus" Version="2.1.0-alpha.22" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@@ -160,7 +160,21 @@ channelResult.Content, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async ValueTask<OperResult> WriteAsync(string address, string value, IThingsGatewayBitConverter bitConverter = null, CancellationToken cancellationToken = default)
|
||||
public override async ValueTask<OperResult<String[]>> ReadStringAsync(string address, int length, IThingsGatewayBitConverter bitConverter = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
bitConverter ??= ThingsGatewayBitConverter.GetTransByAddress(ref address);
|
||||
|
||||
var result = await ReadAsync(address, GetLength(address, 0, 1), cancellationToken).ConfigureAwait(false);
|
||||
return result.OperResultFrom<String[], byte[]>(() =>
|
||||
{
|
||||
var data = bitConverter.ToString(result.Content, 0, result.Content.Length);
|
||||
return [data];
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async ValueTask<OperResult> WriteAsync(string address, string[] value, IThingsGatewayBitConverter bitConverter = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -172,7 +186,7 @@ channelResult.Content, cancellationToken).ConfigureAwait(false);
|
||||
OperCode = OperCode.PadLeft(8, '0');
|
||||
|
||||
var codes = DataTransUtil.SpliceArray(Password.HexStringToBytes(), OperCode.HexStringToBytes());
|
||||
string[] strArray = value.SplitStringBySemicolon();
|
||||
string[] strArray = value;
|
||||
var dAddress = Dlt645_2007Address.ParseFrom(address, Station, DtuId);
|
||||
return await Dlt645RequestAsync(dAddress, ControlCode.Write, FEHead, codes, strArray, cancellationToken: cancellationToken);
|
||||
}
|
||||
@@ -182,6 +196,20 @@ channelResult.Content, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async ValueTask<OperResult> WriteAsync(string address, string value, IThingsGatewayBitConverter bitConverter = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] strArray = value.SplitStringBySemicolon();
|
||||
return await WriteAsync(address, value, bitConverter, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
#region
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -46,7 +46,6 @@ public partial class ModbusMaster : ProtocolBase, IDtu
|
||||
{
|
||||
switch (ModbusType)
|
||||
{
|
||||
case ModbusTypeEnum.ModbusTcp: return false;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
@@ -221,7 +220,7 @@ public partial class ModbusMaster : ProtocolBase, IDtu
|
||||
var writeData = ThingsGatewayBitConverter.ToUInt16(readData.Content, 0);
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
writeData=writeData.SetBit(mAddress.BitIndex.Value + i, value[i]);
|
||||
writeData = writeData.SetBit(mAddress.BitIndex.Value + i, value[i]);
|
||||
}
|
||||
mAddress.Data = ThingsGatewayBitConverter.GetBytes(writeData);
|
||||
return await ModbusRequestAsync(mAddress, false, cancellationToken);
|
||||
|
@@ -212,170 +212,165 @@ public class ModbusSlave : ProtocolBase, ITcpService, IDtuClient
|
||||
#region 核心
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Task ChannelReceived(IClientChannel client, ReceivedDataEventArgs e)
|
||||
protected override async Task ChannelReceived(IClientChannel client, ReceivedDataEventArgs e)
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
var requestInfo = e.RequestInfo;
|
||||
bool modbusRtu = false;
|
||||
ModbusRequest modbusRequest = default;
|
||||
ReadOnlyMemory<byte> Bytes = default;
|
||||
//接收外部报文
|
||||
if (requestInfo is ModbusRtuSlaveMessage modbusRtuSlaveMessage)
|
||||
{
|
||||
var requestInfo = e.RequestInfo;
|
||||
bool modbusRtu = false;
|
||||
ModbusRequest modbusRequest = default;
|
||||
ReadOnlyMemory<byte> Bytes = default;
|
||||
//接收外部报文
|
||||
if (requestInfo is ModbusRtuSlaveMessage modbusRtuSlaveMessage)
|
||||
if (!modbusRtuSlaveMessage.IsSuccess)
|
||||
{
|
||||
if (!modbusRtuSlaveMessage.IsSuccess)
|
||||
{
|
||||
return;
|
||||
}
|
||||
modbusRequest = modbusRtuSlaveMessage.Request;
|
||||
Bytes = modbusRtuSlaveMessage.Bytes;
|
||||
modbusRtu = true;
|
||||
return;
|
||||
}
|
||||
else if (requestInfo is ModbusTcpSlaveMessage modbusTcpSlaveMessage)
|
||||
modbusRequest = modbusRtuSlaveMessage.Request;
|
||||
Bytes = modbusRtuSlaveMessage.Bytes;
|
||||
modbusRtu = true;
|
||||
}
|
||||
else if (requestInfo is ModbusTcpSlaveMessage modbusTcpSlaveMessage)
|
||||
{
|
||||
if (!modbusTcpSlaveMessage.IsSuccess)
|
||||
{
|
||||
if (!modbusTcpSlaveMessage.IsSuccess)
|
||||
{
|
||||
return;
|
||||
}
|
||||
modbusRequest = modbusTcpSlaveMessage.Request;
|
||||
Bytes = modbusTcpSlaveMessage.Bytes;
|
||||
modbusRtu = false;
|
||||
return;
|
||||
}
|
||||
modbusRequest = modbusTcpSlaveMessage.Request;
|
||||
Bytes = modbusTcpSlaveMessage.Bytes;
|
||||
modbusRtu = false;
|
||||
}
|
||||
|
||||
if (modbusRequest.FunctionCode <= 4)
|
||||
if (modbusRequest.FunctionCode <= 4)
|
||||
{
|
||||
var data = this.ModbusRequest(modbusRequest, true);
|
||||
if (data.IsSuccess)
|
||||
{
|
||||
var data = this.ModbusRequest(modbusRequest, true);
|
||||
if (data.IsSuccess)
|
||||
ValueByteBlock valueByteBlock = new(1024);
|
||||
try
|
||||
{
|
||||
ValueByteBlock valueByteBlock = new(1024);
|
||||
try
|
||||
if (modbusRtu)
|
||||
{
|
||||
if (modbusRtu)
|
||||
valueByteBlock.Write(Bytes.Slice(0, 2).Span);
|
||||
if (modbusRequest.FunctionCode == 1 || modbusRequest.FunctionCode == 2)
|
||||
{
|
||||
valueByteBlock.Write(Bytes.Slice(0, 2).Span);
|
||||
if (modbusRequest.FunctionCode == 1 || modbusRequest.FunctionCode == 2)
|
||||
{
|
||||
valueByteBlock.WriteByte((byte)modbusRequest.Length);
|
||||
valueByteBlock.Write(data.Content.Span);
|
||||
}
|
||||
else
|
||||
{
|
||||
valueByteBlock.WriteByte((byte)data.Content.Length);
|
||||
valueByteBlock.Write(data.Content.Span);
|
||||
}
|
||||
valueByteBlock.Write(CRC16Utils.Crc16Only(valueByteBlock.Memory.Span));
|
||||
await ReturnData(client, valueByteBlock.Memory, e);
|
||||
valueByteBlock.WriteByte((byte)modbusRequest.Length);
|
||||
valueByteBlock.Write(data.Content.Span);
|
||||
}
|
||||
else
|
||||
{
|
||||
valueByteBlock.Write(Bytes.Slice(0, 8).Span);
|
||||
if (modbusRequest.FunctionCode == 1 || modbusRequest.FunctionCode == 2)
|
||||
{
|
||||
valueByteBlock.WriteByte((byte)modbusRequest.Length);
|
||||
valueByteBlock.Write(data.Content.Span);
|
||||
}
|
||||
else
|
||||
{
|
||||
valueByteBlock.WriteByte((byte)data.Content.Length);
|
||||
valueByteBlock.Write(data.Content.Span);
|
||||
}
|
||||
valueByteBlock[5] = (byte)(valueByteBlock.Length - 6);
|
||||
await ReturnData(client, valueByteBlock.Memory, e);
|
||||
valueByteBlock.WriteByte((byte)data.Content.Length);
|
||||
valueByteBlock.Write(data.Content.Span);
|
||||
}
|
||||
valueByteBlock.Write(CRC16Utils.Crc16Only(valueByteBlock.Memory.Span));
|
||||
await ReturnData(client, valueByteBlock.Memory, e);
|
||||
}
|
||||
finally
|
||||
else
|
||||
{
|
||||
valueByteBlock.SafeDispose();
|
||||
valueByteBlock.Write(Bytes.Slice(0, 8).Span);
|
||||
if (modbusRequest.FunctionCode == 1 || modbusRequest.FunctionCode == 2)
|
||||
{
|
||||
valueByteBlock.WriteByte((byte)modbusRequest.Length);
|
||||
valueByteBlock.Write(data.Content.Span);
|
||||
}
|
||||
else
|
||||
{
|
||||
valueByteBlock.WriteByte((byte)data.Content.Length);
|
||||
valueByteBlock.Write(data.Content.Span);
|
||||
}
|
||||
valueByteBlock[5] = (byte)(valueByteBlock.Length - 6);
|
||||
await ReturnData(client, valueByteBlock.Memory, e);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
valueByteBlock.SafeDispose();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await WriteError(modbusRtu, client, Bytes, e);//返回错误码
|
||||
}
|
||||
}
|
||||
else//写入
|
||||
{
|
||||
if (modbusRequest.FunctionCode == 5)
|
||||
{
|
||||
//写入继电器
|
||||
if (this.WriteData != null)
|
||||
{
|
||||
var modbusAddress = new ModbusAddress(modbusRequest) { WriteFunctionCode = modbusRequest.FunctionCode, FunctionCode = 1 };
|
||||
// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
if ((await this.WriteData(modbusAddress, this.ThingsGatewayBitConverter, client).ConfigureAwait(false)).IsSuccess)
|
||||
{
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
if (this.IsWriteMemory)
|
||||
{
|
||||
var result = this.ModbusRequest(modbusRequest, false);
|
||||
if (result.IsSuccess)
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
else
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
else
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await WriteError(modbusRtu, client, Bytes, e);//返回错误码
|
||||
}
|
||||
}
|
||||
else//写入
|
||||
{
|
||||
if (modbusRequest.FunctionCode == 5)
|
||||
{
|
||||
//写入继电器
|
||||
if (this.WriteData != null)
|
||||
//写入内存区
|
||||
var result = this.ModbusRequest(modbusRequest, false);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
var modbusAddress = new ModbusAddress(modbusRequest) { WriteFunctionCode = modbusRequest.FunctionCode, FunctionCode = 1 };
|
||||
// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
|
||||
if ((await this.WriteData(modbusAddress, this.ThingsGatewayBitConverter, client).ConfigureAwait(false)).IsSuccess)
|
||||
{
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
if (this.IsWriteMemory)
|
||||
{
|
||||
var result = this.ModbusRequest(modbusRequest, false);
|
||||
if (result.IsSuccess)
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
else
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
else
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
//写入内存区
|
||||
var result = this.ModbusRequest(modbusRequest, false);
|
||||
if (result.IsSuccess)
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//写入寄存器
|
||||
if (this.WriteData != null)
|
||||
{
|
||||
var modbusAddress = new ModbusAddress(modbusRequest) { WriteFunctionCode = modbusRequest.FunctionCode, FunctionCode = 3 };
|
||||
if ((await this.WriteData(modbusAddress, this.ThingsGatewayBitConverter, client).ConfigureAwait(false)).IsSuccess)
|
||||
{
|
||||
if (this.IsWriteMemory)
|
||||
{
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
var result = this.ModbusRequest(modbusRequest, false);
|
||||
if (result.IsSuccess)
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
else
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//写入寄存器
|
||||
if (this.WriteData != null)
|
||||
var result = this.ModbusRequest(modbusRequest, false);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
var modbusAddress = new ModbusAddress(modbusRequest) { WriteFunctionCode = modbusRequest.FunctionCode, FunctionCode = 3 };
|
||||
if ((await this.WriteData(modbusAddress, this.ThingsGatewayBitConverter, client).ConfigureAwait(false)).IsSuccess)
|
||||
{
|
||||
if (this.IsWriteMemory)
|
||||
{
|
||||
var result = this.ModbusRequest(modbusRequest, false);
|
||||
if (result.IsSuccess)
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
else
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
else
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = this.ModbusRequest(modbusRequest, false);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
await WriteSuccess(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
await WriteError(modbusRtu, client, Bytes, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ReturnData(IClientChannel client, ReadOnlyMemory<byte> sendData, ReceivedDataEventArgs e)
|
||||
|
Reference in New Issue
Block a user