增加自定义不是房间的消息发送
This commit is contained in:
@@ -5,6 +5,7 @@ using UnityEngine;
|
||||
|
||||
public interface IGlobalConfigSystem : ISystem
|
||||
{
|
||||
public string IP { get; }
|
||||
public string GetConnectionId();
|
||||
public void SetConnectionId(string connectionId);
|
||||
|
||||
@@ -21,6 +22,9 @@ public interface IGlobalConfigSystem : ISystem
|
||||
|
||||
public Texture2D GetConnectionTexture();
|
||||
public void SetConnectionTexture(Texture2D connectionTexture);
|
||||
|
||||
public string GetUserId();
|
||||
public void SetUserId(string userId);
|
||||
}
|
||||
|
||||
public class GlobalConfigSystem : AbstractSystem, IGlobalConfigSystem
|
||||
@@ -53,11 +57,19 @@ public class GlobalConfigSystem : AbstractSystem, IGlobalConfigSystem
|
||||
private CancellationTokenSource _cts;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 连接ID
|
||||
/// </summary>
|
||||
private string _userId;
|
||||
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public string IP => "http://127.0.0.1:8080";
|
||||
|
||||
public string GetConnectionId()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_connectionId))
|
||||
@@ -143,6 +155,22 @@ public class GlobalConfigSystem : AbstractSystem, IGlobalConfigSystem
|
||||
_connectionTexture = connectionTexture;
|
||||
}
|
||||
|
||||
public string GetUserId()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_userId))
|
||||
{
|
||||
Debug.LogWarning("GlobalConfigSystem: GetUserId not set");
|
||||
return "";
|
||||
}
|
||||
|
||||
return _userId;
|
||||
}
|
||||
|
||||
public void SetUserId(string userId)
|
||||
{
|
||||
_userId = userId;
|
||||
}
|
||||
|
||||
protected override void OnInit()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Net;
|
||||
using RenderStreaming;
|
||||
using Stary.Evo;
|
||||
using Stary.Evo.UIFarme;
|
||||
@@ -8,6 +9,11 @@ public class Main : MonoBehaviour, IController
|
||||
{
|
||||
private void Start()
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback =
|
||||
(sender, certificate, chain, sslPolicyErrors) =>
|
||||
{
|
||||
return true; // 信任所有证书,仅开发环境使用
|
||||
};
|
||||
this.GetSystem<IPanelSystem>().PushQueue<StartPanel>();
|
||||
}
|
||||
|
||||
|
||||
3
Assets/Script/MainPanel.meta
Normal file
3
Assets/Script/MainPanel.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1645e864f3c440ea9e6155be8f97d045
|
||||
timeCreated: 1779019467
|
||||
201
Assets/Script/MainPanel/ContactEntryController.cs
Normal file
201
Assets/Script/MainPanel/ContactEntryController.cs
Normal file
@@ -0,0 +1,201 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using RenderStreaming;
|
||||
using Stary.Evo;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace Script
|
||||
{
|
||||
public class ContactEntryController : MonoBehaviour, IController
|
||||
{
|
||||
private Transform _background;
|
||||
private Transform _backgroundName;
|
||||
private GameObject _confirmBtnTime;
|
||||
private Text _confirmBtnTimeText;
|
||||
private Button _confirmButton;
|
||||
private bool _isCountingDown;
|
||||
private MeetingContacts _meetingContacts;
|
||||
private Transform _messageText;
|
||||
private Transform _nameText;
|
||||
private MeetingContacts.UsersItem _usersItem;
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
_isCountingDown = false;
|
||||
}
|
||||
|
||||
public IArchitecture GetArchitecture()
|
||||
{
|
||||
return MainArchitecture.Interface;
|
||||
}
|
||||
|
||||
public void SetData(MeetingContacts.UsersItem item, MeetingContacts meetingContactsController)
|
||||
{
|
||||
_usersItem = item;
|
||||
_meetingContacts = meetingContactsController;
|
||||
///头像赋值
|
||||
if (string.IsNullOrEmpty(item.avatar))
|
||||
{
|
||||
var randomColor = GetRandomColor();
|
||||
_background = transform.Find("headBackground");
|
||||
if (_background != null)
|
||||
{
|
||||
var image = _background.GetComponent<Image>();
|
||||
if (image != null) image.color = randomColor;
|
||||
}
|
||||
|
||||
_backgroundName = _background.transform.Find("Name");
|
||||
if (_backgroundName != null)
|
||||
{
|
||||
var textComponent = _backgroundName.GetComponent<Text>();
|
||||
if (textComponent != null && !string.IsNullOrEmpty(item.name))
|
||||
textComponent.text = item.name.Substring(0, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_background = transform.Find("headBackground");
|
||||
if (_background != null)
|
||||
{
|
||||
var imageComponent = _background.GetComponent<Image>();
|
||||
if (imageComponent != null) DownloadAndSetAvatar(item.avatar, imageComponent);
|
||||
}
|
||||
|
||||
_backgroundName = _background.transform.Find("Name");
|
||||
if (_backgroundName != null) _backgroundName.GetComponent<Text>().text = "";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(item.name))
|
||||
_nameText = transform.Find("Name");
|
||||
if (_nameText != null)
|
||||
{
|
||||
var textComponent = _nameText.GetComponent<Text>();
|
||||
if (textComponent != null) textComponent.text = item.name;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(item.userId))
|
||||
{
|
||||
_messageText = transform.Find("Message");
|
||||
if (_messageText != null)
|
||||
{
|
||||
var textComponent = _messageText.GetComponent<Text>();
|
||||
if (textComponent != null) textComponent.text = item.userId;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(item.role))
|
||||
{
|
||||
var role = item.role;
|
||||
var idle = transform.Find("Name/state/idle");
|
||||
var participant = transform.Find("Name/state/participant");
|
||||
var host = transform.Find("Name/state/host");
|
||||
|
||||
if (role.Equals("host"))
|
||||
{
|
||||
host.gameObject.SetActive(true);
|
||||
participant.gameObject.SetActive(false);
|
||||
idle.gameObject.SetActive(false);
|
||||
}
|
||||
else if (role.Equals("participant"))
|
||||
{
|
||||
participant.gameObject.SetActive(true);
|
||||
host.gameObject.SetActive(false);
|
||||
idle.gameObject.SetActive(false);
|
||||
}
|
||||
else if (role.Equals("idle"))
|
||||
{
|
||||
idle.gameObject.SetActive(true);
|
||||
host.gameObject.SetActive(false);
|
||||
participant.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
_confirmButton = transform.Find("callBtn").GetComponent<Button>();
|
||||
_confirmButton.onClick.AddListener(OnClickEntry);
|
||||
_confirmBtnTime = _confirmButton.transform.Find("timebg").gameObject;
|
||||
_confirmBtnTimeText = _confirmBtnTime.transform.Find("Text").GetComponent<Text>();
|
||||
_confirmBtnTime.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void OnClickEntry()
|
||||
{
|
||||
if (_isCountingDown)
|
||||
{
|
||||
Debug.Log("倒计时进行中,无法点击");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"点击了联系人: {_usersItem.name}");
|
||||
// 这里可以添加点击联系人后的逻辑,比如打开聊天窗口
|
||||
// 或者发送邀请请求等
|
||||
_meetingContacts.ClickContactEntry(_background.GetComponent<Image>().sprite,
|
||||
_backgroundName.GetComponent<Text>().text, _usersItem);
|
||||
_meetingContacts.CurrentEntry = this;
|
||||
}
|
||||
|
||||
public void StartCountdown()
|
||||
{
|
||||
if (_isCountingDown) return;
|
||||
_isCountingDown = true;
|
||||
_confirmButton.interactable = false;
|
||||
_confirmBtnTime.gameObject.SetActive(true);
|
||||
StartCoroutine(CountdownCoroutine(50));
|
||||
}
|
||||
|
||||
private IEnumerator CountdownCoroutine(int seconds)
|
||||
{
|
||||
Debug.Log($"开始{seconds}秒倒计时");
|
||||
for (var i = seconds; i >= 0; i--)
|
||||
{
|
||||
_confirmBtnTimeText.text = i.ToString();
|
||||
Debug.Log($"倒计时: {i}秒");
|
||||
yield return new WaitForSeconds(1);
|
||||
}
|
||||
|
||||
Debug.Log("倒计时结束");
|
||||
_isCountingDown = false;
|
||||
_confirmButton.interactable = true;
|
||||
_confirmBtnTime.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private Color GetRandomColor()
|
||||
{
|
||||
return new Color(
|
||||
Random.Range(0.2f, 0.8f),
|
||||
Random.Range(0.2f, 0.8f),
|
||||
Random.Range(0.2f, 0.8f),
|
||||
1f
|
||||
);
|
||||
}
|
||||
|
||||
private async void DownloadAndSetAvatar(string avatarUrl, Image targetImage)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tempPath = Path.Combine(Application.temporaryCachePath, $"avatar_{Guid.NewGuid()}.png");
|
||||
var result = await WebRequestSystem.GetFile(avatarUrl, tempPath);
|
||||
|
||||
if (result.code == 200)
|
||||
{
|
||||
var bytes = File.ReadAllBytes(tempPath);
|
||||
var texture = new Texture2D(2, 2);
|
||||
texture.LoadImage(bytes);
|
||||
|
||||
var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height),
|
||||
Vector2.one * 0.5f);
|
||||
targetImage.sprite = sprite;
|
||||
|
||||
File.Delete(tempPath);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"下载头像失败: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Script/MainPanel/ContactEntryController.cs.meta
Normal file
3
Assets/Script/MainPanel/ContactEntryController.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c16475152291466fa053f892d1ec0c8b
|
||||
timeCreated: 1779100629
|
||||
@@ -17,6 +17,8 @@ namespace Script
|
||||
/// </summary>
|
||||
private Text _idText;
|
||||
|
||||
private MeetingContacts _meetingContacts;
|
||||
|
||||
/// <summary>
|
||||
/// 房间人数
|
||||
/// </summary>
|
||||
@@ -36,7 +38,6 @@ namespace Script
|
||||
|
||||
public override string UIPath => "Canvas";
|
||||
|
||||
|
||||
public override void Initialize(GameObject panelGo)
|
||||
{
|
||||
base.Initialize(panelGo);
|
||||
@@ -45,11 +46,14 @@ namespace Script
|
||||
_arrowLeft = panelGo.transform.Find("Header/arrow-left").GetComponent<Button>();
|
||||
_idText = panelGo.transform.Find("MeetingInfoCard/meeting/id").GetComponent<Text>();
|
||||
_roomPeopleNumText = panelGo.transform.Find("MeetingInfoCard/numberOfPeople/number").GetComponent<Text>();
|
||||
_meetingContacts = new MeetingContacts();
|
||||
_meetingContacts.Initialize(panelGo.transform.Find("MeetingContacts").gameObject);
|
||||
}
|
||||
|
||||
public override void OnEnter(Action complete = null)
|
||||
{
|
||||
base.OnEnter(complete);
|
||||
_meetingContacts.OnEnter();
|
||||
_arrowLeft.onClick.AddListener(OnArrowLeftClick);
|
||||
}
|
||||
|
||||
@@ -57,6 +61,7 @@ namespace Script
|
||||
public override void OnExit(float delay = 0)
|
||||
{
|
||||
base.OnExit(delay);
|
||||
_meetingContacts.OnExit();
|
||||
_arrowLeft.onClick.RemoveListener(OnArrowLeftClick);
|
||||
}
|
||||
|
||||
188
Assets/Script/MainPanel/MeetingContacts.cs
Normal file
188
Assets/Script/MainPanel/MeetingContacts.cs
Normal file
@@ -0,0 +1,188 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using RenderStreaming;
|
||||
using Stary.Evo;
|
||||
using Unity.RenderStreaming;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Script
|
||||
{
|
||||
public class MeetingContacts : IController
|
||||
{
|
||||
/// <summary>
|
||||
/// 联系人列表项字典
|
||||
/// Key: 参与者ID
|
||||
/// Value: 联系人列表项实例
|
||||
/// </summary>
|
||||
private readonly Dictionary<GameObject, ContactEntryController> _contactEntries = new();
|
||||
|
||||
private Image _avatarImage;
|
||||
private Button _cancelButton;
|
||||
private Button _confirmButton;
|
||||
|
||||
private GameObject _confirmingPop;
|
||||
|
||||
/// <summary>
|
||||
/// 联系人列表项预制体
|
||||
/// </summary>
|
||||
private GameObject _contactEntryPrefab;
|
||||
|
||||
/// <summary>
|
||||
/// 全部联系人列表容器
|
||||
/// </summary>
|
||||
private Transform _content;
|
||||
|
||||
private Text _idText;
|
||||
private InputField _leaveMessage;
|
||||
private Text _messageText;
|
||||
private Text _nameText;
|
||||
|
||||
private GameObject _panelGo;
|
||||
|
||||
public ContactEntryController CurrentEntry { get; set; }
|
||||
|
||||
public IArchitecture GetArchitecture()
|
||||
{
|
||||
return MainArchitecture.Interface;
|
||||
}
|
||||
|
||||
public void Initialize(GameObject panelGo)
|
||||
{
|
||||
_panelGo = panelGo;
|
||||
_contactEntryPrefab = Resources.Load<GameObject>("ContactEntry");
|
||||
_content = _panelGo.transform.Find("MeetingGrid/Viewport/Content");
|
||||
|
||||
//邀请界面
|
||||
_confirmingPop = _panelGo.transform.Find("MeetingGrid/ConfirmingPop").gameObject;
|
||||
_confirmingPop.SetActive(false);
|
||||
//确认邀请
|
||||
_idText = _confirmingPop.transform.Find("bg/id").GetComponent<Text>();
|
||||
_leaveMessage = _confirmingPop.transform.Find("bg/leaveMessage").GetComponent<InputField>();
|
||||
_confirmButton = _confirmingPop.transform.Find("bg/invite").GetComponent<Button>();
|
||||
_cancelButton = _confirmingPop.transform.Find("bg/cancel").GetComponent<Button>();
|
||||
|
||||
_avatarImage = _confirmingPop.transform.Find("ParticipantEntry/head").GetComponent<Image>();
|
||||
_nameText = _confirmingPop.transform.Find("ParticipantEntry/Name").GetComponent<Text>();
|
||||
_messageText = _confirmingPop.transform.Find("ParticipantEntry/Message").GetComponent<Text>();
|
||||
}
|
||||
|
||||
public async void OnEnter()
|
||||
{
|
||||
var response =
|
||||
await WebRequestSystem.Get<ResponseUsers>(this.GetSystem<IGlobalConfigSystem>().IP, "/signaling/users");
|
||||
if (response != null && response.totalCount > 0)
|
||||
for (var i = 0; i < response.totalCount; i++)
|
||||
{
|
||||
var item = response.users[i];
|
||||
if (string.IsNullOrEmpty(item.name) ||
|
||||
string.IsNullOrEmpty(item.userId)) continue;
|
||||
var entry = GameObject.Instantiate(_contactEntryPrefab, _content);
|
||||
var contactEntryController = entry.GetOrAddComponent<ContactEntryController>();
|
||||
contactEntryController.SetData(item, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnExit()
|
||||
{
|
||||
}
|
||||
|
||||
public void ClickContactEntry(Sprite avatarImage, string name, UsersItem item)
|
||||
{
|
||||
_confirmingPop.SetActive(true);
|
||||
|
||||
|
||||
_idText.text = this.GetSystem<IGlobalConfigSystem>().GetConnectionId();
|
||||
|
||||
_avatarImage.sprite = avatarImage;
|
||||
var avatarName = _avatarImage.transform.Find("Name").GetComponent<Text>();
|
||||
avatarName.text = name;
|
||||
_nameText.text = item.name;
|
||||
_messageText.text = item.userId;
|
||||
|
||||
_confirmButton.onClick.AddListener(() =>
|
||||
{
|
||||
_confirmingPop.SetActive(false);
|
||||
CurrentEntry.StartCountdown();
|
||||
// var avatar = _profileImage.sprite.name.Replace("(Clone)", "");
|
||||
var userInfo = new
|
||||
{
|
||||
type = "invite-call",
|
||||
data = new
|
||||
{
|
||||
connectionId = this.GetSystem<IGlobalConfigSystem>().GetConnectionId(),
|
||||
targetSocketId = item.socketId,
|
||||
targetUserId = item.userId,
|
||||
inviterUserId = this.GetSystem<IGlobalConfigSystem>().GetUserId(),
|
||||
inviterName = this.GetSystem<IGlobalConfigSystem>().GetConnectionName(),
|
||||
inviterAvatar =
|
||||
$"{this.GetSystem<IGlobalConfigSystem>().IP}/images/head/" +
|
||||
$"{this.GetSystem<IGlobalConfigSystem>().GetConnectionTexture().name}.png"
|
||||
}
|
||||
};
|
||||
SignalingMessageHelper.SendMessage(JsonConvert.SerializeObject(userInfo));
|
||||
});
|
||||
_cancelButton.onClick.AddListener(() =>
|
||||
{
|
||||
_confirmingPop.SetActive(false);
|
||||
CurrentEntry = null;
|
||||
});
|
||||
}
|
||||
|
||||
public class ContactEntryData
|
||||
{
|
||||
public string avatar;
|
||||
public GameObject entry;
|
||||
public Toggle invitationTog;
|
||||
public string name;
|
||||
public string participantId;
|
||||
public string role;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ResponseUsers
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public List<UsersItem> users { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public int totalCount { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class UsersItem
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public string socketId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public string connectionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public string participantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public string role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public string userId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public string name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public string avatar { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Script/MainPanel/MeetingContacts.cs.meta
Normal file
3
Assets/Script/MainPanel/MeetingContacts.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05ce391aaa7a4698941ba9f6b0157614
|
||||
timeCreated: 1779019493
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Script;
|
||||
using Stary.Evo;
|
||||
using Stary.Evo.UIFarme;
|
||||
@@ -91,6 +92,24 @@ namespace Unity.RenderStreaming
|
||||
public override void Initialize(GameObject panelGo)
|
||||
{
|
||||
base.Initialize(panelGo);
|
||||
_arrowLeft = panelGo.transform.Find("Herder/arrow-left").GetComponent<Button>();
|
||||
_profilePhoto = panelGo.transform.Find("HeadPortraits/MeetingInfoCard").GetComponent<Button>();
|
||||
_profileImage = _profilePhoto.transform.Find("mask/sprite").GetComponent<Image>();
|
||||
_meetingNameInput = panelGo.transform.Find("card/search/InputField").GetComponent<InputField>();
|
||||
_meetingId = panelGo.transform.Find("card/huiyiID/connectionId").GetComponent<Text>();
|
||||
_randomMeetingId = panelGo.transform.Find("card/huiyiID/Button").GetComponent<Button>();
|
||||
_timeDropdown = panelGo.transform.Find("card/time/Dropdown").GetComponent<Dropdown>();
|
||||
_startButton = panelGo.transform.Find("invite").GetComponent<Button>();
|
||||
_spriteAtlas = Resources.Load<SpriteAtlas>("SpriteAtlas");
|
||||
if (_spriteAtlas != null)
|
||||
{
|
||||
_profileSprites = new Sprite[_spriteAtlas.spriteCount];
|
||||
_spriteAtlas.GetSprites(_profileSprites);
|
||||
}
|
||||
|
||||
_profileSpriteIndex = 0;
|
||||
OnClickProfilePhoto();
|
||||
|
||||
renderStreaming = GameObject.FindObjectOfType<SignalingManager>();
|
||||
hostConnection = GameObject.FindObjectOfType<HostConnection>();
|
||||
videoStreamSender = hostConnection.GetComponent<VideoStreamSender>();
|
||||
@@ -110,23 +129,6 @@ namespace Unity.RenderStreaming
|
||||
if (settings?.SignalingSettings != null)
|
||||
renderStreaming.SetSignalingSettings(settings.SignalingSettings);
|
||||
renderStreaming.Run();
|
||||
_arrowLeft = panelGo.transform.Find("Herder/arrow-left").GetComponent<Button>();
|
||||
_profilePhoto = panelGo.transform.Find("HeadPortraits/MeetingInfoCard").GetComponent<Button>();
|
||||
_profileImage = _profilePhoto.transform.Find("mask/sprite").GetComponent<Image>();
|
||||
_meetingNameInput = panelGo.transform.Find("card/search/InputField").GetComponent<InputField>();
|
||||
_meetingId = panelGo.transform.Find("card/huiyiID/connectionId").GetComponent<Text>();
|
||||
_randomMeetingId = panelGo.transform.Find("card/huiyiID/Button").GetComponent<Button>();
|
||||
_timeDropdown = panelGo.transform.Find("card/time/Dropdown").GetComponent<Dropdown>();
|
||||
_startButton = panelGo.transform.Find("invite").GetComponent<Button>();
|
||||
_spriteAtlas = Resources.Load<SpriteAtlas>("SpriteAtlas");
|
||||
if (_spriteAtlas != null)
|
||||
{
|
||||
_profileSprites = new Sprite[_spriteAtlas.spriteCount];
|
||||
_spriteAtlas.GetSprites(_profileSprites);
|
||||
}
|
||||
|
||||
_profileSpriteIndex = 0;
|
||||
OnClickProfilePhoto();
|
||||
}
|
||||
|
||||
public override void OnEnter(Action complete = null)
|
||||
@@ -183,13 +185,38 @@ namespace Unity.RenderStreaming
|
||||
if (string.IsNullOrEmpty(_meetingNameInput.text)) _meetingNameInput.text = $"{meetingId}的房间";
|
||||
}
|
||||
|
||||
private string OnClickRandomUserId()
|
||||
{
|
||||
return $"user_{Random.Range(100, 999)}";
|
||||
}
|
||||
|
||||
private void OnClickStartButton()
|
||||
{
|
||||
this.GetSystem<IGlobalConfigSystem>().SetUserId(OnClickRandomUserId());
|
||||
this.GetSystem<IGlobalConfigSystem>().SetConnectionTimeType(_timeDropdown.value);
|
||||
this.GetSystem<IGlobalConfigSystem>().SetConnectionId(_meetingId.text);
|
||||
hostConnection.RoomConnectionId = this.GetSystem<IGlobalConfigSystem>().GetConnectionId();
|
||||
this.GetSystem<IGlobalConfigSystem>().SetConnectionName(_meetingNameInput.text);
|
||||
this.GetSystem<IGlobalConfigSystem>().SetConnectionTexture(Texture2D.whiteTexture);
|
||||
this.GetSystem<IGlobalConfigSystem>().SetConnectionTexture(_profileImage.sprite.texture);
|
||||
if (!SignalingMessageHelper.IsReady())
|
||||
{
|
||||
Debug.LogError("Signaling 未就绪");
|
||||
return;
|
||||
}
|
||||
|
||||
var avatar = _profileImage.sprite.name.Replace("(Clone)", "");
|
||||
var userInfo = new
|
||||
{
|
||||
type = "host-userInfo",
|
||||
data = new
|
||||
{
|
||||
connectionId = hostConnection.RoomConnectionId,
|
||||
id = this.GetSystem<IGlobalConfigSystem>().GetUserId(),
|
||||
name = _meetingNameInput.text,
|
||||
avatar = $"{this.GetSystem<IGlobalConfigSystem>().IP}/images/head/{avatar}.png"
|
||||
}
|
||||
};
|
||||
SignalingMessageHelper.SendMessage(JsonConvert.SerializeObject(userInfo));
|
||||
SetUp();
|
||||
PanelSystem.PopQueue<StartPanel>();
|
||||
PanelSystem.PushQueue<MainPanel>();
|
||||
|
||||
509
Assets/Script/WebRequestSystem.cs
Normal file
509
Assets/Script/WebRequestSystem.cs
Normal file
@@ -0,0 +1,509 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace Stary.Evo
|
||||
{
|
||||
public static class WebRequestSystem
|
||||
{
|
||||
private static string authorization;
|
||||
|
||||
static WebRequestSystem()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
authorization = CustomEditorPrefs.GetString("Authorization");
|
||||
#else
|
||||
authorization = CustomPlayerPrefs.GetString("Authorization");
|
||||
#endif
|
||||
}
|
||||
|
||||
public static async Task<bool> Login(string url, string username, string password)
|
||||
{
|
||||
var data = new
|
||||
{
|
||||
username,
|
||||
password,
|
||||
roleType = "client"
|
||||
};
|
||||
var postData = JsonConvert.SerializeObject(data);
|
||||
try
|
||||
{
|
||||
using var webRequest = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
|
||||
|
||||
webRequest.downloadHandler = new DownloadHandlerBuffer();
|
||||
if (string.IsNullOrEmpty(postData))
|
||||
{
|
||||
Debug.LogError("WebRequestSystem.Login postData is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
var postBytes = Encoding.UTF8.GetBytes(postData);
|
||||
webRequest.uploadHandler = new UploadHandlerRaw(postBytes);
|
||||
webRequest.SetRequestHeader("Content-Type", "application/json");
|
||||
webRequest.timeout = 10;
|
||||
await webRequest.SendWebRequest();
|
||||
webRequest.uploadHandler?.Dispose();
|
||||
// 更新错误检查方式
|
||||
if (webRequest.result == UnityWebRequest.Result.ConnectionError ||
|
||||
webRequest.result == UnityWebRequest.Result.ProtocolError)
|
||||
{
|
||||
Debug.LogError(webRequest.error);
|
||||
}
|
||||
else
|
||||
{
|
||||
var authResponse =
|
||||
JsonConvert.DeserializeObject<ResultMessageEntity>(webRequest.downloadHandler.text);
|
||||
Debug.Log("UnityEvo:ResultMessageEntity" + authResponse.data);
|
||||
if (authResponse.code == 200)
|
||||
{
|
||||
var authResponseData =
|
||||
JsonConvert.DeserializeObject<AuthenticationResponse>(authResponse.data.ToString());
|
||||
Debug.Log("UnityEvo:AuthenticationResponse" + authResponseData.Token);
|
||||
authorization = authResponseData.Token;
|
||||
#if UNITY_EDITOR
|
||||
CustomEditorPrefs.SetString("Authorization", authorization);
|
||||
#else
|
||||
CustomPlayerPrefs.SetString("Authorization",authorization);
|
||||
#endif
|
||||
|
||||
Debug.Log("UnityEvo:登录成功");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("UnityEvo:WebRequestSystem.Login" + e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GET请求数据
|
||||
/// </summary>
|
||||
/// <param name="url">请求数据的URL地址</param>
|
||||
/// <param name="token">token验证的参数,此处为authorization</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<bool> GetValidateToken(string url)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
authorization = CustomEditorPrefs.GetString("Authorization");
|
||||
#else
|
||||
authorization = CustomPlayerPrefs.GetString("Authorization");
|
||||
#endif
|
||||
try
|
||||
{
|
||||
using var webRequest =
|
||||
new UnityWebRequest($"{url}?token={authorization}", UnityWebRequest.kHttpVerbGET);
|
||||
//using UnityWebRequest webRequest = UnityWebRequest.Get($"{url}?token={authorization}");
|
||||
webRequest.downloadHandler = new DownloadHandlerBuffer();
|
||||
webRequest.timeout = 10;
|
||||
await webRequest.SendWebRequest();
|
||||
// 增强错误处理
|
||||
if (webRequest.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
var errorMsg = $"HTTP {webRequest.responseCode}\n" +
|
||||
$"URL: {url}\n" +
|
||||
$"Error: {webRequest.error}\n" +
|
||||
$"Response: {webRequest.downloadHandler.text}";
|
||||
|
||||
Debug.LogError(errorMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
var resultMessageEntity =
|
||||
JsonConvert.DeserializeObject<ResultMessageEntity>(webRequest.downloadHandler.text);
|
||||
if (resultMessageEntity.code == 200)
|
||||
return true; // 添加返回值
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("UnityEvo:WebRequestSystem.GetValidateToken" + e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// POST请求数据
|
||||
/// </summary>
|
||||
/// <param name="url">获取Token值的服务URL地址(很重要)</param>
|
||||
/// <param name="postData">传入请求的参数,此处参数为JOSN格式</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<ResultMessageEntity> PostFile(string url, string[] path,
|
||||
Dictionary<string, string> headers = null, Action<float> uploadProgress = null)
|
||||
{
|
||||
//UnityWebRequest[] files = new UnityWebRequest[3];
|
||||
var form = new WWWForm();
|
||||
|
||||
for (var i = 0; i < path.Length; i++)
|
||||
{
|
||||
var bytes = await File.ReadAllBytesAsync(path[i]);
|
||||
form.AddBinaryData("files[]", bytes, Path.GetFileName(path[i]));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var webRequest = UnityWebRequest.Post(url, form);
|
||||
|
||||
webRequest.SetRequestHeader("Authorization", authorization);
|
||||
if (headers != null)
|
||||
foreach (var header in headers)
|
||||
webRequest.SetRequestHeader(header.Key, header.Value);
|
||||
|
||||
webRequest.disposeUploadHandlerOnDispose = true;
|
||||
webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
webRequest.disposeCertificateHandlerOnDispose = true;
|
||||
webRequest.timeout = 60;
|
||||
|
||||
// 发送请求但不等待完成
|
||||
var operation = webRequest.SendWebRequest();
|
||||
// 轮询获取上传进度
|
||||
while (!operation.isDone)
|
||||
{
|
||||
// 调用进度回调函数
|
||||
uploadProgress?.Invoke(webRequest.uploadProgress);
|
||||
// 等待一帧,避免阻塞
|
||||
await UniTask.Yield();
|
||||
}
|
||||
|
||||
webRequest.uploadHandler?.Dispose();
|
||||
// 更新错误检查方式
|
||||
if (webRequest.result == UnityWebRequest.Result.ConnectionError ||
|
||||
webRequest.result == UnityWebRequest.Result.ProtocolError)
|
||||
{
|
||||
Debug.LogError(webRequest.error);
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 5001,
|
||||
message = webRequest.error
|
||||
};
|
||||
}
|
||||
|
||||
var resultMessageEntity =
|
||||
JsonConvert.DeserializeObject<ResultMessageEntity>(webRequest.downloadHandler.text);
|
||||
if (resultMessageEntity.code != 200) Debug.LogError("上传异常,无文件数据返回!!");
|
||||
|
||||
return resultMessageEntity;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("UnityEvo:WebRequestSystem.PostFile" + e.Message);
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 5001,
|
||||
message = e.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GET请求数据
|
||||
/// </summary>
|
||||
/// <param name="url">请求数据的URL地址</param>
|
||||
/// <param name="token">token验证的参数,此处为authorization</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<ResultMessageEntity> GetFile(string url, string tempPath,
|
||||
Action<float> downloadProgress = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var webRequest = UnityWebRequest.Get(url);
|
||||
webRequest.downloadHandler = new DownloadHandlerFile(tempPath);
|
||||
if (authorization != null)
|
||||
webRequest.SetRequestHeader("Authorization", authorization); // 修正请求头名称规范
|
||||
|
||||
|
||||
var operation = webRequest.SendWebRequest();
|
||||
while (!operation.isDone)
|
||||
{
|
||||
downloadProgress?.Invoke(webRequest.downloadProgress);
|
||||
await UniTask.Yield();
|
||||
}
|
||||
|
||||
// 增强错误处理
|
||||
if (webRequest.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
var errorMsg = $"HTTP {webRequest.responseCode}\n" +
|
||||
$"URL: {url}\n" +
|
||||
$"Error: {webRequest.error}\n";
|
||||
|
||||
Debug.LogError(errorMsg);
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 5001,
|
||||
message = errorMsg
|
||||
};
|
||||
}
|
||||
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 200,
|
||||
message = "下载成功"
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("UnityEvo:WebRequestSystem.GetFile" + e.Message);
|
||||
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 5001,
|
||||
message = e.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GET请求数据
|
||||
/// 携带数据:否
|
||||
/// 幂等性:是
|
||||
/// </summary>
|
||||
/// <param name="url">请求数据的URL地址</param>
|
||||
/// <param name="path">请求数据的路径</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<T> Get<T>(string url, string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fullUrl = url.TrimEnd('/') + "/" + path.TrimStart('/');
|
||||
using var webRequest = new UnityWebRequest(fullUrl, UnityWebRequest.kHttpVerbGET);
|
||||
webRequest.downloadHandler = new DownloadHandlerBuffer();
|
||||
if (authorization != null)
|
||||
webRequest.SetRequestHeader("Authorization", authorization); // 修正请求头名称规范
|
||||
|
||||
webRequest.timeout = 20;
|
||||
await webRequest.SendWebRequest();
|
||||
|
||||
// 增强错误处理
|
||||
if (webRequest.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
var errorMsg = $"HTTP {webRequest.responseCode}\n" +
|
||||
$"URL: {url}\n" +
|
||||
$"Error: {webRequest.error}\n" +
|
||||
$"Response: {webRequest.downloadHandler.text}";
|
||||
|
||||
Debug.LogError(errorMsg);
|
||||
}
|
||||
|
||||
var resultMessageEntity =
|
||||
JsonConvert.DeserializeObject<T>(webRequest.downloadHandler.text);
|
||||
|
||||
|
||||
return resultMessageEntity;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("UnityEvo:WebRequestSystem.Get" + e.Message);
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// POST请求数据
|
||||
/// 携带数据:是
|
||||
/// 幂等性:否
|
||||
/// </summary>
|
||||
/// <param name="url">获取Token值的服务URL地址(很重要)</param>
|
||||
/// <param name="postData">传入请求的参数,此处参数为JOSN格式</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<ResultMessageEntity> Post(string url, string postData)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var webRequest = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
|
||||
// #if UNITY_2021_3_OR_NEWER
|
||||
// using (UnityWebRequest webRequest = UnityWebRequest.PostWwwForm(url, postData)) //第二种写法此行注释
|
||||
// #else
|
||||
// using (UnityWebRequest webRequest = UnityWebRequest.PostWwwForm(url, postData)) //第二种写法此行注释
|
||||
// #endif
|
||||
webRequest.downloadHandler = new DownloadHandlerBuffer();
|
||||
var postBytes = Encoding.UTF8.GetBytes(postData);
|
||||
webRequest.uploadHandler = new UploadHandlerRaw(postBytes);
|
||||
webRequest.SetRequestHeader("Content-Type", "application/json");
|
||||
webRequest.SetRequestHeader("Authorization", authorization);
|
||||
webRequest.disposeUploadHandlerOnDispose = true;
|
||||
webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
webRequest.disposeCertificateHandlerOnDispose = true;
|
||||
webRequest.timeout = 30;
|
||||
await webRequest.SendWebRequest();
|
||||
webRequest.uploadHandler?.Dispose();
|
||||
// 更新错误检查方式
|
||||
if (webRequest.result == UnityWebRequest.Result.ConnectionError ||
|
||||
webRequest.result == UnityWebRequest.Result.ProtocolError)
|
||||
{
|
||||
Debug.LogError(webRequest.error);
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 5001,
|
||||
message = webRequest.error
|
||||
};
|
||||
}
|
||||
|
||||
var resultMessageEntity =
|
||||
JsonConvert.DeserializeObject<ResultMessageEntity>(webRequest.downloadHandler.text);
|
||||
if (resultMessageEntity.code != 200) Debug.LogError(resultMessageEntity.message);
|
||||
|
||||
return resultMessageEntity;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("UnityEvo:WebRequestSystem.Post" + e.Message);
|
||||
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 5001,
|
||||
message = e.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Delete请求数据
|
||||
/// 携带数据:否
|
||||
/// 幂等性:是
|
||||
/// </summary>
|
||||
/// <param name="url">请求数据的URL地址</param>
|
||||
/// <param name="path">请求数据的路径</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<ResultMessageEntity> Delete(string url, string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 修复URL拼接
|
||||
var fullUrl = url.TrimEnd('/') + "/" + path.TrimStart('/');
|
||||
using var webRequest = new UnityWebRequest(fullUrl, UnityWebRequest.kHttpVerbDELETE);
|
||||
webRequest.downloadHandler = new DownloadHandlerBuffer();
|
||||
if (authorization != null)
|
||||
webRequest.SetRequestHeader("Authorization", authorization); // 修正请求头名称规范
|
||||
|
||||
webRequest.timeout = 20;
|
||||
await webRequest.SendWebRequest();
|
||||
|
||||
// 增强错误处理
|
||||
if (webRequest.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
var errorMsg = $"HTTP {webRequest.responseCode}\n" +
|
||||
$"URL: {url}\n" +
|
||||
$"Error: {webRequest.error}\n" +
|
||||
$"Response: {webRequest.downloadHandler.text}";
|
||||
|
||||
Debug.LogError(errorMsg);
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 5001,
|
||||
message = errorMsg
|
||||
};
|
||||
}
|
||||
|
||||
// 修复空响应处理
|
||||
var responseText = webRequest.downloadHandler.text;
|
||||
if (string.IsNullOrEmpty(responseText))
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 200,
|
||||
message = "删除成功"
|
||||
};
|
||||
|
||||
var resultMessageEntity =
|
||||
JsonConvert.DeserializeObject<ResultMessageEntity>(webRequest.downloadHandler.text);
|
||||
if (resultMessageEntity.code != 200) Debug.LogError(resultMessageEntity.message);
|
||||
|
||||
return resultMessageEntity;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("UnityEvo:WebRequestSystem.Get" + e.Message);
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 5001,
|
||||
message = e.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PUT请求数据
|
||||
/// 携带数据:是
|
||||
/// 幂等性:是
|
||||
/// </summary>
|
||||
/// <param name="url">请求数据的URL地址</param>
|
||||
/// <param name="path">请求数据的路径</param>
|
||||
/// <param name="putData">要更新的数据(JSON格式)</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<ResultMessageEntity> Put(string url, string putData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 修复URL拼接
|
||||
|
||||
using var webRequest = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPUT);
|
||||
|
||||
// 设置上传处理器
|
||||
var putBytes = Encoding.UTF8.GetBytes(putData);
|
||||
webRequest.uploadHandler = new UploadHandlerRaw(putBytes);
|
||||
webRequest.downloadHandler = new DownloadHandlerBuffer();
|
||||
|
||||
// 设置请求头
|
||||
webRequest.SetRequestHeader("Content-Type", "application/json");
|
||||
if (authorization != null)
|
||||
webRequest.SetRequestHeader("Authorization", authorization); // 修正请求头名称规范
|
||||
|
||||
webRequest.timeout = 20;
|
||||
await webRequest.SendWebRequest();
|
||||
|
||||
// 增强错误处理
|
||||
if (webRequest.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
var errorMsg = $"HTTP {webRequest.responseCode}\n" +
|
||||
$"URL: {url}\n" +
|
||||
$"Error: {webRequest.error}\n" +
|
||||
$"Response: {webRequest.downloadHandler.text}";
|
||||
|
||||
Debug.LogError(errorMsg);
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 5001,
|
||||
message = errorMsg
|
||||
};
|
||||
}
|
||||
|
||||
// 处理空响应
|
||||
var responseText = webRequest.downloadHandler.text;
|
||||
if (string.IsNullOrEmpty(responseText))
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 200,
|
||||
message = "更新成功"
|
||||
};
|
||||
|
||||
var resultMessageEntity =
|
||||
JsonConvert.DeserializeObject<ResultMessageEntity>(webRequest.downloadHandler.text);
|
||||
if (resultMessageEntity.code != 200) Debug.LogError(resultMessageEntity.message);
|
||||
|
||||
return resultMessageEntity;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("UnityEvo:WebRequestSystem.Put" + e.Message);
|
||||
return new ResultMessageEntity
|
||||
{
|
||||
code = 5001,
|
||||
message = e.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Script/WebRequestSystem.cs.meta
Normal file
3
Assets/Script/WebRequestSystem.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c54940c4eaf5c34c8b143ec9c131d53
|
||||
timeCreated: 1741230908
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using UnityEngine;
|
||||
@@ -11,17 +10,14 @@ namespace Unity.RenderStreaming
|
||||
{
|
||||
public class MessageChannel : DataChannelBase
|
||||
{
|
||||
public event Action<string, UserInfo> OnUserInfoMessageReceived;
|
||||
public event Action<string, MediaStateChange> OnMediaStateChangeReceived;
|
||||
private const int MAX_HISTORY = 100;
|
||||
|
||||
[Header("消息记录")] [SerializeField, TextArea(1, 3)]
|
||||
[Header("消息记录")] [SerializeField] [TextArea(1, 3)]
|
||||
private string lastReceivedMessage;
|
||||
|
||||
[SerializeField] private int receivedMessageCount;
|
||||
|
||||
[SerializeField] private List<MessageRecord> messageHistory = new List<MessageRecord>();
|
||||
|
||||
private const int MAX_HISTORY = 100;
|
||||
[SerializeField] private List<MessageRecord> messageHistory = new();
|
||||
|
||||
public IReadOnlyList<MessageRecord> MessageHistory => messageHistory;
|
||||
public int ReceivedMessageCount => receivedMessageCount;
|
||||
@@ -31,18 +27,18 @@ namespace Unity.RenderStreaming
|
||||
label = "on-message";
|
||||
}
|
||||
|
||||
public event Action<string, UserInfo> OnUserInfoMessageReceived;
|
||||
public event Action<string, MediaStateChange> OnMediaStateChangeReceived;
|
||||
|
||||
public override void OnMessage(string message)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Log($"[MessageChannel] Received: {message}");
|
||||
var record = JsonConvert.DeserializeObject<MessageRecord>(message);
|
||||
if (record == null)
|
||||
{
|
||||
record = new MessageRecord { type = "raw", data = 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;
|
||||
ConnectionId = record.connectionId;
|
||||
JObject json = null;
|
||||
switch (record.type)
|
||||
{
|
||||
@@ -79,9 +75,9 @@ namespace Unity.RenderStreaming
|
||||
var record = new MessageRecord
|
||||
{
|
||||
type = type,
|
||||
data = JsonConvert.SerializeObject(data)
|
||||
data = data
|
||||
};
|
||||
string json = JsonConvert.SerializeObject(record);
|
||||
var json = JsonConvert.SerializeObject(record);
|
||||
Send(json);
|
||||
|
||||
record.isSent = true;
|
||||
@@ -90,14 +86,6 @@ namespace Unity.RenderStreaming
|
||||
messageHistory.RemoveAt(0);
|
||||
}
|
||||
|
||||
public void SendMessage(string message)
|
||||
{
|
||||
Send(message);
|
||||
var record = new MessageRecord { type = "raw", data = message, isSent = true };
|
||||
messageHistory.Add(record);
|
||||
if (messageHistory.Count > MAX_HISTORY)
|
||||
messageHistory.RemoveAt(0);
|
||||
}
|
||||
|
||||
public void ClearHistory()
|
||||
{
|
||||
@@ -110,11 +98,11 @@ namespace Unity.RenderStreaming
|
||||
public class MessageRecord
|
||||
{
|
||||
public string type;
|
||||
public object data;
|
||||
public bool isSent;
|
||||
public string timestamp = DateTime.Now.ToString();
|
||||
public string connectionId;
|
||||
public string participantId;
|
||||
public object data;
|
||||
}
|
||||
}
|
||||
}
|
||||
85
Assets/Script/WebRtc/SignalingMessageHelper.cs
Normal file
85
Assets/Script/WebRtc/SignalingMessageHelper.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
// Assets/Script/WebRtc/SignalingMessageHelper.cs
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.RenderStreaming
|
||||
{
|
||||
public static class SignalingMessageHelper
|
||||
{
|
||||
private static object _webSocketSignaling;
|
||||
private static MethodInfo _sendRawMessageMethod;
|
||||
|
||||
static SignalingMessageHelper()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private static void Initialize()
|
||||
{
|
||||
try
|
||||
{
|
||||
var signalingManager = GameObject.FindObjectOfType<SignalingManager>();
|
||||
if (signalingManager == null)
|
||||
{
|
||||
Debug.LogWarning("SignalingMessageHelper: 找不到 SignalingManager");
|
||||
return;
|
||||
}
|
||||
|
||||
var managerInternalField = typeof(SignalingManager).GetField("m_instance",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var managerInternal = managerInternalField.GetValue(signalingManager);
|
||||
|
||||
if (managerInternal == null)
|
||||
{
|
||||
Debug.LogWarning("SignalingMessageHelper: SignalingManager 内部实例为空");
|
||||
return;
|
||||
}
|
||||
|
||||
var signalingField = managerInternal.GetType().GetField("_signaling",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
_webSocketSignaling = signalingField.GetValue(managerInternal);
|
||||
|
||||
if (_webSocketSignaling == null)
|
||||
{
|
||||
Debug.LogWarning("SignalingMessageHelper: WebSocketSignaling 实例为空");
|
||||
return;
|
||||
}
|
||||
|
||||
_sendRawMessageMethod = _webSocketSignaling.GetType().GetMethod("SendMessage");
|
||||
if (_sendRawMessageMethod == null) Debug.LogWarning("SignalingMessageHelper: 找不到 SendRawMessage 方法");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"SignalingMessageHelper 初始化失败: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static bool SendMessage(string message)
|
||||
{
|
||||
if (_webSocketSignaling == null || _sendRawMessageMethod == null)
|
||||
{
|
||||
Debug.LogError("SignalingMessageHelper 未正确初始化,请确保 WebSocketSignaling 已启动");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_sendRawMessageMethod.Invoke(_webSocketSignaling, new[] { message });
|
||||
Debug.Log("消息已发送到服务端");
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"发送消息失败: {e.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsReady()
|
||||
{
|
||||
return _webSocketSignaling != null && _sendRawMessageMethod != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Script/WebRtc/SignalingMessageHelper.cs.meta
Normal file
11
Assets/Script/WebRtc/SignalingMessageHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cee7bdd2c1f4deb4f9abcfba0ec09ddd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user