using System.Text.Json;
using DysonNetwork.Shared.Proto;
using NodaTime;
using NodaTime.Serialization.SystemTextJson;
namespace DysonNetwork.Pusher.Connection;
public class WebSocketPacket
{
public string Type { get; set; } = null!;
public object? Data { get; set; } = null!;
public string? Endpoint { get; set; }
public string? ErrorMessage { get; set; }
///
/// Creates a WebSocketPacket from raw WebSocket message bytes
///
/// Raw WebSocket message bytes
/// Deserialized WebSocketPacket
public static WebSocketPacket FromBytes(byte[] bytes)
{
var json = System.Text.Encoding.UTF8.GetString(bytes);
var jsonOpts = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower,
};
return JsonSerializer.Deserialize(json, jsonOpts) ??
throw new JsonException("Failed to deserialize WebSocketPacket");
}
///
/// Deserializes the Data property to the specified type T
///
/// Target type to deserialize to
/// Deserialized data of type T
public T? GetData()
{
if (Data is T typedData)
return typedData;
var jsonOpts = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower,
};
return JsonSerializer.Deserialize(
JsonSerializer.Serialize(Data, jsonOpts),
jsonOpts
);
}
///
/// Serializes this WebSocketPacket to a byte array for sending over WebSocket
///
/// Byte array representation of the packet
public byte[] ToBytes()
{
var jsonOpts = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
DictionaryKeyPolicy = JsonNamingPolicy.SnakeCaseLower,
}.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
var json = JsonSerializer.Serialize(this, jsonOpts);
return System.Text.Encoding.UTF8.GetBytes(json);
}
public Shared.Proto.WebSocketPacket ToProtoValue()
{
return new Shared.Proto.WebSocketPacket
{
Type = Type,
Data = GrpcTypeHelper.ConvertClassToValue(Data),
ErrorMessage = ErrorMessage
};
}
public static WebSocketPacket FromProtoValue(Shared.Proto.WebSocketPacket packet)
{
return new WebSocketPacket
{
Type = packet.Type,
Data = GrpcTypeHelper.ConvertValueToObject(packet.Data),
ErrorMessage = packet.ErrorMessage
};
}
}