// Assets/Script/MessageChannel.cs using System; using System.Collections.Generic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine; namespace Unity.RenderStreaming { public class MessageChannel : DataChannelBase { private const int MAX_HISTORY = 100; [Header("消息记录")] [SerializeField] [TextArea(1, 3)] private string lastReceivedMessage; [SerializeField] private int receivedMessageCount; [SerializeField] private List messageHistory = new(); public IReadOnlyList MessageHistory => messageHistory; public int ReceivedMessageCount => receivedMessageCount; private void Start() { label = "on-message"; } public event Action OnUserInfoMessageReceived; public event Action OnMediaStateChangeReceived; public event Action OnChatMessageReceived; public event Action OnRecordingPeerRequestReceived; public event Action OnRecordingAnswerReceived; public event Action OnRecordingCandidateReceived; public event Action OnRecordingStoppedReceived; public override void OnMessage(string message) { try { Debug.Log($"[MessageChannel] Received: {message}"); var record = JsonConvert.DeserializeObject(message); if (record == null) record = new MessageRecord { type = "raw", data = message }; record.timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); ConnectionId = record.connectionId; JObject json = null; switch (record.type) { case MessageTypes.Chat: var chat = record.data as JObject; var chatData = chat.ToObject(); OnChatMessageReceived?.Invoke(ConnectionId, chatData); break; case MessageTypes.UserInfo: json = record.data as JObject; var info = json.ToObject(); OnUserInfoMessageReceived?.Invoke(ConnectionId, info); break; case MessageTypes.MediaStateChange: json = record.data as JObject; var mediaState = json.ToObject(); OnMediaStateChangeReceived?.Invoke(ConnectionId, mediaState); break; case MessageTypes.RecordingPeerRequest: json = record.data as JObject; var recordingPeerRequest = json.ToObject(); OnRecordingPeerRequestReceived?.Invoke(recordingPeerRequest); break; case MessageTypes.RecordingAnswer: json = record.data as JObject; var recordingAnswer = json.ToObject(); OnRecordingAnswerReceived?.Invoke(recordingAnswer); break; case MessageTypes.RecordingCandidate: json = record.data as JObject; var recordingCandidate = json.ToObject(); OnRecordingCandidateReceived?.Invoke(recordingCandidate); break; case MessageTypes.RecordingStopped: json = record.data as JObject; var recordingStopped = json.ToObject(); OnRecordingStoppedReceived?.Invoke(recordingStopped.recordingId); break; } messageHistory.Add(record); if (messageHistory.Count > MAX_HISTORY) messageHistory.RemoveAt(0); lastReceivedMessage = message; receivedMessageCount++; } catch (Exception e) { Debug.LogError($"[MessageChannel] Parse error: {e.Message}"); } } public void SendMessage(string type, T data) { var record = new MessageRecord { type = type, data = data }; var json = JsonConvert.SerializeObject(record); Send(json); record.isSent = true; messageHistory.Add(record); if (messageHistory.Count > MAX_HISTORY) messageHistory.RemoveAt(0); } public void ClearHistory() { messageHistory.Clear(); receivedMessageCount = 0; lastReceivedMessage = ""; } [Serializable] public class MessageRecord { public string type; public bool isSent; public string timestamp = DateTime.Now.ToString(); public string connectionId; public string participantId; public object data; } } }