Fix : 저사양 태블릿 웹사이트 반영 버그 수정
This commit is contained in:
parent
11be1ead86
commit
7f512ca031
BIN
Assets/Resources/StreamingleDashboard/dashboard_script.txt
(Stored with Git LFS)
BIN
Assets/Resources/StreamingleDashboard/dashboard_script.txt
(Stored with Git LFS)
Binary file not shown.
@ -47,6 +47,12 @@ public class StreamDeckServerManager : MonoBehaviour
|
|||||||
private float lastPingTime = 0f;
|
private float lastPingTime = 0f;
|
||||||
private const float WsPingInterval = 5f;
|
private const float WsPingInterval = 5f;
|
||||||
|
|
||||||
|
// 브로드캐스트 coalescing: 같은 프레임에 여러 번 Notify*() 호출되어도 프레임 끝에 1회만 송신
|
||||||
|
private bool pendingCameraNotify, pendingItemNotify, pendingEventNotify, pendingAvatarNotify;
|
||||||
|
// Origin 클라이언트 추적: ProcessMessage 실행 중인 서비스 (낙관적 UI 에코 억제용)
|
||||||
|
private StreamDeckService currentOriginator;
|
||||||
|
private string cameraOriginId, itemOriginId, eventOriginId, avatarOriginId;
|
||||||
|
|
||||||
// 카메라 프리뷰 내부 상태
|
// 카메라 프리뷰 내부 상태
|
||||||
private readonly List<Camera> previewCameraPool = new List<Camera>();
|
private readonly List<Camera> previewCameraPool = new List<Camera>();
|
||||||
private RenderTexture previewRT;
|
private RenderTexture previewRT;
|
||||||
@ -124,6 +130,9 @@ public class StreamDeckServerManager : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 프레임 내 누적된 state 변경을 1회씩만 브로드캐스트 (저사양 클라이언트 렌더 부하 경감)
|
||||||
|
FlushPendingBroadcasts();
|
||||||
|
|
||||||
// WebSocket 프로토콜 레벨 ping — WiFi 라우터의 유휴 연결 드롭 방지
|
// WebSocket 프로토콜 레벨 ping — WiFi 라우터의 유휴 연결 드롭 방지
|
||||||
if (Time.time - lastPingTime >= WsPingInterval)
|
if (Time.time - lastPingTime >= WsPingInterval)
|
||||||
{
|
{
|
||||||
@ -274,7 +283,8 @@ public class StreamDeckServerManager : MonoBehaviour
|
|||||||
version = "1.0",
|
version = "1.0",
|
||||||
data = new
|
data = new
|
||||||
{
|
{
|
||||||
session_id = Guid.NewGuid().ToString(),
|
// session_id는 WebSocketBehavior.ID 사용 — NotifyXxx에서 origin_session으로 그대로 에코됨
|
||||||
|
session_id = service.ID,
|
||||||
message = "유니티 서버에 연결되었습니다!",
|
message = "유니티 서버에 연결되었습니다!",
|
||||||
camera_data = cameraManager.GetCameraListData(),
|
camera_data = cameraManager.GetCameraListData(),
|
||||||
current_camera = cameraManager.GetCurrentCameraState(),
|
current_camera = cameraManager.GetCurrentCameraState(),
|
||||||
@ -294,13 +304,40 @@ public class StreamDeckServerManager : MonoBehaviour
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Broadcast Notifications
|
#region Broadcast Notifications
|
||||||
|
// Notify*()는 상태 변경 플래그만 세우고, Update() 말미 FlushPendingBroadcasts에서 프레임당 1회만 실제 송신.
|
||||||
|
// 다수의 연쇄 변경(예: avatar 전환 → item reset → ... )이 프레임 내 발생해도 클라이언트에는 1회 렌더만 유발.
|
||||||
public void NotifyCameraChanged()
|
public void NotifyCameraChanged()
|
||||||
{
|
{
|
||||||
if (cameraManager == null) return;
|
pendingCameraNotify = true;
|
||||||
|
cameraOriginId = currentOriginator?.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NotifyItemChanged()
|
||||||
|
{
|
||||||
|
pendingItemNotify = true;
|
||||||
|
itemOriginId = currentOriginator?.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NotifyEventChanged()
|
||||||
|
{
|
||||||
|
pendingEventNotify = true;
|
||||||
|
eventOriginId = currentOriginator?.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NotifyAvatarOutfitChanged()
|
||||||
|
{
|
||||||
|
pendingAvatarNotify = true;
|
||||||
|
avatarOriginId = currentOriginator?.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FlushPendingBroadcasts()
|
||||||
|
{
|
||||||
|
if (pendingCameraNotify && cameraManager != null)
|
||||||
|
{
|
||||||
BroadcastJson(new
|
BroadcastJson(new
|
||||||
{
|
{
|
||||||
type = "camera_changed",
|
type = "camera_changed",
|
||||||
|
origin_session = cameraOriginId,
|
||||||
timestamp = DateTime.UtcNow.ToString("o"),
|
timestamp = DateTime.UtcNow.ToString("o"),
|
||||||
version = "1.0",
|
version = "1.0",
|
||||||
data = new
|
data = new
|
||||||
@ -309,15 +346,15 @@ public class StreamDeckServerManager : MonoBehaviour
|
|||||||
current_camera = cameraManager.GetCurrentCameraState()
|
current_camera = cameraManager.GetCurrentCameraState()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
pendingCameraNotify = false;
|
||||||
|
cameraOriginId = null;
|
||||||
}
|
}
|
||||||
|
if (pendingItemNotify && itemController != null)
|
||||||
public void NotifyItemChanged()
|
|
||||||
{
|
{
|
||||||
if (itemController == null) return;
|
|
||||||
|
|
||||||
BroadcastJson(new
|
BroadcastJson(new
|
||||||
{
|
{
|
||||||
type = "item_changed",
|
type = "item_changed",
|
||||||
|
origin_session = itemOriginId,
|
||||||
timestamp = DateTime.UtcNow.ToString("o"),
|
timestamp = DateTime.UtcNow.ToString("o"),
|
||||||
version = "1.0",
|
version = "1.0",
|
||||||
data = new
|
data = new
|
||||||
@ -326,15 +363,15 @@ public class StreamDeckServerManager : MonoBehaviour
|
|||||||
current_item = itemController.GetCurrentItemState()
|
current_item = itemController.GetCurrentItemState()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
pendingItemNotify = false;
|
||||||
|
itemOriginId = null;
|
||||||
}
|
}
|
||||||
|
if (pendingEventNotify && eventController != null)
|
||||||
public void NotifyEventChanged()
|
|
||||||
{
|
{
|
||||||
if (eventController == null) return;
|
|
||||||
|
|
||||||
BroadcastJson(new
|
BroadcastJson(new
|
||||||
{
|
{
|
||||||
type = "event_changed",
|
type = "event_changed",
|
||||||
|
origin_session = eventOriginId,
|
||||||
timestamp = DateTime.UtcNow.ToString("o"),
|
timestamp = DateTime.UtcNow.ToString("o"),
|
||||||
version = "1.0",
|
version = "1.0",
|
||||||
data = new
|
data = new
|
||||||
@ -343,15 +380,15 @@ public class StreamDeckServerManager : MonoBehaviour
|
|||||||
current_event = eventController.GetCurrentEventState()
|
current_event = eventController.GetCurrentEventState()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
pendingEventNotify = false;
|
||||||
|
eventOriginId = null;
|
||||||
}
|
}
|
||||||
|
if (pendingAvatarNotify && avatarOutfitController != null)
|
||||||
public void NotifyAvatarOutfitChanged()
|
|
||||||
{
|
{
|
||||||
if (avatarOutfitController == null) return;
|
|
||||||
|
|
||||||
BroadcastJson(new
|
BroadcastJson(new
|
||||||
{
|
{
|
||||||
type = "avatar_outfit_changed",
|
type = "avatar_outfit_changed",
|
||||||
|
origin_session = avatarOriginId,
|
||||||
timestamp = DateTime.UtcNow.ToString("o"),
|
timestamp = DateTime.UtcNow.ToString("o"),
|
||||||
version = "1.0",
|
version = "1.0",
|
||||||
data = new
|
data = new
|
||||||
@ -360,6 +397,9 @@ public class StreamDeckServerManager : MonoBehaviour
|
|||||||
current_avatar_outfit = avatarOutfitController.GetCurrentAvatarOutfitState()
|
current_avatar_outfit = avatarOutfitController.GetCurrentAvatarOutfitState()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
pendingAvatarNotify = false;
|
||||||
|
avatarOriginId = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BroadcastJson(object data)
|
private void BroadcastJson(object data)
|
||||||
@ -375,6 +415,13 @@ public class StreamDeckServerManager : MonoBehaviour
|
|||||||
var message = JsonConvert.DeserializeObject<Dictionary<string, object>>(messageData);
|
var message = JsonConvert.DeserializeObject<Dictionary<string, object>>(messageData);
|
||||||
string messageType = message.ContainsKey("type") ? message["type"].ToString() : null;
|
string messageType = message.ContainsKey("type") ? message["type"].ToString() : null;
|
||||||
|
|
||||||
|
currentOriginator = service;
|
||||||
|
try { ProcessMessageInner(message, messageType, messageData, service); }
|
||||||
|
finally { currentOriginator = null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessMessageInner(Dictionary<string, object> message, string messageType, string messageData, StreamDeckService service)
|
||||||
|
{
|
||||||
switch (messageType)
|
switch (messageType)
|
||||||
{
|
{
|
||||||
// 카메라
|
// 카메라
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user