Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1cff037c9 | ||
|
|
fc88a2fafa | ||
|
|
45fcceb056 | ||
|
|
7043477038 | ||
|
|
7dd685cf54 | ||
|
|
5f5e4969c0 | ||
|
|
8a53fd19e9 | ||
|
|
baf4714c36 | ||
|
|
7ba9ac7a5b | ||
|
|
85b8f26e8e | ||
|
|
594a0f1410 | ||
|
|
d317d757d7 | ||
|
|
fdf0ba6318 | ||
|
|
15bf7de5fa | ||
|
|
d3402b058e | ||
|
|
e7dfdd4031 | ||
|
|
b2dd7b6364 | ||
|
|
9bd6d9abbf | ||
|
|
cd14428fea | ||
|
|
19d9f03c2b | ||
|
|
0d57e72bbf | ||
|
|
329516a61b | ||
|
|
d566869589 | ||
|
|
9cb8d8e6c7 | ||
|
|
9de3c57e5d |
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.0.24</Version>
|
||||
<Version>3.0.0.27</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<Authors>Diego</Authors>
|
||||
|
||||
@@ -32,7 +32,6 @@ internal class Program
|
||||
AppDomain.CurrentDomain.UnhandledException += (sender, error) =>
|
||||
{
|
||||
};
|
||||
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
@@ -26,10 +26,10 @@
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@port />
|
||||
|
||||
<MButton Class="ma-1" OnClick=@Connect Color="primary">
|
||||
连接
|
||||
启动
|
||||
</MButton>
|
||||
<MButton Class="ma-1" OnClick=@DisConnect Color="red">
|
||||
断开
|
||||
停止
|
||||
</MButton>
|
||||
|
||||
|
||||
|
||||
@@ -207,19 +207,40 @@ public partial class MainLayout
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "GasCustom",
|
||||
"Title": "HZW_QTJC_01",
|
||||
"Children": [
|
||||
{
|
||||
"Href": "/GasCustomSerial",
|
||||
"Title": "GasCustomSerial"
|
||||
"Href": "/HZW_QTJC_01Serial",
|
||||
"Title": "HZW_QTJC_01Serial"
|
||||
},
|
||||
{
|
||||
"Href": "/GasCustomSerialOverTcp",
|
||||
"Title": "GasCustomSerialOverTcp"
|
||||
"Href": "/HZW_QTJC_01SerialOverTcp",
|
||||
"Title": "HZW_QTJC_01SerialOverTcp"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"Title": "LQTCP",
|
||||
"Children": [
|
||||
{
|
||||
"Href": "/LQTCP",
|
||||
"Title": "LQTCP"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "KELID2008",
|
||||
"Children": [
|
||||
{
|
||||
"Href": "/KELID2008",
|
||||
"Title": "KELID2008"
|
||||
},
|
||||
{
|
||||
"Href": "/KELID2008OverTcp",
|
||||
"Title": "KELID2008OverTcp"
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -45,8 +45,18 @@
|
||||
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.HZW_QTJC_01\Page\HZW_QTJC_01SerialOverTcpDebugPage.razor" Link="Pages\HZW_QTJC_01\HZW_QTJC_01SerialOverTcpDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Foundation.Adapter.HZW_QTJC_01\ThingsGateway.Foundation.Adapter.HZW_QTJC_01.csproj" />
|
||||
|
||||
<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.LQTCP\Page\LQTCPDebugPage.razor.cs" Link="Pages\LQTCP\LQTCPDebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.LQTCP\Page\LQTCPDebugPage.razor" Link="Pages\LQTCP\LQTCPDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Foundation.Adapter.LQTCP\ThingsGateway.Foundation.Adapter.LQTCP.csproj" />
|
||||
|
||||
|
||||
<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008DebugPage.razor.cs" Link="Pages\KELID2008\KELID2008DebugPage.razor.cs" />
|
||||
<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008OverTcpDebugPage.razor.cs" Link="Pages\KELID2008\KELID2008OverTcpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008DebugPage.razor" Link="Pages\KELID2008\KELID2008DebugPage.razor" />
|
||||
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008OverTcpDebugPage.razor" Link="Pages\KELID2008\KELID2008OverTcpDebugPage.razor" />
|
||||
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Foundation.Adapter.KELID2008\ThingsGateway.Foundation.Adapter.KELID2008.csproj" />
|
||||
|
||||
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
global using System;
|
||||
|
||||
global using System.Windows.Forms;
|
||||
|
||||
77
framework/Demo/ThingsGateway.Foundation.Demo.Winform/MainFrom.Designer.cs
generated
Normal file
77
framework/Demo/ThingsGateway.Foundation.Demo.Winform/MainFrom.Designer.cs
generated
Normal file
@@ -0,0 +1,77 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
||||
using System.Drawing;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
partial class MainFrom
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainFrom));
|
||||
blazorWebView1 = new Microsoft.AspNetCore.Components.WebView.WindowsForms.BlazorWebView();
|
||||
SuspendLayout();
|
||||
//
|
||||
// blazorWebView1
|
||||
//
|
||||
blazorWebView1.Dock = DockStyle.Fill;
|
||||
blazorWebView1.Location = new Point(0, 0);
|
||||
blazorWebView1.Margin = new Padding(4, 4, 4, 4);
|
||||
blazorWebView1.Name = "blazorWebView1";
|
||||
blazorWebView1.Size = new Size(1029, 529);
|
||||
blazorWebView1.TabIndex = 0;
|
||||
blazorWebView1.Text = "blazorWebView1";
|
||||
//
|
||||
// MainFrom
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(9F, 20F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(1029, 529);
|
||||
Controls.Add(blazorWebView1);
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
Margin = new Padding(4, 4, 4, 4);
|
||||
Name = "MainFrom";
|
||||
Text = "Form1";
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Microsoft.AspNetCore.Components.WebView.WindowsForms.BlazorWebView blazorWebView1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <20>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD>Ϊȫ<CEAA>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ǣ<EFBFBD><C7A3><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4>룩<EFBFBD><EBA3A9><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><DFB1><EFBFBD>Diego<67><6F><EFBFBD><EFBFBD>
|
||||
// Դ<><D4B4><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>Э<EFBFBD><D0AD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD>ֿ<EFBFBD><D6BF>Ŀ<EFBFBD>ԴЭ<D4B4>鼰<EFBFBD><E9BCB0><EFBFBD><EFBFBD>Э<EFBFBD><D0AD>
|
||||
// GiteeԴ<65><D4B4><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<62><D4B4><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<><CAB9><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<51><C8BA>605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using ThingsGateway.Components;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
public partial class MainFrom : Form
|
||||
{
|
||||
public MainFrom()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddWindowsFormsBlazorWebView();
|
||||
services.ThingsGatewayComponentsConfigureServices();
|
||||
|
||||
blazorWebView1.HostPage = "wwwroot/index.html";
|
||||
blazorWebView1.Services = services.BuildServiceProvider();
|
||||
this.Text = "ThingsGateway.Foundation.Demo";
|
||||
blazorWebView1.RootComponents.Add<ThingsGateway.Foundation.Demo.App>("#app");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgvCjzYkwo82JsKPNifCjzYqwo82IcKPNgLCjzYAAAAAAAAA
|
||||
AAAAAAAAAAAAAMKPNgDCjzYBwo82HsKPNknCjzZewo82QcKPNhLCjzYAwo82AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82S8KPNtPCjzbiwo8258KPNuDCjzatwo82EsKP
|
||||
NgAAAAAAAAAAAAAAAADCjzYAwo82BsKPNmvCjzbbwo826MKPNtvCjzbhwo82vcKPNmDCjzYywo82AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMKPNgDCjzYPwo82O8KPNs7Cjzb/wo82iMKP
|
||||
Nh7CjzYCwo82AAAAAAAAAAAAwo82AMKPNgDCjzZnwo8298KPNsLCjzY6wo82GsKPNjTCjzbJwo82/8KP
|
||||
NpTCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMKPNgDCjzYIwo82vsKP
|
||||
Nv/CjzZowo82AAAAAAAAAAAAAAAAAAAAAADCjzYAwo82JMKPNtnCjzbxwo82QcKPNgDCjzYAwo82AMKP
|
||||
NpHCjzb/wo82lsKPNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwo82AMKP
|
||||
NgjCjza9wo82/8KPNmjCjzYAAAAAAAAAAAAAAAAAwo82AMKPNgDCjzZ2wo82/8KPNrnCjzYKwo82AAAA
|
||||
AADCjzYAwo82jcKPNv/CjzaWwo82AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AADCjzYAwo82CMKPNr3Cjzb/wo82aMKPNgAAAAAAAAAAAAAAAADCjzYAwo82CcKPNrrCjzb/wo82fcKP
|
||||
NgDCjzYAAAAAAMKPNgDCjzaLwo82/8KPNpbCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAMKPNgDCjzYIwo82vMKPNv/CjzZpwo82AAAAAAAAAAAAAAAAAMKPNgDCjzYfwo8238KP
|
||||
Nv3CjzZRwo82AMKPNgDCjzYBwo82B8KPNpnCjzb/wo82psKPNgrCjzYAwo82AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgjCjza8wo82/8KPNmnCjzYAAAAAAAAAAAAAAAAAwo82AMKP
|
||||
NjbCjzbxwo829sKPNj7CjzYAwo82AMKPNiPCjzaywo827cKPNv/Cjzbywo82qMKPNhPCjzYAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82CMKPNrvCjzb/wo82acKPNgAAAAAAAAAAAAAA
|
||||
AADCjzYAwo82P8KPNvfCjzbzwo82OcKPNgDCjzYAwo82D8KPNlnCjzZiwo82X8KPNmDCjzZRwo82CcKP
|
||||
NgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMKPNgDCjzYHwo82usKPNv/CjzZpwo82AAAA
|
||||
AAAAAAAAAAAAAMKPNgDCjzY+wo829sKPNvTCjzY8wo82AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgfCjza6wo82/8KP
|
||||
NmnCjzYAAAAAAAAAAAAAAAAAwo82AMKPNirCjzbpwo82+MKPNkDCjzYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82B8KP
|
||||
NrnCjzb/wo82acKPNgAAAAAAAAAAAAAAAADCjzYAwo82FcKPNtLCjzb/wo82VsKPNgAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgLCjzYTwo82BMKP
|
||||
NgDCjzYHwo82t8KPNv/CjzZpwo82AMKPNgDCjzYMwo82E8KPNgDCjzYCwo82n8KPNv/CjzaEwo82AMKP
|
||||
NgAAAAAAwo82AMKPNgDCjzZPwo82XcKPNgLCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82F8KP
|
||||
NrTCjzY6wo82AMKPNgbCjza0wo82/8KPNmnCjzYAwo82AMKPNnPCjzaawo82A8KPNgDCjzZOwo82+MKP
|
||||
NsbCjzYRwo82AAAAAADCjzYAwo82DcKPNsLCjzagwo82AMKPNgAAAAAAAAAAAAAAAAAAAAAAAAAAAMKP
|
||||
NgDCjzYPwo82ysKPNpPCjzYBwo82BcKPNrHCjzb/wo82acKPNgDCjzYUwo82zMKPNpPCjzYAwo82AMKP
|
||||
NgrCjzanwo82/MKPNmnCjzYAwo82AMKPNgDCjzZRwo8298KPNnbCjzYAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAwo82AMKPNgDCjzaawo827cKPNmHCjzYswo82vMKPNv/CjzaEwo82K8KPNoDCjzb5wo82ZMKP
|
||||
NgAAAAAAwo82AMKPNi7CjzbWwo825sKPNlnCjzYdwo82SMKPNtTCjzb9wo82UsKPNgAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNmHCjzb3wo828cKPNt/Cjzbuwo8298KPNurCjzbjwo829MKP
|
||||
NurCjzY6wo82AAAAAADCjzYAwo82AMKPNjfCjza8wo826cKPNtvCjzbewo82ycKPNs7CjzYvwo82AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82EsKPNj3CjzZAwo82QcKPNkDCjzY/wo82QMKP
|
||||
NkDCjzY/wo82OMKPNgrCjzYAAAAAAAAAAADCjzYAwo82AMKPNg/CjzY5wo82SsKPNjDCjzYOwo82G8KP
|
||||
NgXCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////wH4H/8B8Af/AfAH/4f
|
||||
hx/+H4cf/h8PH/4fDAf+HwwH/h8MB/4fD//+Hw///h8P/+IZD4/iGIcP4BGHH+ABwB/wAeAf8AHwH///
|
||||
//////////////////////////////////8=
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo.Winform
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
Application.Run(new MainFrom());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||
<TargetFrameworks>net7.0-windows</TargetFrameworks>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="favicon.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="favicon.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.WindowsForms" Version="7.0.86" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ThingsGateway.Foundation.Demo.Rcl\ThingsGateway.Foundation.Demo.Rcl.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
</Project>
|
||||
BIN
framework/Demo/ThingsGateway.Foundation.Demo.Winform/favicon.ico
Normal file
BIN
framework/Demo/ThingsGateway.Foundation.Demo.Winform/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.0.24</Version>
|
||||
<Version>3.0.0.27</Version>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks>
|
||||
|
||||
@@ -35,12 +35,7 @@ public class DataInfo
|
||||
}
|
||||
internal static class DLT645Helper
|
||||
{
|
||||
internal static byte[] BytesAdd(this byte[] bytes, int value)
|
||||
{
|
||||
for (int index = 0; index < bytes.Length; ++index)
|
||||
bytes[index] = (byte)(bytes[index] + value);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
internal static string Get2007ErrorMessage(byte buffer)
|
||||
{
|
||||
|
||||
@@ -516,9 +516,9 @@ public class OPCUAClient : IDisposable
|
||||
/// <summary>
|
||||
/// 连接到服务器
|
||||
/// </summary>
|
||||
public async Task ConnectAsync()
|
||||
public async Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await ConnectAsync(OPCNode.OPCUrl);
|
||||
await ConnectAsync(OPCNode.OPCUrl, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -538,7 +538,7 @@ public class OPCUAClient : IDisposable
|
||||
/// Creates a new session.
|
||||
/// </summary>
|
||||
/// <returns>The new session object.</returns>
|
||||
private async Task<ISession> ConnectAsync(string serverUrl)
|
||||
private async Task<ISession> ConnectAsync(string serverUrl, CancellationToken cancellationToken)
|
||||
{
|
||||
PrivateDisconnect();
|
||||
|
||||
@@ -547,6 +547,7 @@ public class OPCUAClient : IDisposable
|
||||
throw new ArgumentNullException("未初始化配置");
|
||||
}
|
||||
var useSecurity = OPCNode?.IsUseSecurity ?? true;
|
||||
|
||||
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(m_configuration, serverUrl, useSecurity, 10000);
|
||||
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
|
||||
ConfiguredEndpoint endpoint = new(null, endpointDescription, endpointConfiguration);
|
||||
@@ -569,7 +570,8 @@ public class OPCUAClient : IDisposable
|
||||
(string.IsNullOrEmpty(OPCUAName)) ? m_configuration.ApplicationName : OPCUAName,
|
||||
60000,
|
||||
userIdentity,
|
||||
Array.Empty<string>());
|
||||
Array.Empty<string>(), cancellationToken
|
||||
).ConfigureAwait(false);
|
||||
typeSystem = new ComplexTypeSystem(m_session);
|
||||
|
||||
m_session.KeepAliveInterval = OPCNode.KeepAliveInterval == 0 ? 60000 : OPCNode.KeepAliveInterval;
|
||||
@@ -739,7 +741,7 @@ public class OPCUAClient : IDisposable
|
||||
NodeId nodeToRead = new(nodeIdStr);
|
||||
var node = (VariableNode)await m_session.ReadNodeAsync(nodeToRead, NodeClass.Variable, false, cancellationToken);
|
||||
if (OPCNode.LoadType)
|
||||
await typeSystem.LoadType(node.DataType);
|
||||
await typeSystem.LoadType(node.DataType).ConfigureAwait(false);
|
||||
_variableDicts.AddOrUpdate(nodeIdStr, node);
|
||||
return node;
|
||||
}
|
||||
@@ -779,7 +781,7 @@ public class OPCUAClient : IDisposable
|
||||
if (StatusCode.IsGood(nodes.Item2[i].StatusCode))
|
||||
{
|
||||
var node = ((VariableNode)nodes.Item1[i]);
|
||||
await typeSystem.LoadType(node.DataType);
|
||||
await typeSystem.LoadType(node.DataType).ConfigureAwait(false);
|
||||
_variableDicts.AddOrUpdate(nodeIdStrs[i], node);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.372.56" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.372.56" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.372.76" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.372.76" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -36,11 +36,42 @@ internal partial class SiemensHelper
|
||||
// return OperResult.CreateSuccessResult<byte[]>(numArray);
|
||||
//}
|
||||
|
||||
internal static OperResult<byte[]> AnalysisReadByte(byte[] sends, byte[] content)
|
||||
internal static OperResult<byte[], FilterResult> AnalysisReadByte(byte[] sends, byte[] content)
|
||||
{
|
||||
int length = 0;
|
||||
int itemLen = (sends.Length - 19) / 12;
|
||||
|
||||
//添加错误代码校验
|
||||
if (content[17] + content[18] > 0)
|
||||
{
|
||||
return new($"PLC返回错误,错误类型{content[17].ToString("X2")}错误代码:{content[18].ToString("X2")}")
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
if (content.Length < 21)
|
||||
{
|
||||
return new($"长度不足")
|
||||
{
|
||||
Content2 = FilterResult.Cache
|
||||
};
|
||||
}
|
||||
if (content.Length < 25 + content[20])
|
||||
{
|
||||
return new($"长度不足")
|
||||
{
|
||||
Content2 = FilterResult.Cache
|
||||
};
|
||||
}
|
||||
//添加返回代码校验
|
||||
if (content[21] != 0xff)
|
||||
{
|
||||
return new($"PLC返回错误,返回代码{content[21].ToString("X2")}")
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
|
||||
for (int index = 0; index < itemLen; index++)
|
||||
{
|
||||
if (sends[22 + (index * 12)] >= (byte)S7WordLength.Word)
|
||||
@@ -53,9 +84,9 @@ internal partial class SiemensHelper
|
||||
}
|
||||
}
|
||||
|
||||
if (content.Length < 21 || content[20] != itemLen)
|
||||
if (content[20] != itemLen)
|
||||
{
|
||||
return new OperResult<byte[]>("数据块长度校验失败");
|
||||
return new("数据块长度校验失败");
|
||||
}
|
||||
|
||||
byte[] dataArray = new byte[length];
|
||||
@@ -105,29 +136,39 @@ internal partial class SiemensHelper
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>((int)content[index2] + GetCpuError(content[index2]));
|
||||
return new((int)content[index2] + GetCpuError(content[index2]))
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return OperResult.CreateSuccessResult(dataArray);
|
||||
return OperResult.CreateSuccessResult(dataArray, FilterResult.Success);
|
||||
|
||||
}
|
||||
|
||||
internal static OperResult<byte[]> AnalysisWrite(byte[] content)
|
||||
internal static OperResult<byte[], FilterResult> AnalysisWrite(byte[] content)
|
||||
{
|
||||
if (content.Length < 22)
|
||||
{
|
||||
return new OperResult<byte[]>() { Message = "未知错误" };
|
||||
return new()
|
||||
{
|
||||
Message = "长度不足",
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
|
||||
byte err = content[21];
|
||||
if (err != byte.MaxValue)
|
||||
{
|
||||
return new OperResult<byte[]>((int)content[21] + GetCpuError(content[21]));
|
||||
return new($"错误代码:{(int)content[21]}描述:{GetCpuError(content[21])}")
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateSuccessResult(content);
|
||||
return OperResult.CreateSuccessResult(content, FilterResult.Success);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ public class SiemensS7PLCDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapte
|
||||
/// <inheritdoc/>
|
||||
protected override FilterResult UnpackResponse(SiemensMessage request, byte[] send, byte[] body, byte[] response)
|
||||
{
|
||||
var result = new OperResult<byte[]>();
|
||||
var result = new OperResult<byte[], FilterResult>();
|
||||
if (response[2] * 256 + response[3] == 7)
|
||||
{
|
||||
result = new OperResult<byte[]>() { Content = response };
|
||||
result = new() { Content = response, Content2 = FilterResult.Success };
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -56,6 +56,6 @@ public class SiemensS7PLCDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapte
|
||||
request.ErrorCode = result.ErrorCode;
|
||||
request.Message = result.Message;
|
||||
request.Content = result.Content;
|
||||
return FilterResult.Success;
|
||||
return result.Content2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
0x00 Reserved 未定义,预留
|
||||
|
||||
0x01 Hardware error 硬件错误
|
||||
|
||||
0x03 Accessing the object not allowed 对象不允许访问
|
||||
|
||||
0x05 Invalid address 无效地址,所需的地址超出此PLC的极限
|
||||
|
||||
0x06 Data type not supported 数据类型不支持
|
||||
|
||||
0x07 Data type inconsistent 日期类型不一致
|
||||
|
||||
0x0a Object does not exist 对象不存在
|
||||
|
||||
0xff Success 成功
|
||||
@@ -0,0 +1,825 @@
|
||||
附录一:错误码具体含义
|
||||
|
||||
0x0000
|
||||
|
||||
没有错误
|
||||
|
||||
0x0110
|
||||
|
||||
块号无效
|
||||
|
||||
0x0111
|
||||
|
||||
请求长度无效
|
||||
|
||||
0x0112
|
||||
|
||||
参数无效
|
||||
|
||||
0x0113
|
||||
|
||||
块类型无效
|
||||
|
||||
0x0114
|
||||
|
||||
找不到块
|
||||
|
||||
0x0115
|
||||
|
||||
块已存在
|
||||
|
||||
0x0116
|
||||
|
||||
块被写保护
|
||||
|
||||
0x0117
|
||||
|
||||
块/操作系统更新太大
|
||||
|
||||
0x0118
|
||||
|
||||
块号无效
|
||||
|
||||
0x0119
|
||||
|
||||
输入的密码不正确
|
||||
|
||||
0x011A
|
||||
|
||||
PG资源错误
|
||||
|
||||
0x011B
|
||||
|
||||
PLC资源错误
|
||||
|
||||
0x011C
|
||||
|
||||
协议错误
|
||||
|
||||
0x011D
|
||||
|
||||
块太多(与模块相关的限制)
|
||||
|
||||
0x011E
|
||||
|
||||
不再与数据库建立连接,或者S7DOS句柄无效
|
||||
|
||||
0x011F
|
||||
|
||||
结果缓冲区太小
|
||||
|
||||
0x0120
|
||||
|
||||
块结束列表
|
||||
|
||||
0x0140
|
||||
|
||||
可用内存不足
|
||||
|
||||
0x0141
|
||||
|
||||
由于缺少资源,无法处理作业
|
||||
|
||||
0x8001
|
||||
|
||||
当块处于当前状态时,无法执行请求的服务
|
||||
|
||||
0x8003
|
||||
|
||||
S7协议错误:传输块时发生错误
|
||||
|
||||
0x8100
|
||||
|
||||
应用程序,一般错误:远程模块未知的服务
|
||||
|
||||
0x8104
|
||||
|
||||
未在模块上实现此服务或报告了帧错误
|
||||
|
||||
0x8204
|
||||
|
||||
对象的类型规范不一致
|
||||
|
||||
0x8205
|
||||
|
||||
复制的块已存在且未链接
|
||||
|
||||
0x8301
|
||||
|
||||
模块上的内存空间或工作内存不足,或者指定的存储介质不可访问
|
||||
|
||||
0x8302
|
||||
|
||||
可用资源太少或处理器资源不可用
|
||||
|
||||
0x8304
|
||||
|
||||
无法进一步并行上传。存在资源瓶颈
|
||||
|
||||
0x8305
|
||||
|
||||
功能不可用
|
||||
|
||||
0x8306
|
||||
|
||||
工作内存不足(用于复制,链接,加载AWP)
|
||||
|
||||
0x8307
|
||||
|
||||
保持性工作记忆不够(用于复制,链接,加载AWP)
|
||||
|
||||
0x8401
|
||||
|
||||
S7协议错误:无效的服务序列(例如,加载或上载块)
|
||||
|
||||
0x8402
|
||||
|
||||
由于寻址对象的状态,服务无法执行
|
||||
|
||||
0x8404
|
||||
|
||||
S7协议:无法执行该功能
|
||||
|
||||
0x8405
|
||||
|
||||
远程块处于DISABLE状态(CFB)。该功能无法执行
|
||||
|
||||
0x8500
|
||||
|
||||
S7协议错误:帧错误
|
||||
|
||||
0x8503
|
||||
|
||||
来自模块的警报:服务过早取消
|
||||
|
||||
0x8701
|
||||
|
||||
寻址通信伙伴上的对象时出错(例如,区域长度错误)
|
||||
|
||||
0x8702
|
||||
|
||||
模块不支持所请求的服务
|
||||
|
||||
0x8703
|
||||
|
||||
拒绝访问对象
|
||||
|
||||
0x8704
|
||||
|
||||
访问错误:对象已损坏
|
||||
|
||||
0xD001
|
||||
|
||||
协议错误:非法的作业号
|
||||
|
||||
0xD002
|
||||
|
||||
参数错误:非法的作业变体
|
||||
|
||||
0xD003
|
||||
|
||||
参数错误:模块不支持调试功能
|
||||
|
||||
0xD004
|
||||
|
||||
参数错误:作业状态非法
|
||||
|
||||
0xD005
|
||||
|
||||
参数错误:作业终止非法
|
||||
|
||||
0xD006
|
||||
|
||||
参数错误:非法链路断开ID
|
||||
|
||||
0xD007
|
||||
|
||||
参数错误:缓冲区元素数量非法
|
||||
|
||||
0xD008
|
||||
|
||||
参数错误:扫描速率非法
|
||||
|
||||
0xD009
|
||||
|
||||
参数错误:执行次数非法
|
||||
|
||||
0xD00A
|
||||
|
||||
参数错误:非法触发事件
|
||||
|
||||
0xD00B
|
||||
|
||||
参数错误:非法触发条件
|
||||
|
||||
0xD011
|
||||
|
||||
调用环境路径中的参数错误:块不存在
|
||||
|
||||
0xD012
|
||||
|
||||
参数错误:块中的地址错误
|
||||
|
||||
0xD014
|
||||
|
||||
参数错误:正在删除/覆盖块
|
||||
|
||||
0xD015
|
||||
|
||||
参数错误:标签地址非法
|
||||
|
||||
0xD016
|
||||
|
||||
参数错误:由于用户程序错误,无法测试作业
|
||||
|
||||
0xD017
|
||||
|
||||
参数错误:非法触发号
|
||||
|
||||
0xD025
|
||||
|
||||
参数错误:路径无效
|
||||
|
||||
0xD026
|
||||
|
||||
参数错误:非法访问类型
|
||||
|
||||
0xD027
|
||||
|
||||
参数错误:不允许此数据块数
|
||||
|
||||
0xD031
|
||||
|
||||
内部协议错误
|
||||
|
||||
0xD032
|
||||
|
||||
参数错误:结果缓冲区长度错误
|
||||
|
||||
0xD033
|
||||
|
||||
协议错误:作业长度错误
|
||||
|
||||
0xD03F
|
||||
|
||||
编码错误:参数部分出错(例如,保留字节不等于0)
|
||||
|
||||
0xD041
|
||||
|
||||
数据错误:非法状态列表ID
|
||||
|
||||
0xD042
|
||||
|
||||
数据错误:标签地址非法
|
||||
|
||||
0xD043
|
||||
|
||||
数据错误:找不到引用的作业,检查作业数据
|
||||
|
||||
0xD044
|
||||
|
||||
数据错误:标签值非法,检查作业数据
|
||||
|
||||
0xD045
|
||||
|
||||
数据错误:HOLD中不允许退出ODIS控制
|
||||
|
||||
0xD046
|
||||
|
||||
数据错误:运行时测量期间非法测量阶段
|
||||
|
||||
0xD047
|
||||
|
||||
数据错误:“读取作业列表”中的非法层次结构
|
||||
|
||||
0xD048
|
||||
|
||||
数据错误:“删除作业”中的非法删除ID
|
||||
|
||||
0xD049
|
||||
|
||||
“替换作业”中的替换ID无效
|
||||
|
||||
0xD04A
|
||||
|
||||
执行'程序状态'时出错
|
||||
|
||||
0xD05F
|
||||
|
||||
编码错误:数据部分出错(例如,保留字节不等于0,...)
|
||||
|
||||
0xD061
|
||||
|
||||
资源错误:没有作业的内存空间
|
||||
|
||||
0xD062
|
||||
|
||||
资源错误:作业列表已满
|
||||
|
||||
0xD063
|
||||
|
||||
资源错误:触发事件占用
|
||||
|
||||
0xD064
|
||||
|
||||
资源错误:没有足够的内存空间用于一个结果缓冲区元素
|
||||
|
||||
0xD065
|
||||
|
||||
资源错误:没有足够的内存空间用于多个结果缓冲区元素
|
||||
|
||||
0xD066
|
||||
|
||||
资源错误:可用于运行时测量的计时器被另一个作业占用
|
||||
|
||||
0xD067
|
||||
|
||||
资源错误:“修改标记”作业过多(特别是多处理器操作)
|
||||
|
||||
0xD081
|
||||
|
||||
当前模式下不允许使用的功能
|
||||
|
||||
0xD082
|
||||
|
||||
模式错误:无法退出HOLD模式
|
||||
|
||||
0xD0A1
|
||||
|
||||
当前保护级别不允许使用的功能
|
||||
|
||||
0xD0A2
|
||||
|
||||
目前无法运行,因为正在运行的函数会修改内存
|
||||
|
||||
0xD0A3
|
||||
|
||||
I / O上活动的“修改标记”作业太多(特别是多处理器操作)
|
||||
|
||||
0xD0A4
|
||||
|
||||
'强制'已经建立
|
||||
|
||||
0xD0A5
|
||||
|
||||
找不到引用的作业
|
||||
|
||||
0xD0A6
|
||||
|
||||
无法禁用/启用作业
|
||||
|
||||
0xD0A7
|
||||
|
||||
无法删除作业,例如因为当前正在读取作业
|
||||
|
||||
0xD0A8
|
||||
|
||||
无法替换作业,例如因为当前正在读取或删除作业
|
||||
|
||||
0xD0A9
|
||||
|
||||
无法读取作业,例如因为当前正在删除作业
|
||||
|
||||
0xD0AA
|
||||
|
||||
处理操作超出时间限制
|
||||
|
||||
0xD0AB
|
||||
|
||||
进程操作中的作业参数无效
|
||||
|
||||
0xD0AC
|
||||
|
||||
进程操作中的作业数据无效
|
||||
|
||||
0xD0AD
|
||||
|
||||
已设置操作模式
|
||||
|
||||
0xD0AE
|
||||
|
||||
作业是通过不同的连接设置的,只能通过此连接进行处理
|
||||
|
||||
0xD0C1
|
||||
|
||||
访问标签时至少检测到一个错误
|
||||
|
||||
0xD0C2
|
||||
|
||||
切换到STOP / HOLD模式
|
||||
|
||||
0xD0C3
|
||||
|
||||
访问标记时至少检测到一个错误。模式更改为STOP / HOLD
|
||||
|
||||
0xD0C4
|
||||
|
||||
运行时测量期间超时
|
||||
|
||||
0xD0C5
|
||||
|
||||
块堆栈的显示不一致,因为块被删除/重新加载
|
||||
|
||||
0xD0C6
|
||||
|
||||
作业已被删除,因为它所引用的作业已被删除
|
||||
|
||||
0xD0C7
|
||||
|
||||
由于退出了STOP模式,因此作业被自动删除
|
||||
|
||||
0xD0C8
|
||||
|
||||
由于测试作业和正在运行的程序之间不一致,“块状态”中止
|
||||
|
||||
0xD0C9
|
||||
|
||||
通过复位OB90退出状态区域
|
||||
|
||||
0xD0CA
|
||||
|
||||
通过在退出前重置OB90并访问错误读取标签退出状态范围
|
||||
|
||||
0xD0CB
|
||||
|
||||
外设输出的输出禁用再次激活
|
||||
|
||||
0xD0CC
|
||||
|
||||
调试功能的数据量受时间限制
|
||||
|
||||
0xD201
|
||||
|
||||
块名称中的语法错误
|
||||
|
||||
0xD202
|
||||
|
||||
函数参数中的语法错误
|
||||
|
||||
0xD205
|
||||
|
||||
RAM中已存在链接块:无法进行条件复制
|
||||
|
||||
0xD206
|
||||
|
||||
EPROM中已存在链接块:无法进行条件复制
|
||||
|
||||
0xD208
|
||||
|
||||
超出模块的最大复制(未链接)块数
|
||||
|
||||
0xD209
|
||||
|
||||
(至少)模块上找不到给定块之一
|
||||
|
||||
0xD20A
|
||||
|
||||
超出了可以与一个作业链接的最大块数
|
||||
|
||||
0xD20B
|
||||
|
||||
超出了一个作业可以删除的最大块数
|
||||
|
||||
0xD20C
|
||||
|
||||
OB无法复制,因为关联的优先级不存在
|
||||
|
||||
0xD20D
|
||||
|
||||
SDB无法解释(例如,未知数)
|
||||
|
||||
0xD20E
|
||||
|
||||
没有(进一步)阻止可用
|
||||
|
||||
0xD20F
|
||||
|
||||
超出模块特定的最大块大小
|
||||
|
||||
0xD210
|
||||
|
||||
块号无效
|
||||
|
||||
0xD212
|
||||
|
||||
标头属性不正确(与运行时相关)
|
||||
|
||||
0xD213
|
||||
|
||||
SDB太多。请注意对正在使用的模块的限制
|
||||
|
||||
0xD216
|
||||
|
||||
无效的用户程序 - 重置模块
|
||||
|
||||
0xD217
|
||||
|
||||
不允许在模块属性中指定的保护级别
|
||||
|
||||
0xD218
|
||||
|
||||
属性不正确(主动/被动)
|
||||
|
||||
0xD219
|
||||
|
||||
块长度不正确(例如,第一部分或整个块的长度不正确)
|
||||
|
||||
0xD21A
|
||||
|
||||
本地数据长度不正确或写保护错误
|
||||
|
||||
0xD21B
|
||||
|
||||
模块无法压缩或压缩早期中断
|
||||
|
||||
0xD21D
|
||||
|
||||
传输的动态项目数据量是非法的
|
||||
|
||||
0xD21E
|
||||
|
||||
无法为模块(例如FM,CP)分配参数。系统数据无法链接
|
||||
|
||||
0xD220
|
||||
|
||||
编程语言无效。请注意对正在使用的模块的限制
|
||||
|
||||
0xD221
|
||||
|
||||
连接或路由的系统数据无效
|
||||
|
||||
0xD222
|
||||
|
||||
全局数据定义的系统数据包含无效参数
|
||||
|
||||
0xD223
|
||||
|
||||
通信功能块的实例数据块错误或超出最大背景数据块数
|
||||
|
||||
0xD224
|
||||
|
||||
SCAN系统数据块包含无效参数
|
||||
|
||||
0xD225
|
||||
|
||||
DP系统数据块包含无效参数
|
||||
|
||||
0xD226
|
||||
|
||||
块中发生结构错误
|
||||
|
||||
0xD230
|
||||
|
||||
块中发生结构错误
|
||||
|
||||
0xD231
|
||||
|
||||
至少有一个已加载的OB无法复制,因为关联的优先级不存在
|
||||
|
||||
0xD232
|
||||
|
||||
加载块的至少一个块编号是非法的
|
||||
|
||||
0xD234
|
||||
|
||||
块在指定的内存介质或作业中存在两次
|
||||
|
||||
0xD235
|
||||
|
||||
该块包含不正确的校验和
|
||||
|
||||
0xD236
|
||||
|
||||
该块不包含校验和
|
||||
|
||||
0xD237
|
||||
|
||||
您将要加载块两次,即CPU上已存在具有相同时间戳的块
|
||||
|
||||
0xD238
|
||||
|
||||
指定的块中至少有一个不是DB
|
||||
|
||||
0xD239
|
||||
|
||||
至少有一个指定的DB在装载存储器中不可用作链接变量
|
||||
|
||||
0xD23A
|
||||
|
||||
至少有一个指定的DB与复制和链接的变体有很大不同
|
||||
|
||||
0xD240
|
||||
|
||||
违反了协调规则
|
||||
|
||||
0xD241
|
||||
|
||||
当前保护级别不允许该功能
|
||||
|
||||
0xD242
|
||||
|
||||
处理F块时的保护冲突
|
||||
|
||||
0xD250
|
||||
|
||||
更新和模块ID或版本不匹配
|
||||
|
||||
0xD251
|
||||
|
||||
操作系统组件序列不正确
|
||||
|
||||
0xD252
|
||||
|
||||
校验和错误
|
||||
|
||||
0xD253
|
||||
|
||||
没有可用的可执行加载程序; 只能使用存储卡进行更新
|
||||
|
||||
0xD254
|
||||
|
||||
操作系统中的存储错误
|
||||
|
||||
0xD280
|
||||
|
||||
在S7-300 CPU中编译块时出错
|
||||
|
||||
0xD2A1
|
||||
|
||||
块上的另一个块功能或触发器处于活动状态
|
||||
|
||||
0xD2A2
|
||||
|
||||
块上的触发器处于活动状态。首先完成调试功能
|
||||
|
||||
0xD2A3
|
||||
|
||||
块未激活(链接),块被占用或块当前被标记为删除
|
||||
|
||||
0xD2A4
|
||||
|
||||
该块已被另一个块函数处理
|
||||
|
||||
0xD2A6
|
||||
|
||||
无法同时保存和更改用户程序
|
||||
|
||||
0xD2A7
|
||||
|
||||
块具有“未链接”属性或未处理
|
||||
|
||||
0xD2A8
|
||||
|
||||
激活的调试功能阻止将参数分配给CPU
|
||||
|
||||
0xD2A9
|
||||
|
||||
正在为CPU分配新参数
|
||||
|
||||
0xD2AA
|
||||
|
||||
当前正在为模块分配新参数
|
||||
|
||||
0xD2AB
|
||||
|
||||
当前正在更改动态配置限制
|
||||
|
||||
0xD2AC
|
||||
|
||||
正在运行的激活或取消激活分配(SFC 12)暂时阻止R-KiR过程
|
||||
|
||||
0xD2B0
|
||||
|
||||
在RUN(CiR)中配置时发生错误
|
||||
|
||||
0xD2C0
|
||||
|
||||
已超出最大工艺对象数
|
||||
|
||||
0xD2C1
|
||||
|
||||
模块上已存在相同的技术数据块
|
||||
|
||||
0xD2C2
|
||||
|
||||
无法下载用户程序或下载硬件配置
|
||||
|
||||
0xD401
|
||||
|
||||
信息功能不可用
|
||||
|
||||
0xD402
|
||||
|
||||
信息功能不可用
|
||||
|
||||
0xD403
|
||||
|
||||
服务已登录/注销(诊断/ PMC)
|
||||
|
||||
0xD404
|
||||
|
||||
达到的最大节点数。不再需要登录诊断/ PMC
|
||||
|
||||
0xD405
|
||||
|
||||
不支持服务或函数参数中的语法错误
|
||||
|
||||
0xD406
|
||||
|
||||
当前不可用的必需信息
|
||||
|
||||
0xD407
|
||||
|
||||
发生诊断错误
|
||||
|
||||
0xD408
|
||||
|
||||
更新已中止
|
||||
|
||||
0xD409
|
||||
|
||||
DP总线错误
|
||||
|
||||
0xD601
|
||||
|
||||
函数参数中的语法错误
|
||||
|
||||
0xD602
|
||||
|
||||
输入的密码不正确
|
||||
|
||||
0xD603
|
||||
|
||||
连接已合法化
|
||||
|
||||
0xD604
|
||||
|
||||
已启用连接
|
||||
|
||||
0xD605
|
||||
|
||||
由于密码不存在,因此无法进行合法化
|
||||
|
||||
0xD801
|
||||
|
||||
至少有一个标记地址无效
|
||||
|
||||
0xD802
|
||||
|
||||
指定的作业不存在
|
||||
|
||||
0xD803
|
||||
|
||||
非法的工作状态
|
||||
|
||||
0xD804
|
||||
|
||||
非法循环时间(非法时基或多个)
|
||||
|
||||
0xD805
|
||||
|
||||
不能再设置循环读取作业
|
||||
|
||||
0xD806
|
||||
|
||||
引用的作业处于无法执行请求的功能的状态
|
||||
|
||||
0xD807
|
||||
|
||||
功能因过载而中止,这意味着执行读取周期所需的时间比设置的扫描周期时间长
|
||||
|
||||
0xDC01
|
||||
|
||||
日期和/或时间无效
|
||||
|
||||
0xE201
|
||||
|
||||
CPU已经是主设备
|
||||
|
||||
0xE202
|
||||
|
||||
由于闪存模块中的用户程序不同,无法进行连接和更新
|
||||
|
||||
0xE203
|
||||
|
||||
由于固件不同,无法连接和更新
|
||||
|
||||
0xE204
|
||||
|
||||
由于内存配置不同,无法连接和更新
|
||||
|
||||
0xE205
|
||||
|
||||
由于同步错误导致连接/更新中止
|
||||
|
||||
0xE206
|
||||
|
||||
由于协调违规而拒绝连接/更新
|
||||
|
||||
0xEF01
|
||||
|
||||
S7协议错误:ID2错误; 工作中只允许00H
|
||||
|
||||
0xEF02
|
||||
|
||||
S7协议错误:ID2错误; 资源集不存在
|
||||
@@ -55,7 +55,8 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.Run(() => TcpService.Start());
|
||||
Connect(cancellationToken);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
@@ -19,6 +21,10 @@ namespace ThingsGateway.Foundation.Core;
|
||||
/// </summary>
|
||||
public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDataHandlingAdapter<TRequest> where TRequest : class, IMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// 报文输出时采用字符串还是HexString
|
||||
/// </summary>
|
||||
public virtual bool IsHexData { get; set; } = true;
|
||||
/// <inheritdoc cref="ReadWriteDevicesTcpDataHandleAdapter{TRequest}"/>
|
||||
public ReadWriteDevicesTcpDataHandleAdapter()
|
||||
{
|
||||
@@ -46,7 +52,7 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
|
||||
{
|
||||
//获取全部内容
|
||||
var allBytes = byteBlock.ToArray(0, byteBlock.Len);
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{allBytes.ToHexString(' ')}");
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{(IsHexData ? allBytes.ToHexString(' ') : Encoding.UTF8.GetString(allBytes))}");
|
||||
//缓存/不缓存解析一样,因为游标已经归0
|
||||
{
|
||||
request = Request;
|
||||
@@ -131,7 +137,7 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
|
||||
/// <summary>
|
||||
/// 发送方法,会重新建立<see cref="Request"/>
|
||||
/// </summary>
|
||||
protected void GoSend(byte[] item)
|
||||
protected virtual void GoSend(byte[] item)
|
||||
{
|
||||
byte[] bytes;
|
||||
if (IsSendPackCommand)
|
||||
@@ -141,12 +147,12 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
|
||||
Request = GetInstance();
|
||||
Request.SendBytes = bytes;
|
||||
GoSend(bytes, 0, bytes.Length);
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{Request.SendBytes.ToHexString(' ')}");
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{(IsHexData ? Request.SendBytes.ToHexString(' ') : Encoding.UTF8.GetString(Request.SendBytes))}");
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送方法,会重新建立<see cref="Request"/>
|
||||
/// </summary>
|
||||
protected async Task GoSendAsync(byte[] item)
|
||||
protected virtual async Task GoSendAsync(byte[] item)
|
||||
{
|
||||
byte[] bytes;
|
||||
if (IsSendPackCommand)
|
||||
@@ -180,6 +186,13 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return Owner.ToString();
|
||||
if (Owner is SocketClient client)
|
||||
{
|
||||
return client.GetIPPort();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Owner.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
@@ -21,6 +22,13 @@ namespace ThingsGateway.Foundation.Core;
|
||||
/// </summary>
|
||||
public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHandlingAdapter where TRequest : class, IMessage
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 报文输出时采用字符串还是HexString
|
||||
/// </summary>
|
||||
public virtual bool IsHexData { get; set; } = true;
|
||||
|
||||
/// <inheritdoc cref="ReadWriteDevicesUdpDataHandleAdapter{TRequest}"/>
|
||||
public ReadWriteDevicesUdpDataHandleAdapter()
|
||||
{
|
||||
@@ -68,13 +76,13 @@ public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHa
|
||||
Request = GetInstance();
|
||||
Request.SendBytes = bytes;
|
||||
GoSend(endPoint, bytes, 0, bytes.Length);
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{Request.SendBytes.ToHexString(' ')}");
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{(IsHexData ? Request.SendBytes.ToHexString(' ') : Encoding.UTF8.GetString(Request.SendBytes))}");
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
protected override void PreviewReceived(EndPoint remoteEndPoint, ByteBlock byteBlock)
|
||||
{
|
||||
var allBytes = byteBlock.ToArray(0, byteBlock.Len);
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{allBytes.ToHexString(' ')}");
|
||||
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{(IsHexData ? allBytes.ToHexString(' ') : Encoding.UTF8.GetString(allBytes))}");
|
||||
|
||||
if (Request?.SendBytes == null)
|
||||
{
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.Generic;
|
||||
|
||||
namespace ThingsGateway.Foundation.Core;
|
||||
@@ -17,6 +19,39 @@ namespace ThingsGateway.Foundation.Core;
|
||||
/// <inheritdoc/>
|
||||
public static class ByteExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取异或校验
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="left"></param>
|
||||
/// <param name="right"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] GetAsciiXOR(this byte[] data, int left, int right)
|
||||
{
|
||||
int tmp = data[left];
|
||||
for (int i = left + 1; i < data.Length - right; i++)
|
||||
{
|
||||
tmp = (tmp ^ data[i]);
|
||||
}
|
||||
|
||||
byte[] fcs = new byte[2];
|
||||
fcs[0] = Encoding.ASCII.GetBytes(((byte)tmp).ToString("X2"))[0];
|
||||
fcs[1] = Encoding.ASCII.GetBytes(((byte)tmp).ToString("X2"))[1];
|
||||
return fcs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数组内容分别相加某个数字
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] BytesAdd(this byte[] bytes, int value)
|
||||
{
|
||||
for (int index = 0; index < bytes.Length; ++index)
|
||||
bytes[index] = (byte)(bytes[index] + value);
|
||||
return bytes;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取byte数据类型的第offset位,是否为True<br />
|
||||
/// </summary>
|
||||
|
||||
@@ -103,12 +103,12 @@ namespace ThingsGateway.Foundation.Core
|
||||
{
|
||||
return FilterResult.Cache;
|
||||
}
|
||||
if (!requestInfo.OnParsingStartCode(byteBlock.ToArray(byteBlock.Pos, this.StartCode.Length)))
|
||||
if (!requestInfo.OnParsingStartCode(byteBlock.ToArray(byteBlock.Pos + indexStart + 1 - this.StartCode.Length, this.StartCode.Length)))
|
||||
{
|
||||
byteBlock.Pos += this.StartCode.Length;
|
||||
byteBlock.Pos += indexStart;
|
||||
return FilterResult.GoOn;
|
||||
}
|
||||
byteBlock.Pos += this.StartCode.Length;
|
||||
byteBlock.Pos += indexStart + 1;
|
||||
request = requestInfo;
|
||||
|
||||
int len;
|
||||
|
||||
@@ -189,7 +189,7 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<string> GetTupleElementNames(this ParameterInfo parameter)
|
||||
{
|
||||
return ((dynamic)parameter.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")))?.TransformNames;
|
||||
return (IEnumerable<string>)DynamicMethodMemberAccessor.Default.GetValue(parameter.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")), "TransformNames");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -199,7 +199,7 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<string> GetTupleElementNames(this MemberInfo memberInfo)
|
||||
{
|
||||
return ((dynamic)memberInfo.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")))?.TransformNames;
|
||||
return (IEnumerable<string>)DynamicMethodMemberAccessor.Default.GetValue(memberInfo.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")), "TransformNames");
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
using System.Numerics;
|
||||
@@ -55,12 +56,11 @@ namespace ThingsGateway.Foundation.Core
|
||||
}
|
||||
|
||||
var capacity = 0L;
|
||||
var poolId = this.Id;
|
||||
var maxBuckets = SelectBucketIndex(maxArrayLength);
|
||||
var buckets = new Bucket[maxBuckets + 1];
|
||||
for (var i = 0; i < buckets.Length; i++)
|
||||
{
|
||||
buckets[i] = new Bucket(GetMaxSizeForBucket(i), maxArraysPerBucket, poolId);
|
||||
buckets[i] = new Bucket(GetMaxSizeForBucket(i), maxArraysPerBucket);
|
||||
long num = GetMaxSizeForBucket(i) * maxArraysPerBucket;
|
||||
capacity += num;
|
||||
}
|
||||
@@ -183,16 +183,19 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// </summary>
|
||||
/// <param name="size"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int HitSize(int size)
|
||||
{
|
||||
return GetMaxSizeForBucket(SelectBucketIndex(size));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static int GetMaxSizeForBucket(int binIndex)
|
||||
{
|
||||
return 16 << binIndex;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static int SelectBucketIndex(int bufferSize)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
@@ -208,18 +211,16 @@ namespace ThingsGateway.Foundation.Core
|
||||
internal readonly int m_bufferLength;
|
||||
private readonly int m_numberOfBuffers;
|
||||
private T[][] m_buffers;
|
||||
private readonly int m_poolId;
|
||||
|
||||
private int m_index;
|
||||
private SpinLock m_lock;
|
||||
|
||||
internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
|
||||
internal Bucket(int bufferLength, int numberOfBuffers)
|
||||
{
|
||||
this.m_lock = new SpinLock(Debugger.IsAttached);
|
||||
this.m_buffers = new T[numberOfBuffers][];
|
||||
this.m_bufferLength = bufferLength;
|
||||
this.m_numberOfBuffers = numberOfBuffers;
|
||||
this.m_poolId = poolId;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <summary>
|
||||
/// 内存池
|
||||
/// </summary>
|
||||
public class BytePool : ArrayPool<byte>
|
||||
public sealed class BytePool : ArrayPool<byte>
|
||||
{
|
||||
private readonly Timer m_timer;
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// <summary>
|
||||
/// 最大传输速度。
|
||||
/// </summary>
|
||||
public long MaxSpeed { get => this.m_flowGate.Maximum; set => this.m_flowGate.Maximum = value; }
|
||||
public virtual long MaxSpeed { get => this.m_flowGate.Maximum; set => this.m_flowGate.Maximum = value; }
|
||||
|
||||
/// <summary>
|
||||
/// 元数据
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
{
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
|
||||
{
|
||||
await actor.SendAsync(this.m_pullFileResourceInfo_Request, byteBlock);
|
||||
actor.Send(this.m_pullFileResourceInfo_Request, byteBlock);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -92,12 +92,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFileResource.SwitchId();
|
||||
byteBlock.Reset();
|
||||
waitFileResource.Package(byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
|
||||
this.DmtpActor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
waitFileResource.UnpackageBody(byteBlock);
|
||||
_ = this.RequestPullFileResourceInfo(waitFileResource);
|
||||
_ = Task.Factory.StartNew(this.RequestPullFileResourceInfo, waitFileResource);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -116,7 +116,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
{
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
|
||||
{
|
||||
await actor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
|
||||
actor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -406,7 +406,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
else
|
||||
{
|
||||
waitSmallFilePackage.UnpackageBody(byteBlock);
|
||||
_ = this.RequestPullSmallFile(waitSmallFilePackage);
|
||||
_ = Task.Factory.StartNew(this.RequestPullSmallFile, waitSmallFilePackage);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -1324,7 +1324,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
{
|
||||
waitFileResource.SwitchId();
|
||||
waitFileResource.Package(byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
|
||||
this.DmtpActor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -59,12 +59,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
/// </summary>
|
||||
public int TryCount { get; set; } = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 设置结果状态
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
public Result SetResult(Result result)
|
||||
internal Result SetResult(Result result)
|
||||
{
|
||||
this.Result = result;
|
||||
return result;
|
||||
|
||||
@@ -240,7 +240,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
DmtpRpcPackage = rpcPackage
|
||||
};
|
||||
this.TryAdd(rpcPackage.Sign, callContext);
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
ps = new object[methodInstance.ParameterTypes.Length];
|
||||
ps[0] = callContext;
|
||||
@@ -314,7 +314,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
rpcPackage.ParametersBytes = new List<byte[]>();
|
||||
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,10 @@ namespace ThingsGateway.Foundation.Http
|
||||
public HttpStaticPagePlugin()
|
||||
{
|
||||
this.FileCache = new FileCachePool();
|
||||
this.SetNavigateAction(request =>
|
||||
{
|
||||
return request.RelativeURL;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -81,15 +85,45 @@ namespace ThingsGateway.Foundation.Http
|
||||
this.FileCache.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新导航
|
||||
/// </summary>
|
||||
public Func<HttpRequest, Task<string>> NavigateAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设定重新导航
|
||||
/// </summary>
|
||||
/// <param name="func"></param>
|
||||
/// <returns></returns>
|
||||
public HttpStaticPagePlugin SetNavigateAction(Func<HttpRequest, Task<string>> func)
|
||||
{
|
||||
this.NavigateAction = func;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设定重新导航
|
||||
/// </summary>
|
||||
/// <param name="func"></param>
|
||||
/// <returns></returns>
|
||||
public HttpStaticPagePlugin SetNavigateAction(Func<HttpRequest, string> func)
|
||||
{
|
||||
this.NavigateAction = (request) =>
|
||||
{
|
||||
return Task.FromResult(func(request));
|
||||
};
|
||||
return this;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public async Task OnHttpRequest(IHttpSocketClient client, HttpContextEventArgs e)
|
||||
{
|
||||
if (this.FileCache.Find(e.Context.Request.RelativeURL, out var data))
|
||||
var url = await this.NavigateAction.Invoke(e.Context.Request);
|
||||
if (this.FileCache.Find(url, out var data))
|
||||
{
|
||||
e.Context.Response.SetStatus();
|
||||
if (this.ContentTypeProvider?.TryGetContentType(e.Context.Request.RelativeURL, out var result) != true)
|
||||
if (this.ContentTypeProvider?.TryGetContentType(url, out var result) != true)
|
||||
{
|
||||
result = HttpTools.GetContentTypeFromExtension(e.Context.Request.RelativeURL);
|
||||
result = HttpTools.GetContentTypeFromExtension(url);
|
||||
}
|
||||
e.Context.Response.ContentType = result;
|
||||
e.Context.Response.SetContentLength(data.Length)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
namespace ThingsGateway.Foundation.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
/// 标识该接口将自动生成调用的扩展方法静态类
|
||||
/// 标识该接口将自动生成调用的代理类
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
|
||||
public sealed class GeneratorRpcProxyAttribute : Attribute
|
||||
@@ -39,7 +39,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
public string Namespace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生成的类名,不要包含“I”,生成接口时会自动家。
|
||||
/// 生成的类名,不要包含“I”,生成接口时会自动添加。
|
||||
/// </summary>
|
||||
public string ClassName { get; set; }
|
||||
|
||||
@@ -48,11 +48,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// </summary>
|
||||
public CodeGeneratorFlag GeneratorFlag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 函数标识
|
||||
/// </summary>
|
||||
public MethodFlags MethodFlags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 继承接口
|
||||
/// </summary>
|
||||
|
||||
@@ -39,7 +39,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// </summary>
|
||||
public RpcAttribute()
|
||||
{
|
||||
this.MethodFlags = MethodFlags.None;
|
||||
this.Exceptions.Add(typeof(TimeoutException), "调用超时");
|
||||
this.Exceptions.Add(typeof(RpcInvokeException), "Rpc调用异常");
|
||||
this.Exceptions.Add(typeof(Exception), "其他异常");
|
||||
@@ -72,11 +71,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// </summary>
|
||||
public string InvokeKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 函数标识
|
||||
/// </summary>
|
||||
public MethodFlags MethodFlags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否仅以函数名调用,当为True是,调用时仅需要传入方法名即可。
|
||||
/// </summary>
|
||||
@@ -122,25 +116,25 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
|
||||
codeString.Append("public static ");
|
||||
codeString.Append(this.GetReturn(methodInstance, false));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, false));
|
||||
codeString.Append("<TClient>(");//方法参数
|
||||
|
||||
codeString.Append($"this TClient client");
|
||||
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
for (var i = 0; i < parametersStr.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
|
||||
codeString.Append(parametersStr[i]);
|
||||
}
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(") where TClient:");
|
||||
@@ -149,7 +143,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
|
||||
codeString.Append(InterfaceTypes[i].FullName);
|
||||
@@ -159,7 +153,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append($"object[] parameters = new object[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
@@ -173,7 +167,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
@@ -181,13 +175,13 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.Append($"Type[] types = new Type[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append($"typeof({this.GetProxyParameterName(parameter)})");
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
@@ -199,7 +193,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count == 0)
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
@@ -207,7 +201,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
else if (isOut || isRef)
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption,ref parameters,types);");
|
||||
@@ -215,7 +209,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
else
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, parameters);");
|
||||
@@ -275,12 +269,12 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
//以下生成异步
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.ExtensionAsync) && !isOut && !isRef)//没有out或者ref
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.ExtensionAsync) /*&& !isOut && !isRef*/)
|
||||
{
|
||||
codeString.AppendLine("///<summary>");
|
||||
codeString.AppendLine($"///{description}");
|
||||
codeString.AppendLine("///</summary>");
|
||||
if (methodInstance.HasReturn)
|
||||
if (methodInstance.HasReturn && !isOut && !isRef)
|
||||
{
|
||||
codeString.Append("public static async ");
|
||||
}
|
||||
@@ -289,24 +283,24 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.Append("public static ");
|
||||
}
|
||||
codeString.Append(this.GetReturn(methodInstance, true));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, true));
|
||||
codeString.Append("<TClient>(");//方法参数
|
||||
|
||||
codeString.Append($"this TClient client");
|
||||
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
for (var i = 0; i < parametersStr.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(parametersStr[i]);
|
||||
}
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(") where TClient:");
|
||||
@@ -315,7 +309,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
|
||||
codeString.Append(InterfaceTypes[i].FullName);
|
||||
@@ -326,16 +320,39 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append($"object[] parameters = new object[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append(parameter.Name);
|
||||
if (parameter.ParameterType.Name.Contains("&") && parameter.IsOut)
|
||||
{
|
||||
codeString.Append($"default({this.GetProxyParameterName(parameter)})");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append(parameter.Name);
|
||||
}
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.Append($"Type[] types = new Type[]");
|
||||
codeString.Append('{');
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append($"typeof({this.GetProxyParameterName(parameter)})");
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
}
|
||||
}
|
||||
|
||||
if (methodInstance.HasReturn)
|
||||
@@ -343,15 +360,23 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count == 0)
|
||||
{
|
||||
codeString.Append(string.Format("return ({0}) await client.InvokeAsync", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
}
|
||||
else if (isOut || isRef)
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption,ref parameters,types);");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append(string.Format("return ({0}) await client.InvokeAsync", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, parameters);");
|
||||
@@ -365,6 +390,12 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
}
|
||||
else if (isOut || isRef)
|
||||
{
|
||||
codeString.Append("client.Invoke(");
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption,ref parameters,types);");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append("return client.InvokeAsync(");
|
||||
@@ -372,6 +403,43 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.AppendLine(",invokeOption, parameters);");
|
||||
}
|
||||
}
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.AppendLine("if(parameters!=null)");
|
||||
codeString.AppendLine("{");
|
||||
for (var i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
codeString.AppendLine(string.Format("{0}=({1})parameters[{2}];", parameters[i].Name, this.GetProxyParameterName(parameters[i]), i));
|
||||
}
|
||||
codeString.AppendLine("}");
|
||||
if (isOut)
|
||||
{
|
||||
codeString.AppendLine("else");
|
||||
codeString.AppendLine("{");
|
||||
for (var i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
if (parameters[i].IsOut)
|
||||
{
|
||||
codeString.AppendLine(string.Format("{0}=default({1});", parameters[i].Name, this.GetProxyParameterName(parameters[i])));
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("}");
|
||||
}
|
||||
}
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
if (methodInstance.HasReturn)
|
||||
{
|
||||
codeString.AppendLine(string.Format("return Task.FromResult<{0}>(returnData);", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.AppendLine(string.Format("return EasyTask.CompletedTask;"));
|
||||
}
|
||||
}
|
||||
|
||||
codeString.AppendLine("}");
|
||||
}
|
||||
return codeString.ToString();
|
||||
@@ -409,21 +477,21 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
|
||||
codeString.Append("public ");
|
||||
codeString.Append(this.GetReturn(methodInstance, false));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, false));
|
||||
codeString.Append("(");//方法参数
|
||||
codeString.Append('(');//方法参数
|
||||
|
||||
for (var i = 0; i < parametersStr.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(parametersStr[i]);
|
||||
}
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(")");
|
||||
@@ -438,7 +506,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append($"object[] parameters = new object[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
@@ -452,7 +520,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
@@ -460,13 +528,13 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.Append($"Type[] types = new Type[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append($"typeof({this.GetProxyParameterName(parameter)})");
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
@@ -478,7 +546,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count == 0)
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})Client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
@@ -554,12 +622,12 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
//以下生成异步
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InstanceAsync) && !isOut && !isRef)//没有out或者ref
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InstanceAsync))
|
||||
{
|
||||
codeString.AppendLine("///<summary>");
|
||||
codeString.AppendLine($"///{description}");
|
||||
codeString.AppendLine("///</summary>");
|
||||
if (methodInstance.HasReturn)
|
||||
if (methodInstance.HasReturn && (!isOut && !isRef))
|
||||
{
|
||||
codeString.Append("public async ");
|
||||
}
|
||||
@@ -568,21 +636,21 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.Append("public ");
|
||||
}
|
||||
codeString.Append(this.GetReturn(methodInstance, true));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, true));
|
||||
codeString.Append("(");//方法参数
|
||||
codeString.Append('(');//方法参数
|
||||
|
||||
for (var i = 0; i < parametersStr.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(parametersStr[i]);
|
||||
}
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(")");
|
||||
@@ -597,16 +665,39 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append($"object[] parameters = new object[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append(parameter.Name);
|
||||
if (parameter.ParameterType.Name.Contains("&") && parameter.IsOut)
|
||||
{
|
||||
codeString.Append($"default({this.GetProxyParameterName(parameter)})");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append(parameter.Name);
|
||||
}
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.Append($"Type[] types = new Type[]");
|
||||
codeString.Append('{');
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append($"typeof({this.GetProxyParameterName(parameter)})");
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
}
|
||||
}
|
||||
|
||||
if (methodInstance.HasReturn)
|
||||
@@ -614,15 +705,23 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count == 0)
|
||||
{
|
||||
codeString.Append(string.Format("return ({0}) await Client.InvokeAsync", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
}
|
||||
else if (isOut || isRef)
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})Client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption,ref parameters,types);");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append(string.Format("return ({0}) await Client.InvokeAsync", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, parameters);");
|
||||
@@ -636,6 +735,12 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
}
|
||||
else if (isOut || isRef)
|
||||
{
|
||||
codeString.Append("Client.Invoke(");
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption,ref parameters,types);");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append("return Client.InvokeAsync(");
|
||||
@@ -643,8 +748,46 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.AppendLine(",invokeOption, parameters);");
|
||||
}
|
||||
}
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.AppendLine("if(parameters!=null)");
|
||||
codeString.AppendLine("{");
|
||||
for (var i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
codeString.AppendLine(string.Format("{0}=({1})parameters[{2}];", parameters[i].Name, this.GetProxyParameterName(parameters[i]), i));
|
||||
}
|
||||
codeString.AppendLine("}");
|
||||
if (isOut)
|
||||
{
|
||||
codeString.AppendLine("else");
|
||||
codeString.AppendLine("{");
|
||||
for (var i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
if (parameters[i].IsOut)
|
||||
{
|
||||
codeString.AppendLine(string.Format("{0}=default({1});", parameters[i].Name, this.GetProxyParameterName(parameters[i])));
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("}");
|
||||
}
|
||||
}
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
if (methodInstance.HasReturn)
|
||||
{
|
||||
codeString.AppendLine(string.Format("return Task.FromResult<{0}>(returnData);", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.AppendLine(string.Format("return EasyTask.CompletedTask;"));
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("}");
|
||||
}
|
||||
|
||||
|
||||
return codeString.ToString();
|
||||
}
|
||||
|
||||
@@ -669,26 +812,26 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
codeString.Append(this.GetReturn(methodInstance, false));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, false));
|
||||
codeString.Append("(");//方法参数
|
||||
codeString.Append('(');//方法参数
|
||||
for (var i = 0; i < parameters.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(parameters[i]);
|
||||
}
|
||||
if (parameters.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(");");
|
||||
}
|
||||
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InterfaceAsync) && !isOut && !isRef)//没有out或者ref
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InterfaceAsync))
|
||||
{
|
||||
codeString.AppendLine("///<summary>");
|
||||
codeString.AppendLine($"///{description}");
|
||||
@@ -699,21 +842,21 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
codeString.Append(this.GetReturn(methodInstance, true));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, true));
|
||||
codeString.Append("(");//方法参数
|
||||
codeString.Append('(');//方法参数
|
||||
|
||||
for (var i = 0; i < parameters.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(parameters[i]);
|
||||
}
|
||||
if (parameters.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(");");
|
||||
@@ -774,7 +917,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
isOut = false;
|
||||
isRef = false;
|
||||
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
var infos = new List<ParameterInfo>(methodInstance.Parameters);
|
||||
infos.RemoveAt(0);
|
||||
|
||||
@@ -302,7 +302,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
|
||||
@@ -75,10 +75,10 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
var fromMethodInfos = new Dictionary<string, MethodInfo>();
|
||||
CodeGenerator.GetMethodInfos(ServerFromType, ref fromMethodInfos);
|
||||
CodeGenerator.GetMethodInfos(this.ServerFromType, ref fromMethodInfos);
|
||||
|
||||
var toMethodInfos = new Dictionary<string, MethodInfo>();
|
||||
CodeGenerator.GetMethodInfos(ServerToType, ref toMethodInfos);
|
||||
CodeGenerator.GetMethodInfos(this.ServerToType, ref toMethodInfos);
|
||||
|
||||
var attributes = method.GetCustomAttributes<RpcAttribute>(true);
|
||||
if (attributes.Any())
|
||||
@@ -98,7 +98,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in ServerFromType.GetCustomAttributes(true))
|
||||
foreach (var item in this.ServerFromType.GetCustomAttributes(true))
|
||||
{
|
||||
if (item is IRpcActionFilter filter)
|
||||
{
|
||||
@@ -106,7 +106,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
if (ServerFromType != ServerToType)
|
||||
if (this.ServerFromType != this.ServerToType)
|
||||
{
|
||||
foreach (var item in toMethod.GetCustomAttributes(true))
|
||||
{
|
||||
@@ -116,7 +116,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in ServerToType.GetCustomAttributes(true))
|
||||
foreach (var item in this.ServerToType.GetCustomAttributes(true))
|
||||
{
|
||||
if (item is IRpcActionFilter filter)
|
||||
{
|
||||
@@ -128,17 +128,23 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
{
|
||||
this.Filters = actionFilters.ToArray();
|
||||
}
|
||||
foreach (var item in attributes)
|
||||
//foreach (var item in attributes)
|
||||
//{
|
||||
// this.MethodFlags |= item.MethodFlags;
|
||||
//}
|
||||
//if (this.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
//{
|
||||
// if (this.Parameters.Length == 0 || !typeof(ICallContext).IsAssignableFrom(this.Parameters[0].ParameterType))
|
||||
// {
|
||||
// throw new RpcException($"函数:{method},标识包含{MethodFlags.IncludeCallContext}时,必须包含{nameof(ICallContext)}或其派生类参数,且为第一参数。");
|
||||
// }
|
||||
//}
|
||||
|
||||
if (this.Parameters.Length > 0 && typeof(ICallContext).IsAssignableFrom(this.Parameters[0].ParameterType))
|
||||
{
|
||||
this.MethodFlags |= item.MethodFlags;
|
||||
}
|
||||
if (this.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
{
|
||||
if (this.Parameters.Length == 0 || !typeof(ICallContext).IsAssignableFrom(this.Parameters[0].ParameterType))
|
||||
{
|
||||
throw new RpcException($"函数:{method},标识包含{MethodFlags.IncludeCallContext}时,必须包含{nameof(ICallContext)}或其派生类参数,且为第一参数。");
|
||||
}
|
||||
this.IncludeCallContext = true;
|
||||
}
|
||||
|
||||
var names = new List<string>();
|
||||
foreach (var parameterInfo in this.Parameters)
|
||||
{
|
||||
@@ -155,6 +161,11 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含调用上下文
|
||||
/// </summary>
|
||||
public bool IncludeCallContext { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 筛选器
|
||||
/// </summary>
|
||||
@@ -165,11 +176,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// </summary>
|
||||
public bool IsEnable { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 函数标识
|
||||
/// </summary>
|
||||
public MethodFlags MethodFlags { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 参数名集合
|
||||
/// </summary>
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:http://rrqm_home.gitee.io/touchsocket/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ThingsGateway.Foundation.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
/// 函数标识
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum MethodFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// 空
|
||||
/// </summary>
|
||||
None = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 包含调用上下文
|
||||
/// </summary>
|
||||
IncludeCallContext = 2
|
||||
}
|
||||
}
|
||||
@@ -34,8 +34,8 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// 调用此服务的主体。
|
||||
/// <para>
|
||||
/// <list type="bullet">
|
||||
/// <item>当该服务在<see cref="ITcpService"/>及派生中调用时,该值一般为<see cref="ISocketClient"/>对象。</item>
|
||||
/// <item>当该服务在<see cref="ITcpClient"/>及派生中调用时,该值一般为<see cref="ITcpClient"/>对象。</item>
|
||||
/// <item>当该服务在ITcpService及派生中调用时,该值一般为ISocketClient对象。</item>
|
||||
/// <item>当该服务在ITcpClient及派生中调用时,该值一般为ITcpClient对象。</item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </summary>
|
||||
|
||||
@@ -39,7 +39,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="parameters">参数</param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
Task InvokeAsync(string targetId, string invokeKey, IInvokeOption invokeOption, params object[] parameters);
|
||||
|
||||
@@ -53,7 +52,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="parameters">参数</param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
/// <returns>返回值</returns>
|
||||
Task<object> InvokeAsync(Type returnType, string targetId, string invokeKey, IInvokeOption invokeOption, params object[] parameters);
|
||||
@@ -67,7 +65,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="parameters">参数</param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
void Invoke(string targetId, string invokeKey, IInvokeOption invokeOption, params object[] parameters);
|
||||
|
||||
@@ -81,7 +78,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="parameters">参数</param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
/// <returns>返回值</returns>
|
||||
object Invoke(Type returnType, string targetId, string invokeKey, IInvokeOption invokeOption, params object[] parameters);
|
||||
@@ -96,7 +92,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="types"></param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
void Invoke(string targetId, string invokeKey, IInvokeOption invokeOption, ref object[] parameters, Type[] types);
|
||||
|
||||
@@ -111,7 +106,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="types"></param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
/// <returns>返回值</returns>
|
||||
object Invoke(Type returnType, string targetId, string invokeKey, IInvokeOption invokeOption, ref object[] parameters, Type[] types);
|
||||
|
||||
@@ -727,6 +727,11 @@ public class SerialSessionBase : BaseSerial, ISerialSession
|
||||
{
|
||||
if (this.SendingData(buffer, offset, length).GetFalseAwaitResult())
|
||||
{
|
||||
if (this.m_delaySender != null)
|
||||
{
|
||||
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
|
||||
return;
|
||||
}
|
||||
this.GetSerialCore().Send(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,10 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
/// </summary>
|
||||
public int DelayLength { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 队列长度
|
||||
/// </summary>
|
||||
public int QueueCount => this.m_queueDatas.Count;
|
||||
|
||||
/// <summary>
|
||||
/// 发送
|
||||
|
||||
@@ -39,23 +39,10 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
public SocketClient()
|
||||
{
|
||||
this.Protocol = Protocol.Tcp;
|
||||
//this.m_receiveCounter = new ValueCounter
|
||||
//{
|
||||
// Period = TimeSpan.FromSeconds(1),
|
||||
// OnPeriod = this.OnReceivePeriod
|
||||
//};
|
||||
//m_sendCounter = new ValueCounter
|
||||
//{
|
||||
// Period = TimeSpan.FromSeconds(1),
|
||||
// OnPeriod = this.OnSendPeriod
|
||||
//};
|
||||
}
|
||||
|
||||
#region 变量
|
||||
|
||||
//private ValueCounter m_receiveCounter;
|
||||
//private ValueCounter m_sendCounter;
|
||||
//private long m_bufferRate = 1;
|
||||
private DelaySender m_delaySender;
|
||||
|
||||
private TcpCore m_tcpCore;
|
||||
@@ -127,25 +114,15 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
#endregion 属性
|
||||
|
||||
#region Internal
|
||||
|
||||
internal Task AuthenticateAsync(ServiceSslOption sslOption)
|
||||
{
|
||||
return this.m_tcpCore.AuthenticateAsync(sslOption);
|
||||
}
|
||||
internal void BeginReceive()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_tcpCore.BeginIocpReceive();
|
||||
//if (this.ReceiveType == ReceiveType.Iocp)
|
||||
//{
|
||||
// //var eventArgs = new SocketAsyncEventArgs();
|
||||
// //eventArgs.Completed += this.EventArgs_Completed;
|
||||
// //var byteBlock = BytePool.Default.GetByteBlock(this.ReceiveBufferSize);
|
||||
// //eventArgs.UserToken = byteBlock;
|
||||
// //eventArgs.SetBuffer(byteBlock.Buffer, 0, byteBlock.Capacity);
|
||||
// //if (!this.MainSocket.ReceiveAsync(eventArgs))
|
||||
// //{
|
||||
// // this.ProcessReceived(eventArgs);
|
||||
// //}
|
||||
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -153,10 +130,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
}
|
||||
}
|
||||
|
||||
internal Task AuthenticateAsync(ServiceSslOption sslOption)
|
||||
{
|
||||
return this.m_tcpCore.AuthenticateAsync(sslOption);
|
||||
}
|
||||
|
||||
internal Task BeginReceiveSsl()
|
||||
{
|
||||
return this.m_tcpCore.BeginSslReceive();
|
||||
@@ -220,7 +194,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
|
||||
if (this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty) is DelaySenderOption senderOption)
|
||||
{
|
||||
this.m_delaySender = new DelaySender(senderOption, this.MainSocket.AbsoluteSend);
|
||||
this.m_delaySender = new DelaySender(senderOption, this.GetTcpCore().Send);
|
||||
}
|
||||
|
||||
var tcpCore = this.Service.RentTcpCore();
|
||||
@@ -239,10 +213,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
this.m_tcpCore = tcpCore;
|
||||
}
|
||||
|
||||
private void TcpCoreBreakOut(TcpCore core, bool manual, string msg)
|
||||
{
|
||||
this.BreakOut(manual, msg);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 中断连接
|
||||
@@ -292,7 +263,10 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
this.Logger.Log(LogLevel.Error, this, "在处理数据时发生错误", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void TcpCoreBreakOut(TcpCore core, bool manual, string msg)
|
||||
{
|
||||
this.BreakOut(manual, msg);
|
||||
}
|
||||
#endregion Internal
|
||||
|
||||
#region 事件&委托
|
||||
@@ -387,10 +361,6 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private Task PrivateOnDisconnecting(object obj)
|
||||
{
|
||||
return this.OnDisconnecting((DisconnectEventArgs)obj);
|
||||
}
|
||||
|
||||
private async Task PrivateOnDisconnected(object obj)
|
||||
{
|
||||
@@ -410,7 +380,10 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
this.Service.ReturnTcpCore(tcp);
|
||||
}
|
||||
}
|
||||
|
||||
private Task PrivateOnDisconnecting(object obj)
|
||||
{
|
||||
return this.OnDisconnecting((DisconnectEventArgs)obj);
|
||||
}
|
||||
#endregion 事件&委托
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -522,23 +495,6 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当即将发送时,如果覆盖父类方法,则不会触发插件。
|
||||
/// </summary>
|
||||
/// <param name="buffer">数据缓存区</param>
|
||||
/// <param name="offset">偏移</param>
|
||||
/// <param name="length">长度</param>
|
||||
/// <returns>返回值表示是否允许发送</returns>
|
||||
protected virtual async Task<bool> SendingData(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (this.PluginsManager.GetPluginCount(nameof(ITcpSendingPlugin.OnTcpSending)) > 0)
|
||||
{
|
||||
var args = new SendingEventArgs(buffer, offset, length);
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpSendingPlugin.OnTcpSending), this, args).ConfigureAwait(false);
|
||||
return args.IsPermitOperation;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当Id更新的时候触发
|
||||
@@ -581,6 +537,24 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当即将发送时,如果覆盖父类方法,则不会触发插件。
|
||||
/// </summary>
|
||||
/// <param name="buffer">数据缓存区</param>
|
||||
/// <param name="offset">偏移</param>
|
||||
/// <param name="length">长度</param>
|
||||
/// <returns>返回值表示是否允许发送</returns>
|
||||
protected virtual async Task<bool> SendingData(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (this.PluginsManager.GetPluginCount(nameof(ITcpSendingPlugin.OnTcpSending)) > 0)
|
||||
{
|
||||
var args = new SendingEventArgs(buffer, offset, length);
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpSendingPlugin.OnTcpSending), this, args).ConfigureAwait(false);
|
||||
return args.IsPermitOperation;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置适配器,该方法不会检验<see cref="CanSetDataHandlingAdapter"/>的值。
|
||||
/// </summary>
|
||||
@@ -635,6 +609,11 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
if (this.SendingData(buffer, offset, length).GetFalseAwaitResult())
|
||||
{
|
||||
if (this.m_delaySender != null)
|
||||
{
|
||||
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
|
||||
return;
|
||||
}
|
||||
this.GetTcpCore().Send(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
@@ -866,18 +845,19 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
|
||||
private Receiver m_receiver;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReceiver CreateReceiver()
|
||||
{
|
||||
return this.m_receiver ??= new Receiver(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ClearReceiver()
|
||||
{
|
||||
this.m_receiver = null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReceiver CreateReceiver()
|
||||
{
|
||||
return this.m_receiver ??= new Receiver(this);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -911,6 +911,11 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
if (this.SendingData(buffer, offset, length).GetFalseAwaitResult())
|
||||
{
|
||||
if (this.m_delaySender != null)
|
||||
{
|
||||
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
|
||||
return;
|
||||
}
|
||||
this.GetTcpCore().Send(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
@@ -941,7 +946,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty);
|
||||
if (delaySenderOption != null)
|
||||
{
|
||||
this.m_delaySender = new DelaySender(delaySenderOption, this.MainSocket.AbsoluteSend);
|
||||
this.m_delaySender = new DelaySender(delaySenderOption, this.GetTcpCore().Send);
|
||||
}
|
||||
this.m_tcpCore.Reset(socket);
|
||||
this.m_tcpCore.OnReceived = this.HandleReceived;
|
||||
|
||||
@@ -493,6 +493,11 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
/// </summary>
|
||||
public override IService Stop()
|
||||
{
|
||||
foreach (var item in m_monitors)
|
||||
{
|
||||
Logger.Info($"{item.Option.IpHost}停止成功");
|
||||
}
|
||||
|
||||
foreach (var item in this.m_monitors)
|
||||
{
|
||||
item.Socket.SafeDispose();
|
||||
@@ -603,6 +608,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
foreach (var item in optionList)
|
||||
{
|
||||
this.AddListen(item);
|
||||
Logger.Info($"{item.IpHost}启动成功");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,8 +91,15 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
public static ResponsedData SendThenResponse<TClient>(this IWaitingClient<TClient> client, byte[] buffer, int timeout, CancellationToken token)
|
||||
where TClient : IClient, ISender
|
||||
{
|
||||
using CancellationTokenSource cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(new CancellationTokenSource(timeout).Token, token);
|
||||
return client.SendThenResponse(buffer, 0, buffer.Length, cancellationTokenSource.Token);
|
||||
if (token.CanBeCanceled)
|
||||
{
|
||||
using CancellationTokenSource cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(new CancellationTokenSource(timeout).Token, token);
|
||||
return client.SendThenResponse(buffer, 0, buffer.Length, cancellationTokenSource.Token);
|
||||
}
|
||||
else
|
||||
{
|
||||
return client.SendThenResponse(buffer, 0, buffer.Length, token);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送数据并等待
|
||||
@@ -105,11 +112,11 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
/// <exception cref="OverlengthException">发送数据超长</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
/// <returns>返回的数据</returns>
|
||||
public static Task<ResponsedData> SendThenResponseAsync<TClient>(this IWaitingClient<TClient> client, byte[] buffer, int timeout, CancellationToken token)
|
||||
public static async Task<ResponsedData> SendThenResponseAsync<TClient>(this IWaitingClient<TClient> client, byte[] buffer, int timeout, CancellationToken token)
|
||||
where TClient : IClient, ISender
|
||||
{
|
||||
using CancellationTokenSource cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(new CancellationTokenSource(timeout).Token, token);
|
||||
return client.SendThenResponseAsync(buffer, 0, buffer.Length, cancellationTokenSource.Token);
|
||||
return await client.SendThenResponseAsync(buffer, 0, buffer.Length, cancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -251,7 +251,7 @@ namespace ThingsGateway.Foundation.WebApi.Swagger
|
||||
Summary = methodInstance.GetDescription()
|
||||
};
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
@@ -312,7 +312,7 @@ namespace ThingsGateway.Foundation.WebApi.Swagger
|
||||
};
|
||||
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
@@ -333,7 +333,7 @@ namespace ThingsGateway.Foundation.WebApi.Swagger
|
||||
openApiPathValue.Parameters = parameters.Count > 0 ? parameters : default;
|
||||
|
||||
ParameterInfo parameterInfo = null;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
if (methodInstance.Parameters.Length > 1)
|
||||
{
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace ThingsGateway.Foundation.WebApi
|
||||
public override string GetInvokenKey(MethodInstance methodInstance)
|
||||
{
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace ThingsGateway.Foundation.WebApi
|
||||
{
|
||||
ps = new object[methodInstance.Parameters.Length];
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
ps[i] = callContext;
|
||||
i++;
|
||||
@@ -227,7 +227,7 @@ namespace ThingsGateway.Foundation.WebApi
|
||||
int index;
|
||||
ps = new object[methodInstance.Parameters.Length];
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
ps[i] = callContext;
|
||||
i++;
|
||||
@@ -263,7 +263,7 @@ namespace ThingsGateway.Foundation.WebApi
|
||||
if (index >= 0)
|
||||
{
|
||||
var str = e.Context.Request.GetBody();
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.0.24</Version>
|
||||
<Version>3.0.0.27</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Confluent.Kafka" Version="2.2.0" />
|
||||
<PackageReference Include="Confluent.Kafka" Version="2.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace ThingsGateway.Plugin.OPCDA;
|
||||
public class OPCDAClient : CollectBase
|
||||
{
|
||||
internal ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient _plc = null;
|
||||
internal CollectDeviceRunTime Device;
|
||||
private readonly OPCDAClientProperty driverPropertys = new();
|
||||
private ConcurrentList<DeviceVariableRunTime> _deviceVariables = new();
|
||||
/// <inheritdoc/>
|
||||
@@ -60,7 +59,7 @@ public class OPCDAClient : CollectBase
|
||||
/// <inheritdoc/>
|
||||
public override bool IsConnected()
|
||||
{
|
||||
Device.SetDeviceStatus(DateTimeExtensions.CurrentDateTime);
|
||||
CurrentDevice.SetDeviceStatus(DateTimeExtensions.CurrentDateTime);
|
||||
return _plc?.IsConnected == true;
|
||||
}
|
||||
|
||||
@@ -137,7 +136,7 @@ public class OPCDAClient : CollectBase
|
||||
/// <inheritdoc/>
|
||||
protected override void Init(CollectDeviceRunTime device, object client = null)
|
||||
{
|
||||
Device = device;
|
||||
CurrentDevice = device;
|
||||
OPCNode opcNode = new()
|
||||
{
|
||||
OPCIP = driverPropertys.OPCIP,
|
||||
@@ -166,7 +165,7 @@ public class OPCDAClient : CollectBase
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Device.KeepRun)
|
||||
if (!CurrentDevice.KeepRun)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -174,7 +173,7 @@ public class OPCDAClient : CollectBase
|
||||
|
||||
foreach (var data in values)
|
||||
{
|
||||
if (!Device.KeepRun)
|
||||
if (!CurrentDevice.KeepRun)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -226,7 +225,6 @@ public class OPCDAClient : CollectBase
|
||||
}
|
||||
}
|
||||
}
|
||||
CurrentDevice.SetDeviceStatus(DateTimeExtensions.CurrentDateTime, 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace ThingsGateway.Plugin.OPCUA;
|
||||
public class OPCUAClient : CollectBase
|
||||
{
|
||||
internal Foundation.Adapter.OPCUA.OPCUAClient _plc = null;
|
||||
internal CollectDeviceRunTime Device;
|
||||
|
||||
private readonly OPCUAClientProperty driverPropertys = new();
|
||||
|
||||
private List<DeviceVariableRunTime> _deviceVariables = new();
|
||||
@@ -56,7 +56,7 @@ public class OPCUAClient : CollectBase
|
||||
/// <inheritdoc/>
|
||||
public override async Task BeforStartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await _plc?.ConnectAsync();
|
||||
await _plc?.ConnectAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -69,7 +69,7 @@ public class OPCUAClient : CollectBase
|
||||
{
|
||||
if (_plc.Session != null)
|
||||
{
|
||||
Device.SetDeviceStatus(DateTimeExtensions.CurrentDateTime);
|
||||
CurrentDevice.SetDeviceStatus(DateTimeExtensions.CurrentDateTime);
|
||||
}
|
||||
return _plc?.Connected == true;
|
||||
}
|
||||
@@ -189,7 +189,6 @@ public class OPCUAClient : CollectBase
|
||||
/// <inheritdoc/>
|
||||
protected override void Init(CollectDeviceRunTime device, object client = null)
|
||||
{
|
||||
Device = device;
|
||||
OPCNode opcNode = new()
|
||||
{
|
||||
OPCUrl = driverPropertys.OPCURL,
|
||||
@@ -230,14 +229,14 @@ public class OPCUAClient : CollectBase
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Device.KeepRun)
|
||||
if (!CurrentDevice.KeepRun)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogMessage.Trace($"{FoundationConst.LogMessageHeader}{ToString()} 状态变化: {Environment.NewLine} {data.variableNode.NodeId} : {data.jToken?.ToString()}");
|
||||
|
||||
if (!Device.KeepRun)
|
||||
if (!CurrentDevice.KeepRun)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public partial class OPCUAClientPage
|
||||
try
|
||||
{
|
||||
OPC.Disconnect();
|
||||
await GetOPCClient().ConnectAsync();
|
||||
await GetOPCClient().ConnectAsync(CancellationToken.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Server" Version="1.4.372.56" />
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Server" Version="1.4.372.76" />
|
||||
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.OPCUA\ThingsGateway.Foundation.Adapter.OPCUA.csproj" />
|
||||
<ProjectReference Include="..\..\Web\ThingsGateway.Components\ThingsGateway.Components.csproj">
|
||||
<Private>false</Private>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.0.24</Version>
|
||||
<Version>3.0.0.27</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<Authors>Diego</Authors>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.0.24</Version>
|
||||
<Version>3.0.0.27</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="7.0.12" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="7.0.13" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.48" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.48" />
|
||||
<PackageReference Include="Furion.Pure" Version="4.8.8.48" />
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.50" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.50" />
|
||||
<PackageReference Include="Furion.Pure" Version="4.8.8.50" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.112" />
|
||||
<PackageReference Include="SqlSugar.TDengineCore" Version="2.9.0" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
|
||||
@@ -91,8 +91,8 @@
|
||||
<MRow Class="ml-2 mr-2 d-flex" NoGutters>
|
||||
<MVirtualScroll Context="itemMessage" Height=@(Height) OverscanCount=2 ItemSize="100" Items="item">
|
||||
<ItemContent>
|
||||
<div title=@itemMessage.message class=@(itemMessage.level<Microsoft.Extensions.Logging.LogLevel.Information?MasaBlazor.Theme.Dark? " while--text ":"black--text":itemMessage.level>=Microsoft.Extensions.Logging.LogLevel.Warning?" red--text ":"green--text ") style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;">
|
||||
@itemMessage.message
|
||||
<div title=@itemMessage.message.Substring(0, Math.Min(itemMessage.message.Length, 500)) class=@(itemMessage.level<Microsoft.Extensions.Logging.LogLevel.Information?MasaBlazor.Theme.Dark? " while--text ":"black--text":itemMessage.level>=Microsoft.Extensions.Logging.LogLevel.Warning?" red--text ":"green--text ") style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;">
|
||||
@itemMessage.message.Substring(0, Math.Min(itemMessage.message.Length, 500))
|
||||
</div>
|
||||
</ItemContent>
|
||||
</MVirtualScroll>
|
||||
@@ -108,8 +108,8 @@
|
||||
<MRow Class="ml-2 mr-2 d-flex" NoGutters>
|
||||
<MVirtualScroll Context="itemMessage" Height=@(Height) OverscanCount=2 ItemSize="100" Items="item">
|
||||
<ItemContent>
|
||||
<div title=@itemMessage style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;">
|
||||
@itemMessage
|
||||
<div title=@itemMessage.Substring(0, Math.Min(itemMessage.Length, 500)) style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;">
|
||||
@itemMessage.Substring(0, Math.Min(itemMessage.Length, 500))
|
||||
</div>
|
||||
</ItemContent>
|
||||
</MVirtualScroll>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Masa.Blazor" Version="1.1.1" />
|
||||
<PackageReference Include="Masa.Blazor.SomethingSkia" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ public abstract class DriverBase : DisposableObject
|
||||
{
|
||||
if (arg3.StartsWith(FoundationConst.LogMessageHeader))
|
||||
{
|
||||
Messages.Add(DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat() + " - " + arg3.Substring(0, Math.Min(arg3.Length, 200)));
|
||||
Messages.Add(DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat() + " - " + arg3);
|
||||
|
||||
if (Messages.Count > 2500)
|
||||
{
|
||||
|
||||
@@ -351,9 +351,34 @@ public class CollectDeviceService : DbRepository<CollectDevice>, ICollectDeviceS
|
||||
|
||||
//添加设备页
|
||||
sheets.Add(ExportHelpers.CollectDeviceSheetName, devExports);
|
||||
|
||||
|
||||
|
||||
|
||||
//添加插件属性页
|
||||
foreach (var item in devicePropertys)
|
||||
{
|
||||
HashSet<string> allKeys = new HashSet<string>();
|
||||
foreach (var dict in item.Value)
|
||||
{
|
||||
foreach (var key in dict.Keys)
|
||||
{
|
||||
allKeys.Add(key);
|
||||
}
|
||||
}
|
||||
foreach (var dict in item.Value)
|
||||
{
|
||||
foreach (var key in allKeys)
|
||||
{
|
||||
if (!dict.ContainsKey(key))
|
||||
{
|
||||
// 添加缺失的键,并设置默认值
|
||||
dict.Add(key, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sheets.Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
|
||||
@@ -278,6 +278,26 @@ public class UploadDeviceService : DbRepository<UploadDevice>, IUploadDeviceServ
|
||||
//添加插件属性页
|
||||
foreach (var item in devicePropertys)
|
||||
{
|
||||
HashSet<string> allKeys = new HashSet<string>();
|
||||
foreach (var dict in item.Value)
|
||||
{
|
||||
foreach (var key in dict.Keys)
|
||||
{
|
||||
allKeys.Add(key);
|
||||
}
|
||||
}
|
||||
foreach (var dict in item.Value)
|
||||
{
|
||||
foreach (var key in allKeys)
|
||||
{
|
||||
if (!dict.ContainsKey(key))
|
||||
{
|
||||
// 添加缺失的键,并设置默认值
|
||||
dict.Add(key, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sheets.Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
|
||||
@@ -203,6 +203,7 @@ public class CollectDeviceCore
|
||||
{
|
||||
try
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested) return;
|
||||
Device.SetDeviceStatus(DateTimeExtensions.CurrentDateTime);
|
||||
|
||||
if (_device == null)
|
||||
@@ -317,6 +318,9 @@ public class CollectDeviceCore
|
||||
{
|
||||
try
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
return ThreadRunReturn.Break;
|
||||
|
||||
if (_device == null)
|
||||
{
|
||||
_logger?.LogError($"{nameof(CollectDeviceRunTime)}不能为null");
|
||||
|
||||
@@ -83,7 +83,6 @@ public class CollectDeviceThread : IAsyncDisposable
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await StopThreadAsync();
|
||||
CollectDeviceCores.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -125,7 +124,7 @@ public class CollectDeviceThread : IAsyncDisposable
|
||||
}
|
||||
try
|
||||
{
|
||||
await DeviceTask.WaitAsync(TimeSpan.FromSeconds(10));
|
||||
await DeviceTask.WaitAsync(CancellationToken.None);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
@@ -136,6 +135,7 @@ public class CollectDeviceThread : IAsyncDisposable
|
||||
foreach (var device in CollectDeviceCores)
|
||||
{
|
||||
device.Logger?.LogInformation($"{device.Device.Name}采集线程停止超时,已强制取消");
|
||||
await device.FinishActionAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -164,88 +164,102 @@ public class CollectDeviceThread : IAsyncDisposable
|
||||
var stoppingToken = StoppingTokens.Last().Token;
|
||||
DeviceTask = await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
await Task.Yield();
|
||||
var channelResult = CollectDeviceCores.FirstOrDefault().Driver.GetShareChannel();
|
||||
LoggerGroup log = CollectDeviceCores.FirstOrDefault().Driver.LogMessage;
|
||||
foreach (var device in CollectDeviceCores)
|
||||
{
|
||||
if (device.Driver == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//添加通道报文到每个设备
|
||||
var data = new EasyLogger(device.Driver.NewMessage) { LogLevel = ThingsGateway.Foundation.Core.LogLevel.Trace };
|
||||
log.AddLogger(data);
|
||||
//传入是否共享通道
|
||||
device.IsShareChannel = CollectDeviceCores.Count > 1;
|
||||
if (channelResult.IsSuccess)
|
||||
{
|
||||
await device.BeforeActionAsync(stoppingToken, channelResult.Content);
|
||||
}
|
||||
else
|
||||
{
|
||||
await device.BeforeActionAsync(stoppingToken);
|
||||
}
|
||||
}
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
try
|
||||
{
|
||||
var channelResult = CollectDeviceCores.FirstOrDefault().Driver.GetShareChannel();
|
||||
LoggerGroup log = CollectDeviceCores.FirstOrDefault().Driver.LogMessage;
|
||||
foreach (var device in CollectDeviceCores)
|
||||
{
|
||||
try
|
||||
if (device.Driver == null)
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested)
|
||||
break;
|
||||
//初始化成功才能执行
|
||||
if (device.IsInitSuccess)
|
||||
{
|
||||
//如果是共享通道类型,需要每次转换时切换适配器
|
||||
if (device.IsShareChannel) device.Driver.InitDataAdapter();
|
||||
|
||||
var result = await device.RunActionAsync(stoppingToken);
|
||||
if (result == ThreadRunReturn.None)
|
||||
{
|
||||
await Task.Delay(CycleInterval);
|
||||
}
|
||||
else if (result == ThreadRunReturn.Continue)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
else if (result == ThreadRunReturn.Break)
|
||||
{
|
||||
//当线程返回Break,直接跳出循环
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.Delay(1000, stoppingToken);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
//添加通道报文到每个设备
|
||||
var data = new EasyLogger(device.Driver.NewMessage) { LogLevel = ThingsGateway.Foundation.Core.LogLevel.Trace };
|
||||
log.AddLogger(data);
|
||||
//传入是否共享通道
|
||||
device.IsShareChannel = CollectDeviceCores.Count > 1;
|
||||
if (channelResult.IsSuccess)
|
||||
{
|
||||
|
||||
await device.BeforeActionAsync(stoppingToken, channelResult.Content);
|
||||
}
|
||||
catch (Exception ex)
|
||||
else
|
||||
{
|
||||
log.Exception(ex);
|
||||
await device.BeforeActionAsync(stoppingToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
//注意插件结束函数不能使用取消传播作为条件
|
||||
foreach (var device in CollectDeviceCores)
|
||||
{
|
||||
//如果插件还没释放,执行一次结束函数
|
||||
if (!device.Driver.DisposedValue)
|
||||
await device.FinishActionAsync();
|
||||
}
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
foreach (var device in CollectDeviceCores)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested)
|
||||
break;
|
||||
//初始化成功才能执行
|
||||
if (device.IsInitSuccess)
|
||||
{
|
||||
//如果是共享通道类型,需要每次转换时切换适配器
|
||||
if (device.IsShareChannel) device.Driver.InitDataAdapter();
|
||||
|
||||
var result = await device.RunActionAsync(stoppingToken);
|
||||
if (result == ThreadRunReturn.None)
|
||||
{
|
||||
await Task.Delay(CycleInterval);
|
||||
}
|
||||
else if (result == ThreadRunReturn.Continue)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
else if (result == ThreadRunReturn.Break)
|
||||
{
|
||||
//当线程返回Break,直接跳出循环
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.Delay(1000, stoppingToken);
|
||||
}
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Exception(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
//注意插件结束函数不能使用取消传播作为条件
|
||||
await Stop(stoppingToken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
//await Task.Yield();
|
||||
await Stop(stoppingToken);
|
||||
}
|
||||
async Task Stop(CancellationToken stoppingToken)
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
foreach (var device in CollectDeviceCores)
|
||||
{
|
||||
//如果插件还没释放,执行一次结束函数
|
||||
if (!device.Driver.DisposedValue)
|
||||
await device.FinishActionAsync();
|
||||
}
|
||||
CollectDeviceCores.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
, TaskCreationOptions.LongRunning);
|
||||
}
|
||||
|
||||
@@ -102,23 +102,28 @@ public class HardwareInfoWorker : BackgroundService
|
||||
string currentPath = Directory.GetCurrentDirectory();
|
||||
DriveInfo drive = new(Path.GetPathRoot(currentPath));
|
||||
|
||||
var remoteIpEnable = App.GetConfig<bool?>("HardwareInfo:RemoteIpEnable") ?? true;
|
||||
var enable = App.GetConfig<bool?>("HardwareInfo:Enable") ?? true;
|
||||
var timeInterval = App.GetConfig<int?>("HardwareInfo:TimeInterval") ?? 10000;
|
||||
if (timeInterval < 5000) timeInterval = 5000;
|
||||
APPInfo.DriveInfo = drive;
|
||||
APPInfo.HostName = Environment.MachineName; // 主机名称
|
||||
APPInfo.SystemOs = RuntimeInformation.OSDescription; // 操作系统
|
||||
APPInfo.OsArchitecture = Environment.OSVersion.Platform.ToString() + " " + RuntimeInformation.OSArchitecture.ToString(); // 系统架构
|
||||
APPInfo.RemoteIp = await GetIpFromOnlineAsync(); // 外网地址
|
||||
if (remoteIpEnable)
|
||||
APPInfo.RemoteIp = await GetIpFromOnlineAsync(); // 外网地址
|
||||
APPInfo.FrameworkDescription = RuntimeInformation.FrameworkDescription; // NET框架
|
||||
APPInfo.Environment = App.HostEnvironment.IsDevelopment() ? "Development" : "Production";
|
||||
APPInfo.Stage = App.HostEnvironment.IsStaging() ? "Stage" : "非Stage"; // 是否Stage环境
|
||||
APPInfo.UpdateTime = DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat();
|
||||
var enable = App.GetConfig<bool?>("HardwareInfo:Enable") ?? true;
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
APPInfo.UpdateTime = DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat();
|
||||
APPInfo.RemoteIp = await GetIpFromOnlineAsync();
|
||||
if (remoteIpEnable)
|
||||
APPInfo.RemoteIp = await GetIpFromOnlineAsync();
|
||||
if (enable)
|
||||
{
|
||||
HardwareInfo?.RefreshMemoryStatus();
|
||||
@@ -127,7 +132,7 @@ public class HardwareInfoWorker : BackgroundService
|
||||
HardwareInfo?.RefreshCPUList();
|
||||
}
|
||||
//10秒更新一次
|
||||
await Task.Delay(10000, stoppingToken);
|
||||
await Task.Delay(timeInterval, stoppingToken);
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
|
||||
@@ -70,6 +70,8 @@ public partial class UpgradeWorker : BackgroundService
|
||||
if (config == null || (!config.ConfigEnable && !config.FileEnable))
|
||||
{
|
||||
_logger.LogInformation("不启用自动更新");
|
||||
StatuString.ErrorCode = 999;
|
||||
StatuString.Message = "已退出:不启用自动更新功能";
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -166,6 +166,7 @@ public class UploadDeviceCore
|
||||
{
|
||||
try
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested) return;
|
||||
if (_device == null)
|
||||
{
|
||||
_logger?.LogError($"{nameof(UploadDeviceRunTime)}不能为null");
|
||||
@@ -265,6 +266,8 @@ public class UploadDeviceCore
|
||||
{
|
||||
try
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
return ThreadRunReturn.Break;
|
||||
if (_device == null)
|
||||
{
|
||||
_logger?.LogError($"{nameof(UploadDeviceRunTime)}不能为null");
|
||||
|
||||
@@ -72,7 +72,6 @@ public class UploadDeviceThread : IAsyncDisposable
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await StopThreadAsync();
|
||||
UploadDeviceCores.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -114,7 +113,7 @@ public class UploadDeviceThread : IAsyncDisposable
|
||||
}
|
||||
try
|
||||
{
|
||||
await DeviceTask.WaitAsync(TimeSpan.FromSeconds(10));
|
||||
await DeviceTask.WaitAsync(CancellationToken.None);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
@@ -125,6 +124,7 @@ public class UploadDeviceThread : IAsyncDisposable
|
||||
foreach (var device in UploadDeviceCores)
|
||||
{
|
||||
device.Logger?.LogInformation($"{device.Device.Name}上传线程停止超时,已强制取消");
|
||||
await device.FinishActionAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -153,77 +153,92 @@ public class UploadDeviceThread : IAsyncDisposable
|
||||
var stoppingToken = StoppingTokens.Last().Token;
|
||||
DeviceTask = await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
await Task.Yield();
|
||||
LoggerGroup log = UploadDeviceCores.FirstOrDefault().Driver.LogMessage;
|
||||
foreach (var device in UploadDeviceCores)
|
||||
{
|
||||
if (device.Driver == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//添加通道报文到每个设备
|
||||
var data = new EasyLogger(device.Driver.NewMessage) { LogLevel = ThingsGateway.Foundation.Core.LogLevel.Trace };
|
||||
log.AddLogger(data);
|
||||
await device.BeforeActionAsync(stoppingToken);
|
||||
}
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
try
|
||||
{
|
||||
//await Task.Yield();
|
||||
LoggerGroup log = UploadDeviceCores.FirstOrDefault().Driver.LogMessage;
|
||||
foreach (var device in UploadDeviceCores)
|
||||
{
|
||||
try
|
||||
if (device.Driver == null)
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested)
|
||||
break;
|
||||
//初始化成功才能执行
|
||||
if (device.IsInitSuccess)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var result = await device.RunActionAsync(stoppingToken);
|
||||
if (result == ThreadRunReturn.None)
|
||||
//添加通道报文到每个设备
|
||||
var data = new EasyLogger(device.Driver.NewMessage) { LogLevel = ThingsGateway.Foundation.Core.LogLevel.Trace };
|
||||
log.AddLogger(data);
|
||||
await device.BeforeActionAsync(stoppingToken);
|
||||
}
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
foreach (var device in UploadDeviceCores)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested)
|
||||
break;
|
||||
//初始化成功才能执行
|
||||
if (device.IsInitSuccess)
|
||||
{
|
||||
await Task.Delay(CycleInterval);
|
||||
|
||||
var result = await device.RunActionAsync(stoppingToken);
|
||||
if (result == ThreadRunReturn.None)
|
||||
{
|
||||
await Task.Delay(CycleInterval);
|
||||
}
|
||||
else if (result == ThreadRunReturn.Continue)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
else if (result == ThreadRunReturn.Break)
|
||||
{
|
||||
//当线程返回Break,直接跳出循环
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (result == ThreadRunReturn.Continue)
|
||||
else
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
else if (result == ThreadRunReturn.Break)
|
||||
{
|
||||
//当线程返回Break,直接跳出循环
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
|
||||
}
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Exception(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Exception(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
//注意插件结束函数不能使用取消传播作为条件
|
||||
await Stop(stoppingToken);
|
||||
}
|
||||
//注意插件结束函数不能使用取消传播作为条件
|
||||
foreach (var device in UploadDeviceCores)
|
||||
finally
|
||||
{
|
||||
//如果插件还没释放,执行一次结束函数
|
||||
if (!device.Driver.DisposedValue)
|
||||
await device.FinishActionAsync();
|
||||
//await Task.Yield();
|
||||
await Stop(stoppingToken);
|
||||
}
|
||||
async Task Stop(CancellationToken stoppingToken)
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
foreach (var device in UploadDeviceCores)
|
||||
{
|
||||
//如果插件还没释放,执行一次结束函数
|
||||
if (!device.Driver.DisposedValue)
|
||||
await device.FinishActionAsync();
|
||||
}
|
||||
UploadDeviceCores.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
, TaskCreationOptions.LongRunning);
|
||||
|
||||
|
||||
@@ -42,60 +42,61 @@
|
||||
<MTab Value="3">
|
||||
其他服务状态
|
||||
</MTab>
|
||||
<MButton Class="position-button" Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicerestart")) Color="red" Dark Fab XSmall Loading=isAllRestart OnClick="AllRestartAsync">
|
||||
<MIcon> mdi-restart </MIcon>
|
||||
</MButton>
|
||||
</MTabs>
|
||||
<MTabsItems Value="tab">
|
||||
<MTabItem Value="1">
|
||||
@if (tab == 1)
|
||||
<MButton Class="position-button" Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicerestart")) Color="red" Dark Fab XSmall Loading=isAllRestart OnClick="AllRestartAsync">
|
||||
<MIcon> mdi-restart </MIcon>
|
||||
</MButton>
|
||||
</MTabs>
|
||||
<MTabsItems Value="tab">
|
||||
<MTabItem Value="1">
|
||||
@if (tab == 1)
|
||||
{
|
||||
<MRow NoGutters>
|
||||
<MCol Md=2 Cols="12">
|
||||
<MCol Md=2 Cols="12">
|
||||
|
||||
<MCard Class="ma-2" Style=@($"height: calc(100vh - {BlazorResourceConst.DefaultHeight + 80}px );")>
|
||||
<MCardTitle>
|
||||
<MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="mx-2 my-1" @bind-Value="_collectDeviceGroupSearchName"
|
||||
<MCard Class="ma-2" Style=@($"height: calc(100vh - {BlazorResourceConst.DefaultHeight + 80}px );")>
|
||||
<MCardTitle>
|
||||
<MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="mx-2 my-1" @bind-Value="_collectDeviceGroupSearchName"
|
||||
Outlined Label=@typeof(CollectDevice).GetDescription(nameof(CollectDevice.DeviceGroup)) />
|
||||
</MCardTitle>
|
||||
</MCardTitle>
|
||||
|
||||
<MTreeview Style=@($"height: calc(100vh - {BlazorResourceConst.DefaultHeight + 240}px; overflow-y:auto)") Dense TItem="string" TKey="string" ActiveChanged=@(async a=>
|
||||
<MTreeview Style=@($"height: calc(100vh - {BlazorResourceConst.DefaultHeight + 240}px; overflow-y:auto)") Dense TItem="string" TKey="string" ActiveChanged=@(async a=>
|
||||
{
|
||||
if(_collectDeviceGroup!=a.FirstOrDefault())
|
||||
{
|
||||
_collectDeviceGroup=a.FirstOrDefault(); CollectDeviceQuery();
|
||||
}
|
||||
} )
|
||||
Items="_collectDeviceGroups" ItemText="r=>r" ItemChildren="r=>null"
|
||||
Search="@_collectDeviceGroupSearchName"
|
||||
Items="_collectDeviceGroups" ItemText="r=>r" ItemChildren="r=>null"
|
||||
Search="@_collectDeviceGroupSearchName"
|
||||
Activatable ItemKey=@(r=>r)>
|
||||
<LabelContent>
|
||||
<span title=@context.Item>
|
||||
@context.Item
|
||||
</span>
|
||||
</LabelContent>
|
||||
</MTreeview>
|
||||
</MCard>
|
||||
</MCol>
|
||||
<MCol Md=3 Cols="12">
|
||||
<MCard Height=@($"calc(100vh - {BlazorResourceConst.DefaultHeight + 80}px; )") Style="overflow-y:auto;" Flat Class="ml-2 my-4">
|
||||
<LabelContent>
|
||||
<span title=@context.Item>
|
||||
@context.Item
|
||||
</span>
|
||||
</LabelContent>
|
||||
</MTreeview>
|
||||
</MCard>
|
||||
</MCol>
|
||||
<MCol Md=3 Cols="12">
|
||||
<MCard Height=@($"calc(100vh - {BlazorResourceConst.DefaultHeight + 80}px; )") Style="overflow-y:auto;" Flat Class="ml-2 my-4">
|
||||
|
||||
<MVirtualScroll Context="item" Height=@($"calc(100vh - {BlazorResourceConst.DefaultHeight+100}px)") OverscanCount=2 ItemSize="60" Items="_collectDeviceCores">
|
||||
<MVirtualScroll Context="item" Height=@($"calc(100vh - {BlazorResourceConst.DefaultHeight+100}px)") OverscanCount=2 ItemSize="60" Items="_collectDeviceCores">
|
||||
|
||||
<ItemContent>
|
||||
@if (item.Device != null)
|
||||
<ItemContent>
|
||||
@if (item.Device != null)
|
||||
{
|
||||
|
||||
<MListItem OnClick=@(()=>CollectDeviceInfo(item))>
|
||||
<MListItemContent>
|
||||
<MListItemTitle>
|
||||
<MLabel Class=@((item.Device?.DeviceStatus==DeviceStatusEnum.OnLine?"green--text":"red--text")+$" text-h6")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between" title=@item.Device?.Name>
|
||||
<span>@item.Device?.Name</span>
|
||||
<span style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;" class="text-caption">@(item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " " + typeof(DeviceStatusEnum).GetDescription(item.Device?.DeviceStatus.ToString()))</span>
|
||||
</div>
|
||||
</MLabel>
|
||||
</MListItemTitle>
|
||||
<MLabel Class=@((item.Device?.DeviceStatus==DeviceStatusEnum.OnLine?"green--text":"red--text")+$" text-h6")>
|
||||
<div class="mt-1 d-flex align-start justify-start" style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;" title=@item.Device?.Name>
|
||||
<span>@item.Device?.Name</span>
|
||||
|
||||
</div>
|
||||
<div style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;" class="text-caption">
|
||||
@(item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " " + typeof(DeviceStatusEnum).GetDescription(item.Device?.DeviceStatus.ToString()))
|
||||
</div>
|
||||
</MLabel>
|
||||
</MListItemContent>
|
||||
|
||||
</MListItem>
|
||||
@@ -113,39 +114,39 @@
|
||||
</MCol>
|
||||
<MCol Md=7 Cols="12">
|
||||
<MCard Style=@($"height: calc(100vh - {BlazorResourceConst.DefaultHeight + 80}px); overflow:auto)") Flat Elevation="0">
|
||||
@if (collectDeviceInfoItem != null && collectDeviceInfoItem?.Device != null)
|
||||
@if (collectDeviceInfoItem != null && collectDeviceInfoItem?.Device != null)
|
||||
{
|
||||
var item = collectDeviceInfoItem;
|
||||
<MCard Style="height:100px;overflow:auto;" Flat Class="ml-4 my-4 ma-2" Elevation="0">
|
||||
|
||||
<MCardActions>
|
||||
<div class="mr-12"></div>
|
||||
<MCardActions>
|
||||
<div class="mr-12"></div>
|
||||
|
||||
<MLabel Class=@((item.Device?.DeviceStatus==DeviceStatusEnum.OnLine?"green--text":"red--text")+$" text-h6")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="mx-3">@item.Device?.Name</span>
|
||||
<span style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;" class="text-caption mx-3">@(item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " " + typeof(DeviceStatusEnum).GetDescription(item.Device?.DeviceStatus.ToString()))</span>
|
||||
<MLabel Class=@((item.Device?.DeviceStatus==DeviceStatusEnum.OnLine?"green--text":"red--text")+$" text-h6")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="mx-3">@item.Device?.Name</span>
|
||||
<span style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;" class="text-caption mx-3">@(item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " " + typeof(DeviceStatusEnum).GetDescription(item.Device?.DeviceStatus.ToString()))</span>
|
||||
</div>
|
||||
</MLabel>
|
||||
|
||||
<MSpacer></MSpacer>
|
||||
<MTooltip Bottom Context="tip">
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasPageWithRole("/gatewayruntime/devicevariable")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small Loading=isRestart
|
||||
OnClick=@(()=>NavigationManager.NavigateTo("/gatewayruntime/devicevariable?devicename="+item.Device?.Name))>
|
||||
<MIcon>mdi-information-outline</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
<span>相关变量</span>
|
||||
</ChildContent>
|
||||
</MTooltip>
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasPageWithRole("/gatewayruntime/devicevariable")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small Loading=isRestart
|
||||
OnClick=@(()=>NavigationManager.NavigateTo("/gatewayruntime/devicevariable?devicename="+item.Device?.Name))>
|
||||
<MIcon>mdi-information-outline</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
<span>相关变量</span>
|
||||
</ChildContent>
|
||||
</MTooltip>
|
||||
|
||||
|
||||
<MTooltip Bottom Context="tip">
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small OnClick=@(()=>ConfigAsync(item.DeviceId,!item.Device?.KeepRun))>
|
||||
<MIcon>@(item.Device?.KeepRun == true ? "mdi-pause" : "mdi-play")</MIcon>
|
||||
<MTooltip Bottom Context="tip">
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small OnClick=@(()=>ConfigAsync(item.DeviceId,!item.Device?.KeepRun))>
|
||||
<MIcon>@(item.Device?.KeepRun == true ? "mdi-pause" : "mdi-play")</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
@@ -154,62 +155,62 @@
|
||||
</MTooltip>
|
||||
|
||||
<MTooltip Bottom Context="tip">
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicerestart")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small Loading=isRestart OnClick=@(()=>RestartAsync(item.DeviceId))>
|
||||
<MIcon>mdi-restart</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
<span>重启</span>
|
||||
</ChildContent>
|
||||
</MTooltip>
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicerestart")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small Loading=isRestart OnClick=@(()=>RestartAsync(item.DeviceId))>
|
||||
<MIcon>mdi-restart</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
<span>重启</span>
|
||||
</ChildContent>
|
||||
</MTooltip>
|
||||
|
||||
</MCardActions>
|
||||
</MCardActions>
|
||||
|
||||
|
||||
</MCard>
|
||||
</MCard>
|
||||
|
||||
<MCard Style="height:200px;overflow:auto;" Flat Class="ml-4 my-4 ma-2" Elevation="0">
|
||||
|
||||
<MSubheader>
|
||||
运行状态
|
||||
</MSubheader>
|
||||
<MRow Class="ml-2 mr-2 d-flex" NoGutters>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.ActiveTime)</span>
|
||||
<span class="text-caption">@item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.SourceVariableCount)</span>
|
||||
<span class="text-caption">@item.Device?.SourceVariableCount</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.DeviceVariableCount)</span>
|
||||
<span class="text-caption">@item.Device?.DeviceVariableCount</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.MethodVariableCount)</span>
|
||||
<span class="text-caption">@item.Device?.MethodVariableCount</span>
|
||||
</MCol>
|
||||
<MCol Md=12 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.LastErrorMessage)</span>
|
||||
<span class="text-caption red--text">@item.Device?.LastErrorMessage</span>
|
||||
</MCol>
|
||||
</MRow>
|
||||
<MSubheader>
|
||||
运行状态
|
||||
</MSubheader>
|
||||
<MRow Class="ml-2 mr-2 d-flex" NoGutters>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.ActiveTime)</span>
|
||||
<span class="text-caption">@item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.SourceVariableCount)</span>
|
||||
<span class="text-caption">@item.Device?.SourceVariableCount</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.DeviceVariableCount)</span>
|
||||
<span class="text-caption">@item.Device?.DeviceVariableCount</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.MethodVariableCount)</span>
|
||||
<span class="text-caption">@item.Device?.MethodVariableCount</span>
|
||||
</MCol>
|
||||
<MCol Md=12 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.LastErrorMessage)</span>
|
||||
<span class="text-caption red--text">@item.Device?.LastErrorMessage</span>
|
||||
</MCol>
|
||||
</MRow>
|
||||
|
||||
<MSubheader>
|
||||
配置信息
|
||||
</MSubheader>
|
||||
<MRow Class="ml-2 mr-2 d-flex" NoGutters>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.PluginName)</span>
|
||||
<span class="text-caption">@item.Device?.PluginName</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.IsLogOut)</span>
|
||||
<span class="text-caption">@item.Device?.IsLogOut</span>
|
||||
</MCol>
|
||||
@foreach (var property in item.Device?.DevicePropertys ?? new())
|
||||
<MSubheader>
|
||||
配置信息
|
||||
</MSubheader>
|
||||
<MRow Class="ml-2 mr-2 d-flex" NoGutters>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.PluginName)</span>
|
||||
<span class="text-caption">@item.Device?.PluginName</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.IsLogOut)</span>
|
||||
<span class="text-caption">@item.Device?.IsLogOut</span>
|
||||
</MCol>
|
||||
@foreach (var property in item.Device?.DevicePropertys ?? new())
|
||||
{
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@property.Description</span>
|
||||
@@ -225,7 +226,7 @@
|
||||
}
|
||||
|
||||
<MCard Flat Class="ml-4">
|
||||
@if (collectDeviceInfoItem != null && collectDeviceInfoItem?.Device != null)
|
||||
@if (collectDeviceInfoItem != null && collectDeviceInfoItem?.Device != null)
|
||||
{
|
||||
ICollection<string> item = null;
|
||||
if (collectDeviceInfoItem.Driver != null)
|
||||
@@ -240,15 +241,15 @@
|
||||
<ConsoleTxt MessageStrings="item" Height=@($"calc(100vh - {BlazorResourceConst.DefaultHeight+480}px)")>
|
||||
|
||||
<MTooltip Bottom Context="tip">
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small
|
||||
OnClick=@(()=>
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small
|
||||
OnClick=@(()=>
|
||||
{
|
||||
if(collectDeviceInfoItem.Driver!=null)
|
||||
collectDeviceInfoItem.Driver.IsSaveLog=! collectDeviceInfoItem.Driver.IsSaveLog;
|
||||
}
|
||||
)>
|
||||
<MIcon>@((collectDeviceInfoItem.Driver?.IsSaveLog == true) ? "mdi-pause" : "mdi-play")</MIcon>
|
||||
<MIcon>@((collectDeviceInfoItem.Driver?.IsSaveLog == true) ? "mdi-pause" : "mdi-play")</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
@@ -277,44 +278,46 @@
|
||||
<MCardTitle>
|
||||
<MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="mx-2 my-1" @bind-Value="_uploadDeviceGroupSearchName"
|
||||
Outlined Label=@typeof(UploadDevice).GetDescription(nameof(UploadDevice.DeviceGroup)) />
|
||||
</MCardTitle>
|
||||
<MTreeview Style=@($"height: calc(100vh - {BlazorResourceConst.DefaultHeight+240}px);overflow-y:auto") Dense TItem="string" TKey="string" ActiveChanged=@(async a=>
|
||||
</MCardTitle>
|
||||
<MTreeview Style=@($"height: calc(100vh - {BlazorResourceConst.DefaultHeight+240}px);overflow-y:auto") Dense TItem="string" TKey="string" ActiveChanged=@(async a=>
|
||||
{
|
||||
if(_uploadDeviceGroup!=a.FirstOrDefault())
|
||||
{
|
||||
_uploadDeviceGroup=a.FirstOrDefault(); UploadDeviceQuery();
|
||||
}
|
||||
} )
|
||||
Items="_uploadDeviceGroups" ItemText="r=>r" ItemChildren="r=>null"
|
||||
Search="@_uploadDeviceGroupSearchName"
|
||||
Items="_uploadDeviceGroups" ItemText="r=>r" ItemChildren="r=>null"
|
||||
Search="@_uploadDeviceGroupSearchName"
|
||||
Activatable ItemKey=@(r=>r)>
|
||||
<LabelContent>
|
||||
<span title=@context.Item>
|
||||
@context.Item
|
||||
</span>
|
||||
</LabelContent>
|
||||
</MTreeview>
|
||||
</MCard>
|
||||
</MCol>
|
||||
<MCol Md=3 Cols="12">
|
||||
<MCard Height=@($"calc(100vh - {BlazorResourceConst.DefaultHeight+80}px)") Style="overflow-y:auto;" Flat Class="ml-2 my-4">
|
||||
<LabelContent>
|
||||
<span title=@context.Item>
|
||||
@context.Item
|
||||
</span>
|
||||
</LabelContent>
|
||||
</MTreeview>
|
||||
</MCard>
|
||||
</MCol>
|
||||
<MCol Md=3 Cols="12">
|
||||
<MCard Height=@($"calc(100vh - {BlazorResourceConst.DefaultHeight+80}px)") Style="overflow-y:auto;" Flat Class="ml-2 my-4">
|
||||
|
||||
<MVirtualScroll Context="item" Height=@($"calc(100vh - {BlazorResourceConst.DefaultHeight+100}px)") OverscanCount=2 ItemSize="60" Items="_uploadDeviceCores">
|
||||
<MVirtualScroll Context="item" Height=@($"calc(100vh - {BlazorResourceConst.DefaultHeight+100}px)") OverscanCount=2 ItemSize="60" Items="_uploadDeviceCores">
|
||||
|
||||
<ItemContent>
|
||||
@if (item.Device != null)
|
||||
<ItemContent>
|
||||
@if (item.Device != null)
|
||||
{
|
||||
|
||||
<MListItem OnClick=@(()=>UploadDeviceInfo(item))>
|
||||
<MListItemContent>
|
||||
<MListItemTitle>
|
||||
<MLabel Class=@((item.Device?.DeviceStatus==DeviceStatusEnum.OnLine?"green--text":"red--text")+$" text-h6")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between" title=@item.Device?.Name>
|
||||
<span>@item.Device?.Name</span>
|
||||
<span style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;" class="text-caption">@(item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " " + typeof(DeviceStatusEnum).GetDescription(item.Device?.DeviceStatus.ToString()))</span>
|
||||
</div>
|
||||
</MLabel>
|
||||
</MListItemTitle>
|
||||
<MLabel Class=@((item.Device?.DeviceStatus==DeviceStatusEnum.OnLine?"green--text":"red--text")+$" text-h6")>
|
||||
<div class="mt-1 d-flex align-start justify-start" style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;" title=@item.Device?.Name>
|
||||
<span>@item.Device?.Name</span>
|
||||
|
||||
</div>
|
||||
<div style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;" class="text-caption">
|
||||
@(item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " " + typeof(DeviceStatusEnum).GetDescription(item.Device?.DeviceStatus.ToString()))
|
||||
</div>
|
||||
</MLabel>
|
||||
|
||||
</MListItemContent>
|
||||
|
||||
</MListItem>
|
||||
@@ -332,39 +335,39 @@
|
||||
</MCol>
|
||||
<MCol Md=7 Cols="12">
|
||||
<MCard Style=@($"height: calc(100vh - {BlazorResourceConst.DefaultHeight + 80}px); overflow:auto)") Flat Elevation="0">
|
||||
@if (uploadDeviceInfoItem != null && uploadDeviceInfoItem?.Device != null)
|
||||
@if (uploadDeviceInfoItem != null && uploadDeviceInfoItem?.Device != null)
|
||||
{
|
||||
var item = uploadDeviceInfoItem;
|
||||
<MCard Style="height:100px;overflow:auto;" Flat Class="ml-4 my-4 ma-2" Elevation="0">
|
||||
|
||||
<MCardActions>
|
||||
<div class="mr-12"></div>
|
||||
<MCardActions>
|
||||
<div class="mr-12"></div>
|
||||
|
||||
<MLabel Class=@((item.Device?.DeviceStatus==DeviceStatusEnum.OnLine?"green--text":"red--text")+$" text-h6")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="mx-3">@item.Device?.Name</span>
|
||||
<span style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;" class="text-caption mx-3">@(item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " " + typeof(DeviceStatusEnum).GetDescription(item.Device?.DeviceStatus.ToString()))</span>
|
||||
<MLabel Class=@((item.Device?.DeviceStatus==DeviceStatusEnum.OnLine?"green--text":"red--text")+$" text-h6")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="mx-3">@item.Device?.Name</span>
|
||||
<span style="white-space: nowrap !important;overflow: hidden !important; text-overflow: ellipsis !important;" class="text-caption mx-3">@(item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " " + typeof(DeviceStatusEnum).GetDescription(item.Device?.DeviceStatus.ToString()))</span>
|
||||
</div>
|
||||
</MLabel>
|
||||
|
||||
<MSpacer></MSpacer>
|
||||
<MTooltip Bottom Context="tip">
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasPageWithRole("/gatewayruntime/devicevariable")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small Loading=isRestart
|
||||
OnClick=@(()=>NavigationManager.NavigateTo("/gatewayruntime/devicevariable?uploaddevicename="+item.Device?.Name))>
|
||||
<MIcon>mdi-information-outline</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
<span>相关变量</span>
|
||||
</ChildContent>
|
||||
</MTooltip>
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasPageWithRole("/gatewayruntime/devicevariable")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small Loading=isRestart
|
||||
OnClick=@(()=>NavigationManager.NavigateTo("/gatewayruntime/devicevariable?uploaddevicename="+item.Device?.Name))>
|
||||
<MIcon>mdi-information-outline</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
<span>相关变量</span>
|
||||
</ChildContent>
|
||||
</MTooltip>
|
||||
|
||||
|
||||
<MTooltip Bottom Context="tip">
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small OnClick=@(()=>UpConfigAsync(item.DeviceId,!item.Device?.KeepRun))>
|
||||
<MIcon>@(item.Device?.KeepRun == true ? "mdi-pause" : "mdi-play")</MIcon>
|
||||
<MTooltip Bottom Context="tip">
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small OnClick=@(()=>UpConfigAsync(item.DeviceId,!item.Device?.KeepRun))>
|
||||
<MIcon>@(item.Device?.KeepRun == true ? "mdi-pause" : "mdi-play")</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
@@ -376,56 +379,56 @@
|
||||
|
||||
|
||||
<MTooltip Bottom Context="tip">
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicerestart")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small Loading=isRestart OnClick=@(()=> UpRestartAsync(item.DeviceId))>
|
||||
<MIcon>mdi-restart</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
<span>重启</span>
|
||||
</ChildContent>
|
||||
</MTooltip>
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicerestart")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small Loading=isRestart OnClick=@(()=> UpRestartAsync(item.DeviceId))>
|
||||
<MIcon>mdi-restart</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
<span>重启</span>
|
||||
</ChildContent>
|
||||
</MTooltip>
|
||||
|
||||
</MCardActions>
|
||||
</MCardActions>
|
||||
|
||||
|
||||
|
||||
|
||||
</MCard>
|
||||
</MCard>
|
||||
<MCard Style="height:200px;overflow:auto;" Flat Class="ml-4 my-4 ma-2" Elevation="0">
|
||||
|
||||
|
||||
<MSubheader>
|
||||
运行状态
|
||||
</MSubheader>
|
||||
<MRow Class="ml-2 mr-2 d-flex" NoGutters>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.ActiveTime)</span>
|
||||
<span class="text-caption">@item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.UploadVariableCount)</span>
|
||||
<span class="text-caption">@item.Device?.UploadVariableCount</span>
|
||||
</MCol>
|
||||
<MCol Md=12 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.LastErrorMessage)</span>
|
||||
<span class="text-caption red--text">@item.Device?.LastErrorMessage</span>
|
||||
</MCol>
|
||||
</MRow>
|
||||
<MSubheader>
|
||||
运行状态
|
||||
</MSubheader>
|
||||
<MRow Class="ml-2 mr-2 d-flex" NoGutters>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.ActiveTime)</span>
|
||||
<span class="text-caption">@item.Device?.ActiveTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.UploadVariableCount)</span>
|
||||
<span class="text-caption">@item.Device?.UploadVariableCount</span>
|
||||
</MCol>
|
||||
<MCol Md=12 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.LastErrorMessage)</span>
|
||||
<span class="text-caption red--text">@item.Device?.LastErrorMessage</span>
|
||||
</MCol>
|
||||
</MRow>
|
||||
|
||||
<MSubheader>
|
||||
配置信息
|
||||
</MSubheader>
|
||||
<MRow Class="ml-2 mr-2 d-flex" NoGutters>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.PluginName)</span>
|
||||
<span class="text-caption">@item.Device?.PluginName</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.IsLogOut)</span>
|
||||
<span class="text-caption">@item.Device?.IsLogOut</span>
|
||||
</MCol>
|
||||
@foreach (var property in item.Device?.DevicePropertys ?? new())
|
||||
<MSubheader>
|
||||
配置信息
|
||||
</MSubheader>
|
||||
<MRow Class="ml-2 mr-2 d-flex" NoGutters>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.PluginName)</span>
|
||||
<span class="text-caption">@item.Device?.PluginName</span>
|
||||
</MCol>
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@item.Device?.Description(a=>a.IsLogOut)</span>
|
||||
<span class="text-caption">@item.Device?.IsLogOut</span>
|
||||
</MCol>
|
||||
@foreach (var property in item.Device?.DevicePropertys ?? new())
|
||||
{
|
||||
<MCol Md=6 Cols="12" Class="px-4 mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text">@property.Description</span>
|
||||
@@ -440,14 +443,14 @@
|
||||
}
|
||||
|
||||
<MCard Flat Class="ml-4">
|
||||
@if (uploadDeviceInfoItem != null && uploadDeviceInfoItem?.Device != null)
|
||||
@if (uploadDeviceInfoItem != null && uploadDeviceInfoItem?.Device != null)
|
||||
{
|
||||
|
||||
|
||||
ICollection<string> item = null;
|
||||
if (uploadDeviceInfoItem.Driver != null)
|
||||
{
|
||||
item = uploadDeviceInfoItem.Driver?.Messages ?? new();
|
||||
item = uploadDeviceInfoItem.Driver?.Messages;
|
||||
}
|
||||
if (item == null)
|
||||
{
|
||||
@@ -456,15 +459,15 @@
|
||||
<ConsoleTxt MessageStrings="item" Height=@($"calc(100vh - {BlazorResourceConst.DefaultHeight+480}px)")>
|
||||
|
||||
<MTooltip Bottom Context="tip">
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small
|
||||
OnClick=@(()=>
|
||||
<ActivatorContent>
|
||||
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small
|
||||
OnClick=@(()=>
|
||||
{
|
||||
if(uploadDeviceInfoItem.Driver!=null)
|
||||
uploadDeviceInfoItem.Driver.IsSaveLog=! uploadDeviceInfoItem.Driver.IsSaveLog;
|
||||
}
|
||||
)>
|
||||
<MIcon>@((uploadDeviceInfoItem.Driver?.IsSaveLog == true) ? "mdi-pause" : "mdi-play")</MIcon>
|
||||
<MIcon>@((uploadDeviceInfoItem.Driver?.IsSaveLog == true) ? "mdi-pause" : "mdi-play")</MIcon>
|
||||
</MButton>
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
@@ -489,46 +492,46 @@
|
||||
@if (tab == 3)
|
||||
{
|
||||
<MRow NoGutters>
|
||||
<MCard Class="ml-2 my-3" Style="width:100%" Elevation="1">
|
||||
<MCardSubtitle Class=@((AlarmHostService.StatuString.IsSuccess?"green--text":"red--text")+$" text-subtitle-2")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span>历史报警服务状态</span>
|
||||
<span class="text-caption">@AlarmHostService.StatuString.Message</span>
|
||||
</div>
|
||||
</MCardSubtitle>
|
||||
</MCard>
|
||||
</MRow>
|
||||
<MCard Class="ml-2 my-3" Style="width:100%" Elevation="1">
|
||||
<MCardSubtitle Class=@((AlarmHostService.StatuString.IsSuccess?"green--text":"red--text")+$" text-subtitle-2")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span>历史报警服务状态</span>
|
||||
<span class="text-caption">@AlarmHostService.StatuString.Message</span>
|
||||
</div>
|
||||
</MCardSubtitle>
|
||||
</MCard>
|
||||
</MRow>
|
||||
<MRow NoGutters>
|
||||
<MCard Class="ml-2 my-3" Style="width:100%" Elevation="1">
|
||||
<MCardSubtitle Class=@((HistoryValueHostService.StatuString.IsSuccess?"green--text":"red--text")+$" text-subtitle-2")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span>历史数据服务状态</span>
|
||||
<span class="text-caption">@HistoryValueHostService.StatuString.Message</span>
|
||||
</div>
|
||||
</MCardSubtitle>
|
||||
</MCard>
|
||||
</MRow>
|
||||
<MCard Class="ml-2 my-3" Style="width:100%" Elevation="1">
|
||||
<MCardSubtitle Class=@((HistoryValueHostService.StatuString.IsSuccess?"green--text":"red--text")+$" text-subtitle-2")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span>历史数据服务状态</span>
|
||||
<span class="text-caption">@HistoryValueHostService.StatuString.Message</span>
|
||||
</div>
|
||||
</MCardSubtitle>
|
||||
</MCard>
|
||||
</MRow>
|
||||
<MRow NoGutters>
|
||||
<MCard Class="ml-2 my-3" Style="width:100%" Elevation="1">
|
||||
<MCardSubtitle Class=@((MemoryVariableWorker.StatuString.IsSuccess?"green--text":"red--text")+$" text-subtitle-2")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span>中间变量计算服务状态</span>
|
||||
<span class="text-caption">@MemoryVariableWorker.StatuString.Message</span>
|
||||
</div>
|
||||
</MCardSubtitle>
|
||||
</MCard>
|
||||
</MRow>
|
||||
|
||||
<MCard Class="ml-2 my-3" Style="width:100%" Elevation="1">
|
||||
<MCardSubtitle Class=@((MemoryVariableWorker.StatuString.IsSuccess?"green--text":"red--text")+$" text-subtitle-2")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span>中间变量计算服务状态</span>
|
||||
<span class="text-caption">@MemoryVariableWorker.StatuString.Message</span>
|
||||
</div>
|
||||
</MCardSubtitle>
|
||||
</MCard>
|
||||
</MRow>
|
||||
|
||||
<MRow NoGutters>
|
||||
<MCard Class="ml-2 my-3" Style="width:100%" Elevation="1">
|
||||
<MCard Class="ml-2 my-3" Style="width:100%" Elevation="1">
|
||||
<MCardSubtitle Class=@((UpgradeWorker.StatuString.IsSuccess?"green--text":"red--text")+$" text-subtitle-2")>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span>自动更新服务状态</span>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span>自动更新服务状态</span>
|
||||
<span class="text-caption">@UpgradeWorker.StatuString.Message</span>
|
||||
</div>
|
||||
</MCardSubtitle>
|
||||
</MCard>
|
||||
</MRow>
|
||||
</div>
|
||||
</MCardSubtitle>
|
||||
</MCard>
|
||||
</MRow>
|
||||
}
|
||||
|
||||
</MTabItem>
|
||||
|
||||
@@ -89,30 +89,37 @@
|
||||
|
||||
<MRow NoGutters>
|
||||
<MCol Md=11 Cols="12" Class="ml-2 mr-2 d-flex justify-space-around">
|
||||
@foreach (var item in HardwareInfoWorker.HardwareInfo.CpuList)
|
||||
@{
|
||||
var hardwareInfo = HardwareInfoWorker.HardwareInfo;
|
||||
}
|
||||
@if (hardwareInfo != null)
|
||||
{
|
||||
|
||||
<div class="ml-2 mr-2 d-flex flex-column align-center">
|
||||
<MProgressCircular Value=@(item.PercentProcessorTime<=100?item.PercentProcessorTime:100) Size="200" Width="12" Class="ma-4" Color=@(item.PercentProcessorTime>70?"red":"green")>
|
||||
<div class="ml-2 mr-2 d-flex flex-column align-center">
|
||||
@((item.PercentProcessorTime).ToString("F0") + " %")
|
||||
@foreach (var item in HardwareInfoWorker.HardwareInfo.CpuList)
|
||||
{
|
||||
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text mx-2">内核</span>
|
||||
<span class="text-caption">@item.NumberOfCores</span>
|
||||
</div>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text mx-2">逻辑处理器</span>
|
||||
<span class="text-caption">@item.NumberOfLogicalProcessors</span>
|
||||
<div class="ml-2 mr-2 d-flex flex-column align-center">
|
||||
<MProgressCircular Value=@(item.PercentProcessorTime<=100?item.PercentProcessorTime:100) Size="200" Width="12" Class="ma-4" Color=@(item.PercentProcessorTime>70?"red":"green")>
|
||||
<div class="ml-2 mr-2 d-flex flex-column align-center">
|
||||
@((item.PercentProcessorTime).ToString("F0") + " %")
|
||||
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text mx-2">内核</span>
|
||||
<span class="text-caption">@item.NumberOfCores</span>
|
||||
</div>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text mx-2">逻辑处理器</span>
|
||||
<span class="text-caption">@item.NumberOfLogicalProcessors</span>
|
||||
</div>
|
||||
</div>
|
||||
</MProgressCircular>
|
||||
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-caption">@item.Name</span>
|
||||
</div>
|
||||
</MProgressCircular>
|
||||
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-caption">@item.Name</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</MCol>
|
||||
@@ -135,35 +142,39 @@
|
||||
<MRow NoGutters>
|
||||
<MCol Md=5 Cols="12" Class="ml-2 mr-2 d-flex justify-space-around">
|
||||
@{
|
||||
var memoryStatus = HardwareInfoWorker.HardwareInfo.MemoryStatus;
|
||||
var memoryStatus = HardwareInfoWorker.HardwareInfo?.MemoryStatus;
|
||||
}
|
||||
<div class="ml-2 mr-2 d-flex flex-column align-center">
|
||||
<MProgressCircular Value=@(memoryStatus.TotalPhysical>memoryStatus.AvailablePhysical?100 - (memoryStatus.AvailablePhysical * 100.00 / memoryStatus.TotalPhysical):100)
|
||||
Size="200" Width="12" Class="ma-4" Color=@(memoryStatus.AvailablePhysical * 100.00 / memoryStatus.TotalPhysical<20?"red":"green")>
|
||||
<div class="ml-2 mr-2 d-flex flex-column align-center">
|
||||
@((100 - (memoryStatus.AvailablePhysical * 100.00 / memoryStatus.TotalPhysical)).ToString("F2") + " %")
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-caption grey--text mx-2">可用</span>
|
||||
<span class="text-caption ">@((memoryStatus.AvailablePhysical / 1024.00 / 1024 / 1024).ToString("F2") + " GB")</span>
|
||||
@if (memoryStatus != null)
|
||||
{
|
||||
<div class="ml-2 mr-2 d-flex flex-column align-center">
|
||||
<MProgressCircular Value=@(memoryStatus.TotalPhysical>memoryStatus.AvailablePhysical?100 - (memoryStatus.AvailablePhysical * 100.00 / memoryStatus.TotalPhysical):100)
|
||||
Size="200" Width="12" Class="ma-4" Color=@(memoryStatus.AvailablePhysical * 100.00 / memoryStatus.TotalPhysical<20?"red":"green")>
|
||||
<div class="ml-2 mr-2 d-flex flex-column align-center">
|
||||
@((100 - (memoryStatus.AvailablePhysical * 100.00 / memoryStatus.TotalPhysical)).ToString("F2") + " %")
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-caption grey--text mx-2">可用</span>
|
||||
<span class="text-caption ">@((memoryStatus.AvailablePhysical / 1024.00 / 1024 / 1024).ToString("F2") + " GB")</span>
|
||||
</div>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-caption grey--text mx-2">总</span>
|
||||
<span class="text-caption ">@((memoryStatus.TotalPhysical / 1024.00 / 1024 / 1024).ToString("F2") + " GB")</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-caption grey--text mx-2">总</span>
|
||||
<span class="text-caption ">@((memoryStatus.TotalPhysical / 1024.00 / 1024 / 1024).ToString("F2") + " GB")</span>
|
||||
</div>
|
||||
</div>
|
||||
</MProgressCircular>
|
||||
</MProgressCircular>
|
||||
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-caption">内存占用率</span>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-caption">内存占用率</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
</MCol>
|
||||
|
||||
<MDivider Class="mx-2" Vertical></MDivider>
|
||||
|
||||
|
||||
<MCol Md=4 Cols="12" Class="pl-2 pr-2 d-flex justify-space-around">
|
||||
@if (HardwareInfoWorker.APPInfo.DriveInfo != null)
|
||||
<MCol Md=4 Cols="12" Class="pl-2 pr-2 d-flex justify-space-around">
|
||||
@if (HardwareInfoWorker.APPInfo.DriveInfo != null)
|
||||
{
|
||||
var drive = HardwareInfoWorker.APPInfo.DriveInfo;
|
||||
<div class="ml-2 mr-2 d-flex flex-column align-center">
|
||||
@@ -207,46 +218,52 @@
|
||||
</MCardSubtitle>
|
||||
<MDivider></MDivider>
|
||||
<MRow NoGutters>
|
||||
@foreach (var network in HardwareInfoWorker.HardwareInfo.NetworkAdapterList ?? new())
|
||||
@{
|
||||
var networkAdapterList = HardwareInfoWorker.HardwareInfo?.NetworkAdapterList;
|
||||
}
|
||||
@if (networkAdapterList != null)
|
||||
{
|
||||
<MCol Md=3 Cols="12" Class="pa-5 d-flex flex-column justify-center">
|
||||
|
||||
<div class="d-flex align-center justify-center">
|
||||
<MIcon>
|
||||
mdi-swap-vertical
|
||||
</MIcon>
|
||||
<div>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text mx-2">上行</span>
|
||||
<span class="text-caption">@((network.BytesReceivedPersec / 1024.00 / 1024).ToString("F2") + " MB")</span>
|
||||
@foreach (var network in networkAdapterList ?? new())
|
||||
{
|
||||
<MCol Md=3 Cols="12" Class="pa-5 d-flex flex-column justify-center">
|
||||
|
||||
</div>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text mx-2">下行</span>
|
||||
<span class="text-caption">@((network.BytesSentPersec / 1024.00 / 1024).ToString("F2") + " MB")</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="text-caption">@network.MACAddress</span>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="text-caption">@network.NetConnectionID</span>
|
||||
</div>
|
||||
@foreach (var item in network.IPAddressList)
|
||||
{
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="text-caption">@item.ToString()</span>
|
||||
<MIcon>
|
||||
mdi-swap-vertical
|
||||
</MIcon>
|
||||
<div>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text mx-2">上行</span>
|
||||
<span class="text-caption">@((network.BytesReceivedPersec / 1024.00 / 1024).ToString("F2") + " MB")</span>
|
||||
|
||||
</div>
|
||||
<div class="mt-1 d-flex align-center justify-space-between">
|
||||
<span class="text-subtitle-2 grey--text mx-2">下行</span>
|
||||
<span class="text-caption">@((network.BytesSentPersec / 1024.00 / 1024).ToString("F2") + " MB")</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="text-caption">@network.MACAddress</span>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="text-caption">@network.NetConnectionID</span>
|
||||
</div>
|
||||
@foreach (var item in network.IPAddressList)
|
||||
{
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="text-caption">@item.ToString()</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
</MCol>
|
||||
</MCol>
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
</MRow>
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
},
|
||||
|
||||
"HardwareInfo": {
|
||||
"Enable": true //启用硬件信息获取,部分系统/硬件不支持相关方法,设为false
|
||||
"Enable": true, //启用硬件信息获取, 部分系统/硬件不支持相关方法,设为false
|
||||
"RemoteIpEnable": true, //是否获取外网IP地址
|
||||
"TimeInterval": 10000 //更新间隔ms
|
||||
},
|
||||
|
||||
//动态API设备
|
||||
|
||||
@@ -35,9 +35,12 @@
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro - AF2021' OR '$(SolutionName)'=='ThingsGateway - Pro'">
|
||||
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.LK.Application\ThingsGateway.LK.Application.csproj" />
|
||||
<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro - AF2021'">
|
||||
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Gateway.LK\ThingsGateway.Gateway.LK.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro'">
|
||||
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Gateway.LK\ThingsGateway.Gateway.LK.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -58,11 +58,11 @@ public class Program
|
||||
builder.WebHost.UseKestrel(
|
||||
o =>
|
||||
{
|
||||
var config = Furion.App.GetConfig<LK.Application.MqttConfig>("MqttConfig", true);
|
||||
var config = Furion.App.GetConfig<ThingsGateway.Gateway.LK.MqttConfig>("MqttConfig", true);
|
||||
|
||||
o.ListenAnyIP(config.Port, a => MQTTnet.AspNetCore.ConnectionBuilderExtensions.UseMqtt(a));
|
||||
|
||||
o.ListenAnyIP(config.WebSocketPort); // Default HTTP pipeline
|
||||
o.ListenAnyIP(config.WebSocketPort);
|
||||
});
|
||||
#endif
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<ProjectReference Include="..\ThingsGateway.Web.Core\ThingsGateway.Web.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro' OR '$(SolutionName)'=='ThingsGateway - Pro - AF2021'">
|
||||
<PropertyGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro - AF2021'">
|
||||
<DefineConstants>AF2021</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ export const language = ["en","zh"];
|
||||
export const removeDefaultStopWordFilter = false;
|
||||
export const removeDefaultStemmer = false;
|
||||
export { default as Mark } from "E:\\Tg\\ThingsGateway\\ThingsGateway-DEV\\handbook\\node_modules\\mark.js\\dist\\mark.js"
|
||||
export const searchIndexUrl = "search-index{dir}.json?_=264c6792";
|
||||
export const searchIndexUrl = "search-index{dir}.json?_=9f4ebc61";
|
||||
export const searchResultLimits = 8;
|
||||
export const searchResultContextMaxLength = 50;
|
||||
export const explicitSearchResultPath = true;
|
||||
|
||||
@@ -227,9 +227,9 @@
|
||||
"179": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/main.90bffab9.js",
|
||||
"hash": "6774eb8ed9189628",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/main.90bffab9.js"
|
||||
"file": "assets/js/main.7a9d5b15.js",
|
||||
"hash": "77266b9ca300039b",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/main.7a9d5b15.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -299,9 +299,9 @@
|
||||
"1303": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/runtime~main.2d62406a.js",
|
||||
"hash": "fc67bb23388f4a51",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/runtime~main.2d62406a.js"
|
||||
"file": "assets/js/runtime~main.4ddd45bf.js",
|
||||
"hash": "061d2e5662b8322a",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/runtime~main.4ddd45bf.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -398,9 +398,9 @@
|
||||
"3371": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/d22033f9.838d285d.js",
|
||||
"hash": "b8c8ee41012bac15",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/d22033f9.838d285d.js"
|
||||
"file": "assets/js/d22033f9.9a898aa5.js",
|
||||
"hash": "86e8f070cc774c84",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/d22033f9.9a898aa5.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -619,9 +619,9 @@
|
||||
"8707": {
|
||||
"js": [
|
||||
{
|
||||
"file": "assets/js/4c79e569.b07342bd.js",
|
||||
"hash": "c0362a85c0105049",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/4c79e569.b07342bd.js"
|
||||
"file": "assets/js/4c79e569.3e5405f6.js",
|
||||
"hash": "baf2d3f9c933bbe5",
|
||||
"publicPath": "/thingsgateway-docs/assets/js/4c79e569.3e5405f6.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
"editUrl": "https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/docs/donate.mdx",
|
||||
"tags": [],
|
||||
"version": "current",
|
||||
"lastUpdatedBy": "2248356998 qq.com",
|
||||
"lastUpdatedAt": 1689499706,
|
||||
"formattedLastUpdatedAt": "Jul 16, 2023",
|
||||
"lastUpdatedBy": "Kimdiego2098",
|
||||
"lastUpdatedAt": 1697721335,
|
||||
"formattedLastUpdatedAt": "Oct 19, 2023",
|
||||
"frontMatter": {
|
||||
"id": "donate",
|
||||
"title": "支持作者"
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
handbook/build/assets/js/d22033f9.9a898aa5.js
Normal file
1
handbook/build/assets/js/d22033f9.9a898aa5.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user