mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-11-01 08:03:58 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ec1ee7627 | ||
|
|
79789388fc | ||
|
|
2c4194ee18 |
@@ -1,8 +1,8 @@
|
|||||||
<Project>
|
<Project>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PluginVersion>10.9.11</PluginVersion>
|
<PluginVersion>10.9.14</PluginVersion>
|
||||||
<ProPluginVersion>10.9.11</ProPluginVersion>
|
<ProPluginVersion>10.9.14</ProPluginVersion>
|
||||||
<AuthenticationVersion>2.9.5</AuthenticationVersion>
|
<AuthenticationVersion>2.9.5</AuthenticationVersion>
|
||||||
<SourceGeneratorVersion>10.9.5</SourceGeneratorVersion>
|
<SourceGeneratorVersion>10.9.5</SourceGeneratorVersion>
|
||||||
<NET8Version>8.0.17</NET8Version>
|
<NET8Version>8.0.17</NET8Version>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public interface IThingsGatewayBitConverter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 指定大小端。
|
/// 指定大小端。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
EndianType EndianType { get; }
|
EndianType EndianType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前的字符串编码类型
|
/// 当前的字符串编码类型
|
||||||
|
|||||||
@@ -62,7 +62,14 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public virtual EndianType EndianType { get; }
|
public virtual EndianType EndianType
|
||||||
|
{
|
||||||
|
get => endianType; set
|
||||||
|
{
|
||||||
|
endianType = value;
|
||||||
|
TouchSocketBitConverter = new TouchSocketBitConverter(endianType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public virtual bool IsStringReverseByteWord { get; set; }
|
public virtual bool IsStringReverseByteWord { get; set; }
|
||||||
@@ -70,7 +77,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public virtual bool IsVariableStringLength { get; set; }
|
public virtual bool IsVariableStringLength { get; set; }
|
||||||
|
|
||||||
internal protected TouchSocketBitConverter TouchSocketBitConverter => TouchSocketBitConverter.GetBitConverter(EndianType);
|
internal protected TouchSocketBitConverter TouchSocketBitConverter { get; set; }
|
||||||
|
|
||||||
static ThingsGatewayBitConverter()
|
static ThingsGatewayBitConverter()
|
||||||
{
|
{
|
||||||
@@ -87,7 +94,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
|||||||
/// 以小端
|
/// 以小端
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly ThingsGatewayBitConverter LittleEndian;
|
public static readonly ThingsGatewayBitConverter LittleEndian;
|
||||||
|
private EndianType endianType;
|
||||||
|
|
||||||
public virtual void OtherPropertySet(IThingsGatewayBitConverter thingsGatewayBitConverter, string registerAddress)
|
public virtual void OtherPropertySet(IThingsGatewayBitConverter thingsGatewayBitConverter, string registerAddress)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public class ScheduledAsyncTask : DisposeBase, IScheduledTask, IScheduledIntInte
|
|||||||
private ILog LogMessage;
|
private ILog LogMessage;
|
||||||
private volatile int _isRunning = 0;
|
private volatile int _isRunning = 0;
|
||||||
private volatile int _pendingTriggers = 0;
|
private volatile int _pendingTriggers = 0;
|
||||||
public Int32 Period => _timer?.Period??0;
|
public Int32 Period => _timer?.Period ?? 0;
|
||||||
|
|
||||||
public ScheduledAsyncTask(int interval, Func<object?, CancellationToken, Task> taskFunc, object? state, ILog log, CancellationToken token)
|
public ScheduledAsyncTask(int interval, Func<object?, CancellationToken, Task> taskFunc, object? state, ILog log, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -150,23 +150,26 @@ public abstract class CollectBase : DriverBase, IRpcDriver
|
|||||||
return variablesMethodResult;
|
return variablesMethodResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private volatile bool _addVariableTasks;
|
||||||
protected void RefreshVariableTasks(CancellationToken cancellationToken)
|
protected void RefreshVariableTasks(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (VariableTasks.Count > 0)
|
if (_addVariableTasks)
|
||||||
{
|
{
|
||||||
foreach (var item in VariableTasks)
|
if (VariableTasks != null)
|
||||||
{
|
{
|
||||||
item.Stop();
|
foreach (var item in VariableTasks)
|
||||||
TaskSchedulerLoop.Remove(item);
|
{
|
||||||
}
|
item.Stop();
|
||||||
|
TaskSchedulerLoop?.Remove(item);
|
||||||
|
}
|
||||||
|
|
||||||
VariableTasks = AddVariableTask(cancellationToken);
|
VariableTasks = AddVariableTask(cancellationToken);
|
||||||
|
|
||||||
foreach (var item in VariableTasks)
|
foreach (var item in VariableTasks)
|
||||||
{
|
{
|
||||||
TaskSchedulerLoop.Add(item);
|
TaskSchedulerLoop?.Add(item);
|
||||||
item.Start();
|
item.Start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,7 +201,7 @@ public abstract class CollectBase : DriverBase, IRpcDriver
|
|||||||
tasks.Add(testOnline);
|
tasks.Add(testOnline);
|
||||||
|
|
||||||
VariableTasks = AddVariableTask(cancellationToken);
|
VariableTasks = AddVariableTask(cancellationToken);
|
||||||
|
_addVariableTasks = true;
|
||||||
tasks.AddRange(VariableTasks);
|
tasks.AddRange(VariableTasks);
|
||||||
return tasks;
|
return tasks;
|
||||||
|
|
||||||
@@ -242,6 +245,7 @@ public abstract class CollectBase : DriverBase, IRpcDriver
|
|||||||
|
|
||||||
protected virtual void SetDeviceStatus(object? state, CancellationToken cancellationToken)
|
protected virtual void SetDeviceStatus(object? state, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
CurrentDevice.SetDeviceStatus(TimerX.Now);
|
||||||
if (IsConnected())
|
if (IsConnected())
|
||||||
{
|
{
|
||||||
if (CurrentDevice.DeviceStatus == DeviceStatusEnum.OffLine)
|
if (CurrentDevice.DeviceStatus == DeviceStatusEnum.OffLine)
|
||||||
|
|||||||
@@ -11,9 +11,6 @@
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
using ThingsGateway.Gateway.Application.Extensions;
|
using ThingsGateway.Gateway.Application.Extensions;
|
||||||
using ThingsGateway.NewLife.Extension;
|
using ThingsGateway.NewLife.Extension;
|
||||||
|
|
||||||
|
|||||||
@@ -107,13 +107,13 @@ public class VariableRuntimeService : IVariableRuntimeService
|
|||||||
var result = await GlobalData.VariableService.DeleteVariableAsync(variableIds).ConfigureAwait(false);
|
var result = await GlobalData.VariableService.DeleteVariableAsync(variableIds).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
||||||
|
ConcurrentHashSet<IDriver> changedDriver = new();
|
||||||
|
|
||||||
|
RuntimeServiceHelper.AddBusinessChangedDriver(variableIds, changedDriver);
|
||||||
|
RuntimeServiceHelper.VariableRuntimesDispose(variableIds);
|
||||||
|
|
||||||
if (restart)
|
if (restart)
|
||||||
{
|
{
|
||||||
|
|
||||||
ConcurrentHashSet<IDriver> changedDriver = new();
|
|
||||||
|
|
||||||
RuntimeServiceHelper.AddBusinessChangedDriver(variableIds, changedDriver);
|
|
||||||
RuntimeServiceHelper.VariableRuntimesDispose(variableIds);
|
|
||||||
await RuntimeServiceHelper.ChangedDriverAsync(changedDriver, _logger, cancellationToken).ConfigureAwait(false);
|
await RuntimeServiceHelper.ChangedDriverAsync(changedDriver, _logger, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,14 +136,14 @@ public class VariableRuntimeService : IVariableRuntimeService
|
|||||||
|
|
||||||
var result = await GlobalData.VariableService.DeleteVariableAsync(null).ConfigureAwait(false);
|
var result = await GlobalData.VariableService.DeleteVariableAsync(null).ConfigureAwait(false);
|
||||||
|
|
||||||
|
ConcurrentHashSet<IDriver> changedDriver = new();
|
||||||
|
var variableIds = GlobalData.IdVariables.Select(a => a.Key).ToHashSet();
|
||||||
|
RuntimeServiceHelper.AddBusinessChangedDriver(variableIds, changedDriver);
|
||||||
|
RuntimeServiceHelper.VariableRuntimesDispose(variableIds);
|
||||||
|
|
||||||
if (restart)
|
if (restart)
|
||||||
{
|
{
|
||||||
ConcurrentHashSet<IDriver> changedDriver = new();
|
|
||||||
var variableIds = GlobalData.IdVariables.Select(a => a.Key).ToHashSet();
|
|
||||||
RuntimeServiceHelper.AddBusinessChangedDriver(variableIds, changedDriver);
|
|
||||||
RuntimeServiceHelper.VariableRuntimesDispose(variableIds);
|
|
||||||
await RuntimeServiceHelper.ChangedDriverAsync(changedDriver, _logger, cancellationToken).ConfigureAwait(false);
|
await RuntimeServiceHelper.ChangedDriverAsync(changedDriver, _logger, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1099,7 +1099,7 @@ public class OpcUaMaster : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static List<VariableNode> GetVariableNodes(ReadValueIdCollection itemsToRead, DataValueCollection values, DiagnosticInfoCollection diagnosticInfos, ResponseHeader responseHeader, int count = 1)
|
private List<VariableNode> GetVariableNodes(ReadValueIdCollection itemsToRead, DataValueCollection values, DiagnosticInfoCollection diagnosticInfos, ResponseHeader responseHeader, int count = 1)
|
||||||
{
|
{
|
||||||
ClientBase.ValidateResponse(values, itemsToRead);
|
ClientBase.ValidateResponse(values, itemsToRead);
|
||||||
ClientBase.ValidateDiagnosticInfos(diagnosticInfos, itemsToRead);
|
ClientBase.ValidateDiagnosticInfos(diagnosticInfos, itemsToRead);
|
||||||
@@ -1130,11 +1130,11 @@ public class OpcUaMaster : IDisposable
|
|||||||
// NodeId Attribute
|
// NodeId Attribute
|
||||||
if (!DataValue.IsGood(value))
|
if (!DataValue.IsGood(value))
|
||||||
{
|
{
|
||||||
throw ServiceResultException.Create(value.StatusCode, 0 + 2 * i, diagnosticInfos, responseHeader.StringTable);
|
Log(3, ServiceResultException.Create(value.StatusCode, 0 + 2 * i, diagnosticInfos, responseHeader.StringTable), $"Get nodeid {itemsToRead[0 + 2 * i].NodeId} fail");
|
||||||
}
|
}
|
||||||
if (value == null)
|
if (value == null)
|
||||||
{
|
{
|
||||||
throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Node does not support the NodeId attribute.");
|
Log(3, ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Node does not support the NodeId attribute."), $"Get nodeid {itemsToRead[0 + 2 * i].NodeId} fail");
|
||||||
}
|
}
|
||||||
|
|
||||||
variableNode.NodeId = (NodeId)value.GetValue(typeof(NodeId));
|
variableNode.NodeId = (NodeId)value.GetValue(typeof(NodeId));
|
||||||
@@ -1376,7 +1376,7 @@ public class OpcUaMaster : IDisposable
|
|||||||
{
|
{
|
||||||
if (m_reConnectHandler == null)
|
if (m_reConnectHandler == null)
|
||||||
{
|
{
|
||||||
Log(3, null, "Reconnecting in {0}s", 1);
|
Log(3, null, "Reconnecting : {0}", e.Status.ToString());
|
||||||
m_ReconnectStarting?.Invoke(this, e);
|
m_ReconnectStarting?.Invoke(this, e);
|
||||||
|
|
||||||
m_reConnectHandler = new SessionReconnectHandler(true, 10000);
|
m_reConnectHandler = new SessionReconnectHandler(true, 10000);
|
||||||
|
|||||||
@@ -165,10 +165,11 @@ public class OpcUaMaster : CollectBase
|
|||||||
//如果是订阅模式,连接时添加订阅组
|
//如果是订阅模式,连接时添加订阅组
|
||||||
if (_plc.OpcUaProperty?.ActiveSubscribe == true && CurrentDevice.VariableSourceReads.Count > 0 && _plc.Session.SubscriptionCount < CurrentDevice.VariableSourceReads.Count)
|
if (_plc.OpcUaProperty?.ActiveSubscribe == true && CurrentDevice.VariableSourceReads.Count > 0 && _plc.Session.SubscriptionCount < CurrentDevice.VariableSourceReads.Count)
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
foreach (var variableSourceRead in CurrentDevice.VariableSourceReads)
|
|
||||||
|
foreach (var variableSourceRead in CurrentDevice.VariableSourceReads)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (_plc.Session.Subscriptions.FirstOrDefault(a => a.DisplayName == variableSourceRead.RegisterAddress) == null)
|
if (_plc.Session.Subscriptions.FirstOrDefault(a => a.DisplayName == variableSourceRead.RegisterAddress) == null)
|
||||||
{
|
{
|
||||||
@@ -180,19 +181,22 @@ public class OpcUaMaster : CollectBase
|
|||||||
|
|
||||||
await Task.Delay(100, cancellationToken).ConfigureAwait(false); // allow for subscription to be finished on server?
|
await Task.Delay(100, cancellationToken).ConfigureAwait(false); // allow for subscription to be finished on server?
|
||||||
|
|
||||||
|
checkLog = true;
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (!checkLog)
|
||||||
|
LogMessage?.LogWarning(ex, "AddSubscriptions error");
|
||||||
|
checkLog = false;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
LogMessage?.LogInformation("AddSubscriptions done");
|
LogMessage?.LogInformation("AddSubscriptions done");
|
||||||
checkLog = true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (!checkLog)
|
|
||||||
LogMessage?.LogWarning(ex, "AddSubscriptions error");
|
|
||||||
checkLog = false;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
|
|||||||
{
|
{
|
||||||
if (rootFolder == null) return;
|
if (rootFolder == null) return;
|
||||||
|
|
||||||
|
NodeIdTags?.Clear();
|
||||||
|
RemoveRootNotifier(rootFolder);
|
||||||
rootFolder?.SafeDispose();
|
rootFolder?.SafeDispose();
|
||||||
rootFolder = null;
|
rootFolder = null;
|
||||||
rootFolder = CreateFolder(null, "ThingsGateway", "ThingsGateway");
|
rootFolder = CreateFolder(null, "ThingsGateway", "ThingsGateway");
|
||||||
@@ -100,7 +102,6 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
AddPredefinedNode(SystemContext, rootFolder);
|
AddPredefinedNode(SystemContext, rootFolder);
|
||||||
|
|
||||||
rootFolder.ClearChangeMasks(SystemContext, true);
|
rootFolder.ClearChangeMasks(SystemContext, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -526,7 +527,7 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
|
|||||||
a.ToDictionary(a => a.Item1.Name, a => a.Item2)
|
a.ToDictionary(a => a.Item1.Name, a => a.Item2)
|
||||||
);
|
);
|
||||||
var result = GlobalData.RpcService.InvokeDeviceMethodAsync("OpcUaServer - " + context?.Session?.Identity?.DisplayName, writeDatas
|
var result = GlobalData.RpcService.InvokeDeviceMethodAsync("OpcUaServer - " + context?.Session?.Identity?.DisplayName, writeDatas
|
||||||
).GetAwaiter().GetResult(); ;
|
).GetAwaiter().GetResult();
|
||||||
|
|
||||||
for (int ii = 0; ii < nodesToWrite.Count; ii++)
|
for (int ii = 0; ii < nodesToWrite.Count; ii++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,19 +44,6 @@ public partial class ThingsGatewayServer : StandardServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//public void AfterVariablesChanged()
|
|
||||||
//{
|
|
||||||
// if(masterNodeManager!=null)
|
|
||||||
// {
|
|
||||||
// masterNodeManager?.Dispose();
|
|
||||||
// masterNodeManager = CreateMasterNodeManager((ServerInternalData)NodeManager.Server, _opcUaServer.m_configuration);
|
|
||||||
// ((ServerInternalData)NodeManager.Server).SetNodeManager(masterNodeManager);
|
|
||||||
// // put the node manager into a state that allows it to be used by other objects.
|
|
||||||
// masterNodeManager.Startup();
|
|
||||||
// }
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected override MasterNodeManager CreateMasterNodeManager(IServerInternal server, ApplicationConfiguration configuration)
|
protected override MasterNodeManager CreateMasterNodeManager(IServerInternal server, ApplicationConfiguration configuration)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -78,14 +78,14 @@ public partial class OpcUaServer : BusinessBase
|
|||||||
|
|
||||||
CollectVariableRuntimes.Clear();
|
CollectVariableRuntimes.Clear();
|
||||||
|
|
||||||
IdVariableRuntimes.ForEach(a =>
|
//IdVariableRuntimes.ForEach(a =>
|
||||||
{
|
//{
|
||||||
VariableValueChange(a.Value, a.Value.AdaptVariableBasicData());
|
// VariableValueChange(a.Value, a.Value.AdaptVariableBasicData());
|
||||||
});
|
//});
|
||||||
|
|
||||||
|
|
||||||
m_server?.NodeManager?.RefreshVariable();
|
|
||||||
|
|
||||||
|
//动态更新UA库节点暂时取消
|
||||||
|
//m_server?.NodeManager?.RefreshVariable();
|
||||||
|
m_server?.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -112,6 +112,7 @@ public partial class OpcUaServer : BusinessBase
|
|||||||
GlobalData.VariableValueChangeEvent += VariableValueChange;
|
GlobalData.VariableValueChangeEvent += VariableValueChange;
|
||||||
|
|
||||||
Localizer = App.CreateLocalizerByType(typeof(OpcUaServer))!;
|
Localizer = App.CreateLocalizerByType(typeof(OpcUaServer))!;
|
||||||
|
|
||||||
await base.InitChannelAsync(channel, cancellationToken).ConfigureAwait(false);
|
await base.InitChannelAsync(channel, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public partial class OpcUaMaster : IDisposable
|
|||||||
LogMessage?.AddLogger(logger);
|
LogMessage?.AddLogger(logger);
|
||||||
|
|
||||||
_plc.LogEvent = (a, b, c, d) => LogMessage?.Log((LogLevel)a, b, c, d);
|
_plc.LogEvent = (a, b, c, d) => LogMessage?.Log((LogLevel)a, b, c, d);
|
||||||
_plc.DataChangedHandler += (a) => LogMessage?.Trace(a.ToSystemTextJsonString());
|
_plc.DataChangedHandler += (a) => LogMessage?.Trace($"id:{a.monitoredItem?.StartNodeId};stateCode:{a.dataValue?.StatusCode};value:{a.jToken?.ToString()}");
|
||||||
base.OnInitialized();
|
base.OnInitialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,3 +19,6 @@ ENV ASPNETCORE_FORWARDEDHEADERS_ENABLED=true
|
|||||||
RUN ln -snf /usr/share/zoneinfo/$TimeZone /etc/localtime && echo $TimeZone > /etc/timezone
|
RUN ln -snf /usr/share/zoneinfo/$TimeZone /etc/localtime && echo $TimeZone > /etc/timezone
|
||||||
|
|
||||||
ENTRYPOINT ["dotnet", "ThingsGateway.Server.dll","--urls","http://*:5000"]
|
ENTRYPOINT ["dotnet", "ThingsGateway.Server.dll","--urls","http://*:5000"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
|
|
||||||
|
#docker run -d --name tg --restart always -p 127.0.0.1:5000:5000 -e ASPNETCORE_ENVIRONMENT=Demo -v /thingsgateway/Keys:/app/Keys -v /thingsgateway/DB:/app/DB --memory="512m" registry.cn-shenzhen.aliyuncs.com/thingsgateway/thingsgateway:latest
|
||||||
|
|
||||||
version: "latest" # Docker Compose 配置版本
|
version: "latest" # Docker Compose 配置版本
|
||||||
|
|
||||||
services: # 定义所有要跑的容器(服务)
|
services: # 定义所有要跑的容器(服务)
|
||||||
thingsgateway: #服务名称
|
thingsgateway: #服务名称
|
||||||
image: registry.cn-shenzhen.aliyuncs.com/thingsgateway/thingsgateway:latest #镜像名:tag
|
image: registry.cn-shenzhen.aliyuncs.com/thingsgateway/thingsgateway:latest #镜像名:tag
|
||||||
container_name: thingsgateway #容器名字
|
container_name: tg #容器名字
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:5000:5000" #"主机端口:容器端口"
|
- "127.0.0.1:5000:5000" #"主机端口:容器端口"
|
||||||
environment:
|
environment:
|
||||||
@@ -16,3 +19,4 @@ services: # 定义所有要跑的容器(服务)
|
|||||||
limits:
|
limits:
|
||||||
memory: 512M
|
memory: 512M
|
||||||
restart: always # 容器异常退出自动重启
|
restart: always # 容器异常退出自动重启
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>10.9.11</Version>
|
<Version>10.9.14</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user