Я совсем новичок в SignalR. Я установил интерфейс в React, который подключается к бэкэнду SignalR, который сам подключается к машине через OP C -UA (это школьный проект)
Цель программы для потоковой передачи данных с PL C на мой интерфейс React . Теперь я делаю это так: подключиться через кнопку в frontend -> Frontend вызывает метод, который подписывается на некоторые узлы PL C, который затем отправляет данные обратно.
Моя проблема в том, что мне нужно, чтобы вызываемый метод работал с 'while (true)' l oop, в противном случае я получаю сообщение об ошибке, поскольку объект Hub удаляется.
(Это заставляет PL C вызывать SubscriptionHandler при изменении значений узла, что приводит к ошибке, поскольку объект Hub больше не существует Я думаю ) -> (new OpcSubscribeDataChange("ns=6;s=::Program:Cube.Command.CntrlCmd", SubscriptionHandler)
Как правильно поддерживать соединение, не удаляя объект-концентратор?
Это код SignalR:
using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;
using System.Diagnostics;
using Opc.UaFx.Client;
using Connections;
namespace StreamBackend.Hubs
{
public class DataHub : Hub
{
private IHubContext<DataHub> _context;
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "ConnectedUsers");
await base.OnConnectedAsync();
Console.WriteLine("Client Connected");
OPC.Client.Connect();
}
public override async Task OnDisconnectedAsync(Exception exception)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR");
await base.OnDisconnectedAsync(exception);
Console.WriteLine("Removed: " + Context.ConnectionId);
}
public DataHub(IHubContext<DataHub> context) {
_context = context;
// Implement check on whether connected already or not
Console.WriteLine("Constructor");
}
public async void SubscriptionHandler(object sender, OpcDataChangeReceivedEventArgs e) {
OpcMonitoredItem item = (OpcMonitoredItem)sender;
var NodeId = Convert.ToString(item.NodeId);
var Value = Convert.ToString(e.Item.Value);
await SendData(NodeId, Value);
}
public async Task SendData(string NodeId, string Value) {
await Clients.All.SendAsync("LatestChange", NodeId, Value);
}
public async Task DataHubConnection()
{
await Clients.All.SendAsync("InvokeMethodFromBackend");
OpcSubscribeDataChange[] nodes = new OpcSubscribeDataChange[] {
new OpcSubscribeDataChange("ns=6;s=::Program:Cube.Command.CntrlCmd", SubscriptionHandler),
new OpcSubscribeDataChange("ns=6;s=::Program:Cube.Command.Parameter[0].Value", SubscriptionHandler)
};
OpcSubscription subscription = OPC.Client.SubscribeNodes(nodes);
// This keeps the "Hub" alive. It is needed, cause it is the SubscriptionHandlers accesspoint
while(true) {
Console.WriteLine("Open");
System.Threading.Thread.Sleep(2000); //Hang out for half a second (testing)
}
}
// 1006 error is when the server closes the connection
}
}