using AyCode.Core.Extensions; using MessagePack; using Newtonsoft.Json.Linq; using System.Text.RegularExpressions; using AyCode.Core.Interfaces; using System.Collections.Generic; using System.Linq.Expressions; namespace AyCode.Services.SignalRs; public class IdMessage { public List Ids { get; private set; } = []; public IdMessage() { } public IdMessage(IEnumerable ids) : this() { //Ids.AddRange(ids); Ids.AddRange(ids.Select(x => { string item; //if (x is Expression expr) //{ // string aa = string.Empty; // var serializer = new ExpressionSerializer(new JsonSerializer()); // try // { // aa = serializer.SerializeText(expr); // } // catch(Exception ex) // { // Console.WriteLine(ex); // } // item = (new[] { aa }).ToJson(); //} //else item = (new[] { x }).ToJson(); return item; })); } public IdMessage(object id) : this(new object[] { id }) { } public IdMessage(IEnumerable ids) : this(ids.Cast().ToArray()) { } public override string ToString() { return string.Join("; ", Ids); } } public class SignalPostJsonMessage { [Key(0)] public string PostDataJson { get; set; } public SignalPostJsonMessage() {} protected SignalPostJsonMessage(string postDataJson) => PostDataJson = postDataJson; } [MessagePackObject] public class SignalPostJsonDataMessage : SignalPostJsonMessage, ISignalPostMessage //where TPostDataType : class { [IgnoreMember] private TPostDataType? _postData; [IgnoreMember] public TPostDataType PostData { get { return _postData ??= PostDataJson.JsonTo()!; } private init { _postData = value; PostDataJson = _postData.ToJson(); } } public SignalPostJsonDataMessage() : base() {} public SignalPostJsonDataMessage(TPostDataType postData) => PostData = postData; public SignalPostJsonDataMessage(string postDataJson) : base(postDataJson) {} } [MessagePackObject] public class SignalPostMessage(TPostData postData) : ISignalPostMessage { [Key(0)] public TPostData? PostData { get; set; } = postData; } public interface ISignalPostMessage : ISignalRMessage { TPostData? PostData { get; } } [MessagePackObject] public class SignalRequestByIdMessage(Guid id) : ISignalRequestMessage, IId { [Key(0)] public Guid Id { get; set; } = id; } public interface ISignalRequestMessage : ISignalRMessage { TRequestId Id { get; set; } } public interface ISignalRMessage { } [MessagePackObject] public sealed class SignalResponseJsonMessage : ISignalResponseMessage { [Key(0)] public int MessageTag { get; set; } [Key(1)] public SignalResponseStatus Status { get; set; } [Key(2)] public string? ResponseData { get; set; } = null; [IgnoreMember] public string? ResponseDataJson => ResponseData; public SignalResponseJsonMessage(){} public SignalResponseJsonMessage(int messageTag, SignalResponseStatus status) { Status = status; MessageTag = messageTag; } public SignalResponseJsonMessage(int messageTag, SignalResponseStatus status, object? responseData) : this(messageTag, status) { if (responseData is string stringdata) ResponseData = stringdata; else ResponseData = responseData.ToJson(); } public SignalResponseJsonMessage(int messageTag, SignalResponseStatus status, string? responseDataJson) : this(messageTag, status) { ResponseData = responseDataJson; } } /// /// Signal response message with lazy deserialization support. /// ResponseData is only deserialized on first access and cached. /// Use ResponseDataJson for direct JSON access without deserialization. /// [MessagePackObject] public sealed class SignalResponseMessage : ISignalResponseMessage { [IgnoreMember] private TResponseData? _responseData; [IgnoreMember] private bool _isDeserialized; [Key(0)] public int MessageTag { get; set; } [Key(1)] public SignalResponseStatus Status { get; set; } /// /// Raw JSON string. Use this for direct JSON access without triggering deserialization. /// [Key(2)] public string? ResponseDataJson { get; set; } /// /// Deserialized response data. Lazy-loaded on first access. /// [IgnoreMember] public TResponseData? ResponseData { get { if (!_isDeserialized) { _responseData = ResponseDataJson != null ? ResponseDataJson.JsonTo() : default; _isDeserialized = true; } return _responseData; } set { _responseData = value; _isDeserialized = true; ResponseDataJson = value?.ToJson(); } } public SignalResponseMessage() { } public SignalResponseMessage(int messageTag, SignalResponseStatus status) { MessageTag = messageTag; Status = status; } public SignalResponseMessage(int messageTag, SignalResponseStatus status, TResponseData? responseData) : this(messageTag, status) { ResponseData = responseData; } public SignalResponseMessage(int messageTag, SignalResponseStatus status, string? responseDataJson) : this(messageTag, status) { ResponseDataJson = responseDataJson; } } public interface ISignalResponseMessage : ISignalResponseMessage { /// /// Deserialized response data. May trigger lazy deserialization. /// TResponseData? ResponseData { get; set; } /// /// Raw JSON string for direct access without deserialization. /// string? ResponseDataJson { get; } } public interface ISignalResponseMessage : ISignalRMessage { int MessageTag { get; set; } SignalResponseStatus Status { get; set; } } public enum SignalResponseStatus : byte { Error = 0, Success = 5 } public interface IAcSignalRHubClient : IAcSignalRHubBase { Task SendMessageToServerAsync(int messageTag, ISignalRMessage? message, int? requestId ); //Task SendRequestToServerAsync(int messageTag, int requestId); }