246 lines
8.3 KiB
C#
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();
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|