Files
Studio/Assets/Scripts/Studio/Connect/StudioRepository.cs
geondo55 60ce186a2e 백업
2025-07-29 14:55:04 +09:00

246 lines
8.3 KiB
C#

using Best.MQTT;
using Best.MQTT.Packets.Builders;
using Newtonsoft.Json.Linq;
using Studio.Conifg;
using Studio.Setting.Connect;
using Studio.Util;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace Studio
{
public class StudioRepository
{
private MQTTClient client;
public bool isMQTTConnected;
public bool isConnected
{
get
{
if (client == null)
return false;
return client.State == ClientStates.Connected;
}
}
public Action<string, Dictionary<string, Dictionary<string, string>>> OnTopicList;
public StudioRepository()
{
Application.quitting += OnDestroy;
}
private Dictionary<string, MQTTClient> clients =new();
public void MQTTCreateConnect(string MQTTDomain,string MQTTPort)
{
var conntedInfo = CreateConntedInfo(MQTTDomain, MQTTPort);
Debug.Log(conntedInfo);
var port = int.Parse(MQTTPort);
var options = new ConnectionOptionsBuilder()
.WithTCP(MQTTDomain, port)
.Build();
if(clients.ContainsKey(conntedInfo))
{
clients[conntedInfo].OnConnected -= OnConnectedMQTT;
clients[conntedInfo].OnStateChanged -= OnStateChangedMQTT;
clients[conntedInfo].OnDisconnect -= OnDisconnectedMQTT;
clients[conntedInfo].OnError -= OnErrorMQTT;
}
clients[conntedInfo] = new MQTTClient(options);
clients[conntedInfo].OnConnected += OnConnectedMQTT;
clients[conntedInfo].OnStateChanged += OnStateChangedMQTT;
clients[conntedInfo].OnDisconnect += OnDisconnectedMQTT;
clients[conntedInfo].OnError += OnErrorMQTT;
}
public string CreateConntedInfo(string MQTTDomain, string MQTTPort)
{
return $"MQTT Domain : {MQTTDomain} , MQTTPORT :{MQTTPort}";
}
public MQTTClient FindClient(string MQTTDomain, string MQTTPort)
{
string key = CreateConntedInfo(MQTTDomain, MQTTPort);
if (clients.ContainsKey(key))
{
return clients[key];
}
else
{
return null;
}
}
private ConnectPacketBuilder ConnectPacketBuilderCallback(MQTTClient client, ConnectPacketBuilder builder)
{
return builder.WithKeepAlive(60 * 60);//keep alive 1시간으로
}
public async Task<StudioEntityWithState<object>> BaseInfo(string url)
{
try
{
return await Task.Run<StudioEntityWithState<object>>(async () =>
{
ResponseModel<object> response = await RestAPI.RequestPost<ResponseModel<object>>(url);
Debug.Log(response);
if (response.code == "SUCCESS")
return new StudioEntityWithState<object>(APIState.Loaded, response.data,response.requestsize,response.message);
return new StudioEntityWithState<object>(APIState.Error, null, 0,response.message);
});
}
catch (Exception e)
{
return new StudioEntityWithState<object>(APIState.Error, null,0, e.Message);
}
}
public void MQTTConnect(string key)
{
clients[key].BeginConnect(ConnectPacketBuilderCallback);
}
private void OnErrorMQTT(MQTTClient client, string error)
{
Debug.Log($"OnError reason: '{error}'");
}
private void OnDisconnectedMQTT(MQTTClient client, DisconnectReasonCodes reasonCode, string reasonMessage)
{
if (Application.isPlaying)
{
//MQTT재시작
}
}
private void OnStateChangedMQTT(MQTTClient client, ClientStates oldState, ClientStates newState)
{
Debug.Log($"{oldState} => {newState}");
}
private void OnConnectedMQTT(MQTTClient client)
{
var conntedInfo = $"MQTT Domain : {client.Options.Host} , MQTTPORT :{client.Options.Port}";
var topics = StudioService.instance.TopciTable[conntedInfo];
foreach(var topic in topics)
{
Subscribe(client, topic.topic);
}
Debug.Log($"MQTT OnConnected");
}
public void DisConnectMQTT()
{
foreach (var client in clients)
{
client.Value?.CreateDisconnectPacketBuilder()
.WithReasonCode(DisconnectReasonCodes.NormalDisconnection)
.WithReasonString($"{client.Value.Options.Host} Disconnecting")
.BeginDisconnect();
}
}
/// <summary>
/// 구독
/// </summary>
/// <param name="topic"></param>
private void Subscribe(MQTTClient client,string topic)
{
client.CreateBulkSubscriptionBuilder()
.WithTopic(new SubscribeTopicBuilder(topic).WithMessageCallback(OnTopic))
.BeginSubscribe();
}
/// <summary>
/// 구독 취소
/// </summary>
/// <param name="topic"></param>
public void UnSubscibe(MQTTClient client, string topic)
{
client.CreateUnsubscribePacketBuilder(topic)
.WithAcknowledgementCallback((client, topicFilter, reasonCode) => Debug.Log($"Unsubscribe request to topic filter '{topicFilter}' returned with code: {reasonCode}"))
.BeginUnsubscribe();
}
public void UnSubscibeAll()
{
List<MQTTConnection> mqttConnections = ConfigConnected.MQTTSettings.mqttConnections;
foreach (var connection in mqttConnections)
{
foreach (var topic in connection.topics)
{
UnSubscibe(FindClient(connection.domain, connection.port), topic.topic);
}
}
}
private void OnTopic(MQTTClient client, SubscriptionTopic topic, string topicName, ApplicationMessage message)
{
string payload = Encoding.UTF8.GetString(message.Payload.Data, message.Payload.Offset, message.Payload.Count);
var type = topic.Filter.ToString();
JObject json = JObject.Parse(payload);
foreach(JProperty prop in json.Children())
{
string key = prop.Name.ToString();
string value = prop.Value.ToString();
}
var T = json["data"];
var split = T.ToString().Split('[');
var t = $"[{split[split.Length-1]}";
JArray jarray = JArray.Parse(t);
var list = new Dictionary<string, Dictionary<string, string>>();
foreach (JObject obj in jarray.Children())
{
Dictionary<string, string> keyvalue = new();
int index = 0;
string id = string.Empty;
foreach (JProperty prop in obj.Children())
{
string key = prop.Name.ToString();
string value = prop.Value.ToString();
if (index == 0)
{
if (!list.ContainsKey(value))
list.Add(value, new());
id = value;
index = 1;
}
keyvalue.Add(key, value);
}
list[id] = keyvalue;
}
CheckUpdate(type, list);
}
private void CheckUpdate(string type, Dictionary<string, Dictionary<string, string>> data)
{
if (data == null)
return;
if(data.Count > 0)
OnTopicList?.Invoke(type, data);
}
private void OnDestroy()
{
foreach(var client in clients)
{
client.Value?.CreateDisconnectPacketBuilder()
.WithReasonCode(DisconnectReasonCodes.NormalDisconnection)
.WithReasonString($"{client.Value.Options.Host} Disconnecting")
.BeginDisconnect();
}
}
}
}