diff --git a/Assets/Infrastructure/Network/Configs.meta b/Assets/Infrastructure/Network/Configs.meta
deleted file mode 100644
index b8432f4..0000000
--- a/Assets/Infrastructure/Network/Configs.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: fd48a88d389f79249986de098143c22f
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Infrastructure/Network/Configs/NetworkConfig.cs b/Assets/Infrastructure/Network/Configs/NetworkConfig.cs
deleted file mode 100644
index e69bdde..0000000
--- a/Assets/Infrastructure/Network/Configs/NetworkConfig.cs
+++ /dev/null
@@ -1,404 +0,0 @@
-using UnityEngine;
-
-namespace ProjectVG.Infrastructure.Network.Configs
-{
- ///
- /// Unity 표준 방식의 네트워크 설정 ScriptableObject
- /// Editor에서 설정 가능하고, 런타임에서는 정적 접근자로 사용
- ///
- [CreateAssetMenu(fileName = "NetworkConfig", menuName = "ProjectVG/Network/NetworkConfig")]
- public class NetworkConfig : ScriptableObject
- {
- [Header("Environment Settings")]
- [SerializeField] private EnvironmentType environment = EnvironmentType.Development;
-
- [Header("Server Addresses")]
- [SerializeField] private string developmentServer = "localhost:7900";
- [SerializeField] private string testServer = "localhost:7900";
- [SerializeField] private string productionServer = "122.153.130.223:7900";
-
- [Header("HTTP API Settings")]
- [SerializeField] private string apiVersion = "v1";
- [SerializeField] private string apiPath = "api";
- [SerializeField] private float httpTimeout = 30f;
- [SerializeField] private int maxRetryCount = 3;
- [SerializeField] private float retryDelay = 1f;
-
- [Header("WebSocket Settings")]
- [SerializeField] private string wsPath = "ws";
- [SerializeField] private float wsTimeout = 30f;
- [SerializeField] private float reconnectDelay = 5f;
- [SerializeField] private int maxReconnectAttempts = 3;
- [SerializeField] private bool autoReconnect = true;
- [SerializeField] private float heartbeatInterval = 30f;
- [SerializeField] private bool enableHeartbeat = true;
- [SerializeField] private int maxMessageSize = 65536; // 64KB
- [SerializeField] private float messageTimeout = 10f;
- [SerializeField] private bool enableMessageLogging = true;
- [SerializeField] private string wsMessageType = "json"; // "json" 또는 "binary"
-
- [Header("Common Settings")]
- [SerializeField] private string userAgent = "ProjectVG-Client/1.0";
- [SerializeField] private string contentType = "application/json";
-
- // Environment enum
- public enum EnvironmentType
- {
- Development,
- Test,
- Production
- }
-
- // Singleton instance
- private static NetworkConfig _instance;
- public static NetworkConfig Instance
- {
- get
- {
- if (_instance == null)
- {
- _instance = Resources.Load("NetworkConfig");
- if (_instance == null)
- {
- Debug.LogError("NetworkConfig를 찾을 수 없습니다. Resources 폴더에 NetworkConfig.asset 파일을 생성하세요.");
- _instance = CreateDefaultInstance();
- }
- }
- return _instance;
- }
- }
-
- // Properties
- public EnvironmentType Environment => environment;
- public string ApiPath => apiPath;
- public string WsPath => wsPath;
-
-
-
- #region Environment Configuration
-
-
-
- #endregion
-
- #region Static Accessors (편의 메서드들)
-
- ///
- /// 현재 환경
- ///
- public static EnvironmentType CurrentEnvironment => Instance.Environment;
-
- ///
- /// HTTP 서버 주소
- ///
- public static string HttpServerAddress
- {
- get
- {
- string server;
- switch (Instance.environment)
- {
- case EnvironmentType.Development:
- server = Instance.developmentServer;
- break;
- case EnvironmentType.Test:
- server = Instance.testServer;
- break;
- case EnvironmentType.Production:
- server = Instance.productionServer;
- break;
- default:
- server = Instance.developmentServer;
- break;
- }
- return $"http://{server}";
- }
- }
-
- ///
- /// WebSocket 서버 주소
- ///
- public static string WebSocketServerAddress
- {
- get
- {
- string server;
- switch (Instance.environment)
- {
- case EnvironmentType.Development:
- server = Instance.developmentServer;
- break;
- case EnvironmentType.Test:
- server = Instance.testServer;
- break;
- case EnvironmentType.Production:
- server = Instance.productionServer;
- break;
- default:
- server = Instance.developmentServer;
- break;
- }
- return $"ws://{server}";
- }
- }
-
- ///
- /// API 버전
- ///
- public static string ApiVersion => Instance.apiVersion;
-
- ///
- /// HTTP 타임아웃
- ///
- public static float HttpTimeout => Instance.httpTimeout;
-
- ///
- /// 최대 재시도 횟수
- ///
- public static int MaxRetryCount => Instance.maxRetryCount;
-
- ///
- /// 재시도 지연 시간
- ///
- public static float RetryDelay => Instance.retryDelay;
-
- ///
- /// WebSocket 타임아웃
- ///
- public static float WebSocketTimeout => Instance.wsTimeout;
-
- ///
- /// 재연결 지연 시간
- ///
- public static float ReconnectDelay => Instance.reconnectDelay;
-
- ///
- /// 최대 재연결 시도 횟수
- ///
- public static int MaxReconnectAttempts => Instance.maxReconnectAttempts;
-
- ///
- /// 자동 재연결
- ///
- public static bool AutoReconnect => Instance.autoReconnect;
-
- ///
- /// 하트비트 간격
- ///
- public static float HeartbeatInterval => Instance.heartbeatInterval;
-
- ///
- /// 하트비트 활성화
- ///
- public static bool EnableHeartbeat => Instance.enableHeartbeat;
-
- ///
- /// 최대 메시지 크기
- ///
- public static int MaxMessageSize => Instance.maxMessageSize;
-
- ///
- /// 메시지 타임아웃
- ///
- public static float MessageTimeout => Instance.messageTimeout;
-
- ///
- /// 메시지 로깅 활성화
- ///
- public static bool EnableMessageLogging => Instance.enableMessageLogging;
-
- ///
- /// WebSocket 메시지 타입
- ///
- public static string WebSocketMessageType => Instance.wsMessageType;
-
- ///
- /// JSON 메시지 타입인지 확인
- ///
- public static bool IsJsonMessageType => Instance.wsMessageType?.ToLower() == "json";
-
- ///
- /// 바이너리 메시지 타입인지 확인
- ///
- public static bool IsBinaryMessageType => Instance.wsMessageType?.ToLower() == "binary";
-
- ///
- /// 사용자 에이전트
- ///
- public static string UserAgent => Instance.userAgent;
-
- ///
- /// 콘텐츠 타입
- ///
- public static string ContentType => Instance.contentType;
-
- ///
- /// 전체 API URL 생성
- ///
- public static string GetFullApiUrl(string endpoint)
- {
- var baseUrl = HttpServerAddress;
- return $"{baseUrl.TrimEnd('/')}/{Instance.apiPath.TrimStart('/').TrimEnd('/')}/{Instance.apiVersion.TrimStart('/').TrimEnd('/')}/{endpoint.TrimStart('/')}";
- }
-
- ///
- /// 사용자 API URL
- ///
- public static string GetUserApiUrl(string path = "")
- {
- return GetFullApiUrl($"users/{path.TrimStart('/')}");
- }
-
- ///
- /// 캐릭터 API URL
- ///
- public static string GetCharacterApiUrl(string path = "")
- {
- return GetFullApiUrl($"characters/{path.TrimStart('/')}");
- }
-
- ///
- /// 대화 API URL
- ///
- public static string GetConversationApiUrl(string path = "")
- {
- return GetFullApiUrl($"conversations/{path.TrimStart('/')}");
- }
-
- ///
- /// 인증 API URL
- ///
- public static string GetAuthApiUrl(string path = "")
- {
- return GetFullApiUrl($"auth/{path.TrimStart('/')}");
- }
-
- ///
- /// WebSocket URL
- ///
- public static string GetWebSocketUrl()
- {
- var baseUrl = WebSocketServerAddress;
- return $"{baseUrl.TrimEnd('/')}/{Instance.wsPath.TrimStart('/').TrimEnd('/')}";
- }
-
- ///
- /// 버전이 포함된 WebSocket URL
- ///
- public static string GetWebSocketUrlWithVersion()
- {
- var baseUrl = WebSocketServerAddress;
- return $"{baseUrl.TrimEnd('/')}/api/{Instance.apiVersion.TrimStart('/').TrimEnd('/')}/{Instance.wsPath.TrimStart('/').TrimEnd('/')}";
- }
-
- ///
- /// 세션이 포함된 WebSocket URL
- ///
- public static string GetWebSocketUrlWithSession(string sessionId)
- {
- var baseWsUrl = GetWebSocketUrlWithVersion();
- return $"{baseWsUrl}?sessionId={sessionId}";
- }
-
-
- ///
- /// 개발 환경 설정
- ///
- public static void SetDevelopmentEnvironment()
- {
- if (Application.isPlaying)
- {
- Debug.LogWarning("런타임 중에는 환경 설정을 변경할 수 없습니다.");
- return;
- }
-
- Instance.environment = EnvironmentType.Development;
- }
-
- ///
- /// 테스트 환경 설정
- ///
- public static void SetTestEnvironment()
- {
- if (Application.isPlaying)
- {
- Debug.LogWarning("런타임 중에는 환경 설정을 변경할 수 없습니다.");
- return;
- }
-
- Instance.environment = EnvironmentType.Test;
- }
-
- ///
- /// 프로덕션 환경 설정
- ///
- public static void SetProductionEnvironment()
- {
- if (Application.isPlaying)
- {
- Debug.LogWarning("런타임 중에는 환경 설정을 변경할 수 없습니다.");
- return;
- }
-
- Instance.environment = EnvironmentType.Production;
- }
-
- ///
- /// 현재 설정 로그 출력
- ///
- public static void LogCurrentSettings()
- {
- Debug.Log($"=== NetworkConfig 현재 설정 ===");
- Debug.Log($"환경: {CurrentEnvironment}");
- Debug.Log($"HTTP 서버: {HttpServerAddress}");
- Debug.Log($"WebSocket 서버: {WebSocketServerAddress}");
- Debug.Log($"API 버전: {ApiVersion}");
- Debug.Log($"HTTP 타임아웃: {HttpTimeout}s");
- Debug.Log($"WebSocket 타임아웃: {WebSocketTimeout}s");
- Debug.Log($"자동 재연결: {AutoReconnect}");
- Debug.Log($"하트비트: {EnableHeartbeat} ({HeartbeatInterval}s)");
- Debug.Log($"================================");
- }
-
- #endregion
-
- #region Private Methods
-
- ///
- /// 기본 인스턴스 생성 (Resources 폴더에 파일이 없을 때)
- ///
- private static NetworkConfig CreateDefaultInstance()
- {
- var instance = CreateInstance();
-
- // 기본 설정
- instance.environment = EnvironmentType.Development;
- instance.developmentServer = "localhost:7900";
- instance.testServer = "localhost:7900";
- instance.productionServer = "122.153.130.223:7900";
- instance.apiVersion = "v1";
- instance.apiPath = "api";
- instance.httpTimeout = 30f;
- instance.maxRetryCount = 3;
- instance.retryDelay = 1f;
- instance.wsPath = "ws";
- instance.wsTimeout = 30f;
- instance.reconnectDelay = 5f;
- instance.maxReconnectAttempts = 3;
- instance.autoReconnect = true;
- instance.heartbeatInterval = 30f;
- instance.enableHeartbeat = true;
- instance.maxMessageSize = 65536;
- instance.messageTimeout = 10f;
- instance.enableMessageLogging = true;
- instance.userAgent = "ProjectVG-Client/1.0";
- instance.contentType = "application/json";
-
- Debug.LogWarning("기본 NetworkConfig를 생성했습니다. Resources 폴더에 NetworkConfig.asset 파일을 생성하는 것을 권장합니다.");
-
- return instance;
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/Configs/NetworkConfig.cs.meta b/Assets/Infrastructure/Network/Configs/NetworkConfig.cs.meta
deleted file mode 100644
index 233db0c..0000000
--- a/Assets/Infrastructure/Network/Configs/NetworkConfig.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: 86f34d98107a627428323909bc15f04d
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/Configs/ServerConfig.cs b/Assets/Infrastructure/Network/Configs/ServerConfig.cs
deleted file mode 100644
index 8ea77ca..0000000
--- a/Assets/Infrastructure/Network/Configs/ServerConfig.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-namespace ProjectVG.Infrastructure.Network.Configs
-{
- ///
- /// 서버 설정 정보 (현재 미사용)
- /// 서버의 메시지 형식과 지원 기능을 정의합니다.
- /// WebSocket뿐만 아니라 다른 서버 설정도 포함할 수 있습니다.
- ///
- [System.Serializable]
- public class ServerConfig
- {
- ///
- /// 메시지 타입 ("json" 또는 "binary")
- ///
- public string messageType;
-
- ///
- /// 서버 버전
- ///
- public string version;
-
- ///
- /// 오디오 지원 여부
- ///
- public bool supportsAudio;
-
- ///
- /// 바이너리 메시지 지원 여부
- ///
- public bool supportsBinary;
-
- ///
- /// 오디오 형식 (예: "wav", "mp3")
- ///
- public string audioFormat;
-
- ///
- /// 최대 메시지 크기 (바이트)
- ///
- public int maxMessageSize;
-
- ///
- /// JSON 형식인지 확인
- ///
- public bool IsJsonFormat => messageType?.ToLower() == "json";
-
- ///
- /// 바이너리 형식인지 확인
- ///
- public bool IsBinaryFormat => messageType?.ToLower() == "binary";
-
- ///
- /// 설정 정보를 문자열로 반환
- ///
- public override string ToString()
- {
- return $"ServerConfig[Type: {messageType}, Version: {version}, Audio: {supportsAudio}, Binary: {supportsBinary}, Format: {audioFormat}, MaxSize: {maxMessageSize} bytes]";
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/Configs/ServerConfig.cs.meta b/Assets/Infrastructure/Network/Configs/ServerConfig.cs.meta
deleted file mode 100644
index d2afddc..0000000
--- a/Assets/Infrastructure/Network/Configs/ServerConfig.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: aed6fafe9b2afc74c800a2a8ba99570a
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/Configs/ServerConfigLoader.cs b/Assets/Infrastructure/Network/Configs/ServerConfigLoader.cs
deleted file mode 100644
index d5a07db..0000000
--- a/Assets/Infrastructure/Network/Configs/ServerConfigLoader.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-using System;
-using UnityEngine;
-using UnityEngine.Networking;
-using Cysharp.Threading.Tasks;
-using ProjectVG.Infrastructure.Network.Configs;
-
-namespace ProjectVG.Infrastructure.Network.Configs
-{
- ///
- /// 서버 설정 로더 (현재 미사용)
- /// 서버에서 메시지 타입 등의 설정을 동적으로 로드합니다.
- /// WebSocket뿐만 아니라 다른 서버 설정도 로드할 수 있습니다.
- ///
- public static class ServerConfigLoader
- {
- ///
- /// 서버 설정 로드
- ///
- /// 설정 엔드포인트 (기본값: "config")
- /// 서버 설정 또는 null
- public static async UniTask LoadServerConfigAsync(string configEndpoint = "config")
- {
- try
- {
- Debug.Log($"서버 설정 로드 중... (엔드포인트: {configEndpoint})");
-
- var configUrl = NetworkConfig.GetFullApiUrl(configEndpoint);
- using (var request = UnityWebRequest.Get(configUrl))
- {
- request.timeout = 10;
- await request.SendWebRequest();
-
- if (request.result == UnityWebRequest.Result.Success)
- {
- var jsonResponse = request.downloadHandler.text;
- var serverConfig = JsonUtility.FromJson(jsonResponse);
-
- Debug.Log($"서버 설정 로드 완료: {serverConfig.messageType}");
- return serverConfig;
- }
- else
- {
- Debug.LogWarning($"서버 설정 로드 실패: {request.error}");
- return null;
- }
- }
- }
- catch (Exception ex)
- {
- Debug.LogError($"서버 설정 로드 중 오류: {ex.Message}");
- return null;
- }
- }
-
- ///
- /// 서버 설정 유효성 검사
- ///
- /// 서버 설정
- /// 유효한지 여부
- public static bool ValidateServerConfig(ServerConfig config)
- {
- if (config == null)
- {
- Debug.LogWarning("서버 설정이 null입니다.");
- return false;
- }
-
- if (string.IsNullOrEmpty(config.messageType))
- {
- Debug.LogWarning("서버 설정에 메시지 타입이 없습니다.");
- return false;
- }
-
- var messageType = config.messageType.ToLower();
- if (messageType != "json" && messageType != "binary")
- {
- Debug.LogWarning($"지원하지 않는 메시지 타입: {config.messageType}");
- return false;
- }
-
- Debug.Log($"서버 설정 유효성 검사 통과: {config.messageType}");
- return true;
- }
-
- ///
- /// 서버 설정과 NetworkConfig 비교
- ///
- /// 서버 설정
- /// 일치하는지 여부
- public static bool CompareWithNetworkConfig(ServerConfig serverConfig)
- {
- if (serverConfig == null) return false;
-
- var networkConfigType = NetworkConfig.WebSocketMessageType.ToLower();
- var serverConfigType = serverConfig.messageType.ToLower();
-
- var isMatch = networkConfigType == serverConfigType;
-
- if (!isMatch)
- {
- Debug.LogWarning($"NetworkConfig({networkConfigType})와 서버 설정({serverConfigType})이 일치하지 않습니다.");
- }
- else
- {
- Debug.Log($"NetworkConfig와 서버 설정이 일치합니다: {networkConfigType}");
- }
-
- return isMatch;
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/Configs/ServerConfigLoader.cs.meta b/Assets/Infrastructure/Network/Configs/ServerConfigLoader.cs.meta
deleted file mode 100644
index c972348..0000000
--- a/Assets/Infrastructure/Network/Configs/ServerConfigLoader.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: 709b436d429928c4c8da5256aad82347
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs.meta b/Assets/Infrastructure/Network/DTOs.meta
deleted file mode 100644
index 08d2e6f..0000000
--- a/Assets/Infrastructure/Network/DTOs.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 195135de6dfc91948b7c869169221d53
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Infrastructure/Network/DTOs/BaseApiResponse.cs b/Assets/Infrastructure/Network/DTOs/BaseApiResponse.cs
deleted file mode 100644
index cc8bb20..0000000
--- a/Assets/Infrastructure/Network/DTOs/BaseApiResponse.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System;
-
-namespace ProjectVG.Infrastructure.Network.DTOs
-{
- ///
- /// API 응답의 기본 구조
- ///
- [Serializable]
- public class BaseApiResponse
- {
- public bool success;
- public string message;
- public long timestamp;
- public string requestId;
- }
-
- ///
- /// 데이터를 포함하는 API 응답
- ///
- [Serializable]
- public class ApiResponse : BaseApiResponse
- {
- public T data;
- }
-
- ///
- /// 페이지네이션 정보
- ///
- [Serializable]
- public class PaginationInfo
- {
- public int page;
- public int limit;
- public int total;
- public int totalPages;
- public bool hasNext;
- public bool hasPrev;
- }
-
- ///
- /// 페이지네이션된 API 응답
- ///
- [Serializable]
- public class PaginatedApiResponse : BaseApiResponse
- {
- public T[] data;
- public PaginationInfo pagination;
- }
-
- ///
- /// 에러 응답
- ///
- [Serializable]
- public class ErrorResponse : BaseApiResponse
- {
- public string errorCode;
- public string errorType;
- public string[] details;
- }
-}
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/BaseApiResponse.cs.meta b/Assets/Infrastructure/Network/DTOs/BaseApiResponse.cs.meta
deleted file mode 100644
index 7c3ecc0..0000000
--- a/Assets/Infrastructure/Network/DTOs/BaseApiResponse.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: 359796341ec306b42b9219b5fff1feca
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/Character.meta b/Assets/Infrastructure/Network/DTOs/Character.meta
deleted file mode 100644
index 1705825..0000000
--- a/Assets/Infrastructure/Network/DTOs/Character.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 6c376144b261f82498097408eb9c393f
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Infrastructure/Network/DTOs/Character/CharacterInfo.cs b/Assets/Infrastructure/Network/DTOs/Character/CharacterInfo.cs
deleted file mode 100644
index 3db5e85..0000000
--- a/Assets/Infrastructure/Network/DTOs/Character/CharacterInfo.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace ProjectVG.Infrastructure.Network.DTOs.Character
-{
- ///
- /// 캐릭터 정보 DTO
- ///
- [Serializable]
- public class CharacterData
- {
- [SerializeField] public string id;
- [SerializeField] public string name;
- [SerializeField] public string description;
- [SerializeField] public string role;
- [SerializeField] public bool isActive;
- }
-}
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/Character/CharacterInfo.cs.meta b/Assets/Infrastructure/Network/DTOs/Character/CharacterInfo.cs.meta
deleted file mode 100644
index 28feae1..0000000
--- a/Assets/Infrastructure/Network/DTOs/Character/CharacterInfo.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: 4442e4d5ae93e4f4aa37f85e1a2eef48
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/Character/CreateCharacterRequest.cs b/Assets/Infrastructure/Network/DTOs/Character/CreateCharacterRequest.cs
deleted file mode 100644
index 45375d8..0000000
--- a/Assets/Infrastructure/Network/DTOs/Character/CreateCharacterRequest.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace ProjectVG.Infrastructure.Network.DTOs.Character
-{
- ///
- /// 캐릭터 생성 요청 DTO
- ///
- [Serializable]
- public class CreateCharacterRequest
- {
- public string name;
- public string description;
- public string role;
- public bool isActive = true;
- }
-}
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/Character/CreateCharacterRequest.cs.meta b/Assets/Infrastructure/Network/DTOs/Character/CreateCharacterRequest.cs.meta
deleted file mode 100644
index 2cc318b..0000000
--- a/Assets/Infrastructure/Network/DTOs/Character/CreateCharacterRequest.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: 8934f22c6576c584c9a76cd0ca57a5fe
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/Character/UpdateCharacterRequest.cs b/Assets/Infrastructure/Network/DTOs/Character/UpdateCharacterRequest.cs
deleted file mode 100644
index 2cf7044..0000000
--- a/Assets/Infrastructure/Network/DTOs/Character/UpdateCharacterRequest.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace ProjectVG.Infrastructure.Network.DTOs.Character
-{
- ///
- /// 캐릭터 수정 요청 DTO
- ///
- [Serializable]
- public class UpdateCharacterRequest
- {
- public string name;
- public string description;
- public string role;
- public bool isActive;
- }
-}
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/Character/UpdateCharacterRequest.cs.meta b/Assets/Infrastructure/Network/DTOs/Character/UpdateCharacterRequest.cs.meta
deleted file mode 100644
index 51be348..0000000
--- a/Assets/Infrastructure/Network/DTOs/Character/UpdateCharacterRequest.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: 88a11fb1cb2ce8f46a6fd6df981f1854
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/Chat.meta b/Assets/Infrastructure/Network/DTOs/Chat.meta
deleted file mode 100644
index 733db01..0000000
--- a/Assets/Infrastructure/Network/DTOs/Chat.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 45b3af16b93a1e44399f346aed069e31
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Infrastructure/Network/DTOs/Chat/ChatRequest.cs b/Assets/Infrastructure/Network/DTOs/Chat/ChatRequest.cs
deleted file mode 100644
index 247f357..0000000
--- a/Assets/Infrastructure/Network/DTOs/Chat/ChatRequest.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-using UnityEngine;
-using Newtonsoft.Json;
-
-namespace ProjectVG.Infrastructure.Network.DTOs.Chat
-{
- ///
- /// 채팅 요청 DTO (Newtonsoft.Json을 사용하여 snake_case 지원)
- ///
- [Serializable]
- public class ChatRequest
- {
- [JsonProperty("session_id")]
- [SerializeField] public string sessionId;
-
- [JsonProperty("message")]
- [SerializeField] public string message;
-
- [JsonProperty("character_id")]
- [SerializeField] public string characterId;
-
- [JsonProperty("user_id")]
- [SerializeField] public string userId;
-
- [JsonProperty("action")]
- [SerializeField] public string action = "chat";
-
- [JsonProperty("actor")]
- [SerializeField] public string actor;
-
- [JsonProperty("instruction")]
- [SerializeField] public string instruction;
-
- [JsonProperty("requested_at")]
- [SerializeField] public string requestedAt;
- }
-}
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/Chat/ChatRequest.cs.meta b/Assets/Infrastructure/Network/DTOs/Chat/ChatRequest.cs.meta
deleted file mode 100644
index 48b9b22..0000000
--- a/Assets/Infrastructure/Network/DTOs/Chat/ChatRequest.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: 508dce3896fd1a24dbb39ec613bac2df
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/Chat/ChatResponse.cs b/Assets/Infrastructure/Network/DTOs/Chat/ChatResponse.cs
deleted file mode 100644
index 609dafb..0000000
--- a/Assets/Infrastructure/Network/DTOs/Chat/ChatResponse.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-
-namespace ProjectVG.Infrastructure.Network.DTOs.Chat
-{
- ///
- /// 채팅 응답 DTO
- ///
- [Serializable]
- public class ChatResponse
- {
- public bool success;
- public string message;
- public string sessionId;
- }
-}
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/Chat/ChatResponse.cs.meta b/Assets/Infrastructure/Network/DTOs/Chat/ChatResponse.cs.meta
deleted file mode 100644
index 956fddd..0000000
--- a/Assets/Infrastructure/Network/DTOs/Chat/ChatResponse.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: f55f8bd1f455ad54caaea20c4fc09253
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/DTOs/WebSocket.meta b/Assets/Infrastructure/Network/DTOs/WebSocket.meta
deleted file mode 100644
index 461d67b..0000000
--- a/Assets/Infrastructure/Network/DTOs/WebSocket.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 96cf5f40d2d8aab478c179145464c91b
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Infrastructure/Network/Http.meta b/Assets/Infrastructure/Network/Http.meta
deleted file mode 100644
index e5bdd72..0000000
--- a/Assets/Infrastructure/Network/Http.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: a27aa8428fdf0974990bab2179bf081f
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Infrastructure/Network/Http/HttpApiClient.cs b/Assets/Infrastructure/Network/Http/HttpApiClient.cs
deleted file mode 100644
index 9983bfa..0000000
--- a/Assets/Infrastructure/Network/Http/HttpApiClient.cs
+++ /dev/null
@@ -1,386 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using UnityEngine;
-using UnityEngine.Networking;
-using Cysharp.Threading.Tasks;
-using System.Threading;
-using ProjectVG.Infrastructure.Network.Configs;
-using Newtonsoft.Json;
-
-namespace ProjectVG.Infrastructure.Network.Http
-{
- ///
- /// HTTP API 클라이언트
- /// UnityWebRequest를 사용하여 서버와 통신하며, UniTask 기반 비동기 처리를 지원합니다.
- ///
- public class HttpApiClient : MonoBehaviour
- {
- [Header("API Configuration")]
- // NetworkConfig를 사용하여 설정을 관리합니다.
-
- private const string ACCEPT_HEADER = "application/json";
- private const string AUTHORIZATION_HEADER = "Authorization";
- private const string BEARER_PREFIX = "Bearer ";
-
- private readonly Dictionary defaultHeaders = new Dictionary();
- private CancellationTokenSource cancellationTokenSource;
-
- public static HttpApiClient Instance { get; private set; }
-
- #region Unity Lifecycle
-
- private void Awake()
- {
- InitializeSingleton();
- }
-
- private void OnDestroy()
- {
- Cleanup();
- }
-
- #endregion
-
- #region Public API
-
-
-
- public void AddDefaultHeader(string key, string value)
- {
- defaultHeaders[key] = value;
- }
-
- public void SetAuthToken(string token)
- {
- AddDefaultHeader(AUTHORIZATION_HEADER, $"{BEARER_PREFIX}{token}");
- }
-
- public async UniTask GetAsync(string endpoint, Dictionary headers = null, CancellationToken cancellationToken = default)
- {
- var url = GetFullUrl(endpoint);
- return await SendRequestAsync(url, UnityWebRequest.kHttpVerbGET, null, headers, cancellationToken);
- }
-
- public async UniTask PostAsync(string endpoint, object data = null, Dictionary headers = null, CancellationToken cancellationToken = default)
- {
- var url = GetFullUrl(endpoint);
- var jsonData = SerializeData(data);
- LogRequestDetails("POST", url, jsonData);
- return await SendRequestAsync(url, UnityWebRequest.kHttpVerbPOST, jsonData, headers, cancellationToken);
- }
-
- public async UniTask PutAsync(string endpoint, object data = null, Dictionary headers = null, CancellationToken cancellationToken = default)
- {
- var url = GetFullUrl(endpoint);
- var jsonData = SerializeData(data);
- return await SendRequestAsync(url, UnityWebRequest.kHttpVerbPUT, jsonData, headers, cancellationToken);
- }
-
- public async UniTask DeleteAsync(string endpoint, Dictionary headers = null, CancellationToken cancellationToken = default)
- {
- var url = GetFullUrl(endpoint);
- return await SendRequestAsync(url, UnityWebRequest.kHttpVerbDELETE, null, headers, cancellationToken);
- }
-
- public async UniTask UploadFileAsync(string endpoint, byte[] fileData, string fileName, string fieldName = "file", Dictionary headers = null, CancellationToken cancellationToken = default)
- {
- var url = GetFullUrl(endpoint);
- return await SendFileRequestAsync(url, fileData, fileName, fieldName, headers, cancellationToken);
- }
-
- public void Shutdown()
- {
- cancellationTokenSource?.Cancel();
- }
-
- #endregion
-
- #region Private Methods
-
- private void InitializeSingleton()
- {
- if (Instance == null)
- {
- Instance = this;
- DontDestroyOnLoad(gameObject);
- InitializeClient();
- }
- else
- {
- Destroy(gameObject);
- }
- }
-
- private void InitializeClient()
- {
- cancellationTokenSource = new CancellationTokenSource();
- ApplyNetworkConfig();
- SetupDefaultHeaders();
- }
-
- private void ApplyNetworkConfig()
- {
- Debug.Log($"NetworkConfig 적용: {NetworkConfig.CurrentEnvironment} 환경");
- }
-
- private void SetupDefaultHeaders()
- {
- defaultHeaders.Clear();
- defaultHeaders["Content-Type"] = NetworkConfig.ContentType;
- defaultHeaders["User-Agent"] = NetworkConfig.UserAgent;
- defaultHeaders["Accept"] = ACCEPT_HEADER;
- }
-
- private string GetFullUrl(string endpoint)
- {
- return NetworkConfig.GetFullApiUrl(endpoint);
- }
-
- private string SerializeData(object data)
- {
- return data != null ? JsonConvert.SerializeObject(data) : null;
- }
-
- private void LogRequestDetails(string method, string url, string jsonData)
- {
- Debug.Log($"HTTP {method} 요청 URL: {url}");
- if (!string.IsNullOrEmpty(jsonData))
- {
- Debug.Log($"HTTP 요청 데이터: {jsonData}");
- }
- }
-
- private async UniTask SendRequestAsync(string url, string method, string jsonData, Dictionary headers, CancellationToken cancellationToken)
- {
- var combinedCancellationToken = CreateCombinedCancellationToken(cancellationToken);
-
- Debug.Log($"HTTP 요청 시작: {method} {url}");
- if (!string.IsNullOrEmpty(jsonData))
- {
- Debug.Log($"HTTP 요청 데이터: {jsonData}");
- }
-
- for (int attempt = 0; attempt <= NetworkConfig.MaxRetryCount; attempt++)
- {
- try
- {
- using var request = CreateRequest(url, method, jsonData, headers);
-
- Debug.Log($"HTTP 요청 전송 중... (시도 {attempt + 1}/{NetworkConfig.MaxRetryCount + 1})");
- var operation = request.SendWebRequest();
- await operation.WithCancellation(combinedCancellationToken);
-
- if (request.result == UnityWebRequest.Result.Success)
- {
- Debug.Log($"HTTP 요청 성공: {request.responseCode}");
- return ParseResponse(request);
- }
- else
- {
- await HandleRequestFailure(request, attempt, combinedCancellationToken);
- }
- }
- catch (OperationCanceledException)
- {
- throw;
- }
- catch (Exception ex) when (ex is not ApiException)
- {
- await HandleRequestException(ex, attempt, combinedCancellationToken);
- }
- }
-
- throw new ApiException($"{NetworkConfig.MaxRetryCount + 1}번 시도 후 요청 실패", 0, "최대 재시도 횟수 초과");
- }
-
- private async UniTask SendFileRequestAsync(string url, byte[] fileData, string fileName, string fieldName, Dictionary headers, CancellationToken cancellationToken)
- {
- var combinedCancellationToken = CreateCombinedCancellationToken(cancellationToken);
-
- for (int attempt = 0; attempt <= NetworkConfig.MaxRetryCount; attempt++)
- {
- try
- {
- var form = new WWWForm();
- form.AddBinaryData(fieldName, fileData, fileName);
-
- using var request = UnityWebRequest.Post(url, form);
- SetupRequest(request, headers);
- request.timeout = (int)NetworkConfig.HttpTimeout;
-
- var operation = request.SendWebRequest();
- await operation.WithCancellation(combinedCancellationToken);
-
- if (request.result == UnityWebRequest.Result.Success)
- {
- return ParseResponse(request);
- }
- else
- {
- await HandleFileUploadFailure(request, attempt, combinedCancellationToken);
- }
- }
- catch (OperationCanceledException)
- {
- throw;
- }
- catch (Exception ex) when (ex is not ApiException)
- {
- await HandleFileUploadException(ex, attempt, combinedCancellationToken);
- }
- }
-
- throw new ApiException($"{NetworkConfig.MaxRetryCount + 1}번 시도 후 파일 업로드 실패", 0, "최대 재시도 횟수 초과");
- }
-
- private CancellationToken CreateCombinedCancellationToken(CancellationToken cancellationToken)
- {
- return CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cancellationTokenSource.Token).Token;
- }
-
- private async UniTask HandleRequestFailure(UnityWebRequest request, int attempt, CancellationToken cancellationToken)
- {
- var error = new ApiException(request.error, request.responseCode, request.downloadHandler?.text);
- Debug.LogError($"HTTP 요청 실패: {request.result}, 상태코드: {request.responseCode}, 오류: {request.error}");
-
- if (ShouldRetry(request.responseCode) && attempt < NetworkConfig.MaxRetryCount)
- {
- Debug.LogWarning($"API 요청 실패 (시도 {attempt + 1}/{NetworkConfig.MaxRetryCount + 1}): {error.Message}");
- await UniTask.Delay(TimeSpan.FromSeconds(NetworkConfig.RetryDelay * (attempt + 1)), cancellationToken: cancellationToken);
- return;
- }
-
- throw error;
- }
-
- private async UniTask HandleRequestException(Exception ex, int attempt, CancellationToken cancellationToken)
- {
- if (attempt < NetworkConfig.MaxRetryCount)
- {
- Debug.LogWarning($"API 요청 예외 발생 (시도 {attempt + 1}/{NetworkConfig.MaxRetryCount + 1}): {ex.Message}");
- await UniTask.Delay(TimeSpan.FromSeconds(NetworkConfig.RetryDelay * (attempt + 1)), cancellationToken: cancellationToken);
- return;
- }
- throw new ApiException($"{NetworkConfig.MaxRetryCount + 1}번 시도 후 요청 실패", 0, ex.Message);
- }
-
- private async UniTask HandleFileUploadFailure(UnityWebRequest request, int attempt, CancellationToken cancellationToken)
- {
- var error = new ApiException(request.error, request.responseCode, request.downloadHandler?.text);
-
- if (ShouldRetry(request.responseCode) && attempt < NetworkConfig.MaxRetryCount)
- {
- Debug.LogWarning($"파일 업로드 실패 (시도 {attempt + 1}/{NetworkConfig.MaxRetryCount + 1}): {error.Message}");
- await UniTask.Delay(TimeSpan.FromSeconds(NetworkConfig.RetryDelay * (attempt + 1)), cancellationToken: cancellationToken);
- return;
- }
-
- throw error;
- }
-
- private async UniTask HandleFileUploadException(Exception ex, int attempt, CancellationToken cancellationToken)
- {
- if (attempt < NetworkConfig.MaxRetryCount)
- {
- Debug.LogWarning($"파일 업로드 예외 발생 (시도 {attempt + 1}/{NetworkConfig.MaxRetryCount + 1}): {ex.Message}");
- await UniTask.Delay(TimeSpan.FromSeconds(NetworkConfig.RetryDelay * (attempt + 1)), cancellationToken: cancellationToken);
- return;
- }
- throw new ApiException($"{NetworkConfig.MaxRetryCount + 1}번 시도 후 파일 업로드 실패", 0, ex.Message);
- }
-
- private UnityWebRequest CreateRequest(string url, string method, string jsonData, Dictionary headers)
- {
- var request = new UnityWebRequest(url, method);
-
- if (!string.IsNullOrEmpty(jsonData))
- {
- var bodyRaw = Encoding.UTF8.GetBytes(jsonData);
- request.uploadHandler = new UploadHandlerRaw(bodyRaw);
- }
-
- request.downloadHandler = new DownloadHandlerBuffer();
- SetupRequest(request, headers);
- request.timeout = (int)NetworkConfig.HttpTimeout;
-
- return request;
- }
-
- private void SetupRequest(UnityWebRequest request, Dictionary headers)
- {
- foreach (var header in defaultHeaders)
- {
- request.SetRequestHeader(header.Key, header.Value);
- }
-
- if (headers != null)
- {
- foreach (var header in headers)
- {
- request.SetRequestHeader(header.Key, header.Value);
- }
- }
- }
-
- private T ParseResponse(UnityWebRequest request)
- {
- var responseText = request.downloadHandler?.text;
-
- if (string.IsNullOrEmpty(responseText))
- {
- return default(T);
- }
-
- try
- {
- return JsonConvert.DeserializeObject(responseText);
- }
- catch (Exception ex)
- {
- return TryFallbackParse(responseText, request.responseCode, ex);
- }
- }
-
- private T TryFallbackParse(string responseText, long responseCode, Exception originalException)
- {
- try
- {
- return JsonUtility.FromJson(responseText);
- }
- catch (Exception fallbackEx)
- {
- throw new ApiException($"응답 파싱 실패: {originalException.Message} (폴백도 실패: {fallbackEx.Message})", responseCode, responseText);
- }
- }
-
- private bool ShouldRetry(long responseCode)
- {
- return responseCode >= 500 || responseCode == 429;
- }
-
- private void Cleanup()
- {
- cancellationTokenSource?.Cancel();
- cancellationTokenSource?.Dispose();
- }
-
- #endregion
- }
-
- ///
- /// API 예외 클래스
- ///
- public class ApiException : Exception
- {
- public long StatusCode { get; }
- public string ResponseBody { get; }
-
- public ApiException(string message, long statusCode, string responseBody)
- : base(message)
- {
- StatusCode = statusCode;
- ResponseBody = responseBody;
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/Http/HttpApiClient.cs.meta b/Assets/Infrastructure/Network/Http/HttpApiClient.cs.meta
deleted file mode 100644
index 4ad71af..0000000
--- a/Assets/Infrastructure/Network/Http/HttpApiClient.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: 00fbb8efd091db646bc0653b6295222f
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/README.md b/Assets/Infrastructure/Network/README.md
deleted file mode 100644
index b546cf2..0000000
--- a/Assets/Infrastructure/Network/README.md
+++ /dev/null
@@ -1,269 +0,0 @@
-# ProjectVG Network Module
-
-Unity 클라이언트와 서버 간의 통신을 위한 네트워크 모듈입니다.
-강제된 JSON 형식 `{type: "xxx", data: {...}}`을 사용합니다.
-
-## 📦 설치
-
-### 1. UniTask 설치
-```json
-// Packages/manifest.json
-"com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask"
-```
-
-### 2. 플랫폼별 WebSocket 구현
-플랫폼에 따라 최적화된 WebSocket 구현을 사용합니다.
-
-**플랫폼별 구현:**
-- 🟩 Desktop: System.Net.WebSockets.ClientWebSocket
-- 🟩 WebGL: UnityWebRequest.WebSocket
-- 🟩 Mobile: 네이티브 WebSocket 라이브러리
-
-## 🏗️ 구조
-
-```
-Assets/Infrastructure/Network/
-├── Configs/ # 설정 파일들
-│ └── NetworkConfig.cs # Unity 표준 ScriptableObject 기반 설정
-├── DTOs/ # 데이터 전송 객체들
-│ ├── BaseApiResponse.cs # 기본 API 응답
-│ ├── Chat/ # 채팅 관련 DTO
-│ └── Character/ # 캐릭터 관련 DTO
-├── Http/ # HTTP 클라이언트
-│ └── HttpApiClient.cs # HTTP API 클라이언트
-├── Services/ # API 서비스들
-│ ├── ApiServiceManager.cs # API 서비스 매니저
-│ ├── ChatApiService.cs # 채팅 API 서비스
-│ └── CharacterApiService.cs # 캐릭터 API 서비스
-└── WebSocket/ # WebSocket 관련
- ├── WebSocketManager.cs # WebSocket 매니저 (단순화됨)
- ├── WebSocketFactory.cs # 플랫폼별 WebSocket 팩토리
- ├── INativeWebSocket.cs # 플랫폼별 WebSocket 인터페이스
- └── Platforms/ # 플랫폼별 WebSocket 구현
- ├── DesktopWebSocket.cs # 데스크톱용 (.NET ClientWebSocket)
- ├── WebGLWebSocket.cs # WebGL용 (UnityWebRequest)
- └── MobileWebSocket.cs # 모바일용 (네이티브 라이브러리)
-```
-
-## 🚀 사용법
-
-### 1. Unity 표준 ScriptableObject 기반 설정 관리
-
-#### 설정 파일 생성
-```csharp
-// Unity Editor에서 ScriptableObject 생성
-// Assets/Infrastructure/Network/Configs/ 폴더에서 우클릭
-// Create > ProjectVG > Network > NetworkConfig
-// Resources 폴더에 NetworkConfig.asset 파일 생성
-```
-
-#### 앱 시작 시 환경 설정
-```csharp
-// 앱 시작 시 (Editor에서만 가능)
-NetworkConfig.SetDevelopmentEnvironment(); // localhost:7900
-NetworkConfig.SetTestEnvironment(); // localhost:7900
-NetworkConfig.SetProductionEnvironment(); // 122.153.130.223:7900
-```
-
-#### 런타임 중 설정 사용
-```csharp
-// 어디서든 동일한 설정 접근 (강제로 NetworkConfig 사용)
-var currentEnv = NetworkConfig.CurrentEnvironment;
-var apiUrl = NetworkConfig.GetFullApiUrl("chat");
-var wsUrl = NetworkConfig.GetWebSocketUrl();
-
-// API URL 생성
-var userUrl = NetworkConfig.GetUserApiUrl();
-var characterUrl = NetworkConfig.GetCharacterApiUrl();
-var conversationUrl = NetworkConfig.GetConversationApiUrl();
-var authUrl = NetworkConfig.GetAuthApiUrl();
-
-// WebSocket URL 생성
-var wsUrl = NetworkConfig.GetWebSocketUrl();
-var wsUrlWithVersion = NetworkConfig.GetWebSocketUrlWithVersion();
-var wsUrlWithSession = NetworkConfig.GetWebSocketUrlWithSession("session-123");
-```
-
-### 2. WebSocket 사용 (단순화됨)
-
-#### 기본 사용법
-```csharp
-// WebSocket 매니저 사용
-var wsManager = WebSocketManager.Instance;
-
-// 이벤트 구독
-wsManager.OnConnected += () => Debug.Log("연결됨");
-wsManager.OnDisconnected += () => Debug.Log("연결 해제됨");
-wsManager.OnError += (error) => Debug.LogError($"오류: {error}");
-wsManager.OnSessionIdReceived += (sessionId) => Debug.Log($"세션 ID: {sessionId}");
-wsManager.OnChatMessageReceived += (message) => Debug.Log($"채팅: {message}");
-
-// 연결
-await wsManager.ConnectAsync();
-
-// 메시지 전송
-await wsManager.SendChatMessageAsync("안녕하세요!");
-
-// 연결 해제
-await wsManager.DisconnectAsync();
-```
-
-#### 강제된 JSON 형식 사용
-```csharp
-// 메시지 전송 (강제된 형식)
-await wsManager.SendMessageAsync("chat", new ChatData
-{
- message = "안녕하세요!",
- sessionId = "session-123",
- timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
-});
-
-// 서버에서 받는 메시지 형식
-// {
-// "type": "session_id",
-// "data": {
-// "session_id": "session_123456789"
-// }
-// }
-//
-// {
-// "type": "chat",
-// "data": {
-// "message": "안녕하세요!",
-// "sessionId": "session-123",
-// "timestamp": 1703123456789
-// }
-// }
-```
-
-### 3. HTTP API 사용
-
-#### API 서비스 매니저 사용
-```csharp
-// API 서비스 매니저 사용
-var apiManager = ApiServiceManager.Instance;
-
-// 채팅 API 사용
-var chatResponse = await apiManager.Chat.SendChatAsync(
- new ChatRequest
- {
- message = "안녕하세요!",
- characterId = "char-456",
- userId = "user-789",
- sessionId = "session-123"
- }
-);
-
-// 캐릭터 API 사용
-var character = await apiManager.Character.GetCharacterAsync("char-456");
-```
-
-### 4. 전체 흐름 테스트 (권장)
-```csharp
-// NetworkTestManager 사용
-var testManager = FindObjectOfType();
-
-// 1. WebSocket 연결
-await testManager.ConnectWebSocket();
-
-// 2. HTTP 요청 전송
-await testManager.SendChatRequest();
-
-// 3. WebSocket으로 결과 수신 (자동)
-// 서버가 비동기 작업 완료 후 WebSocket으로 결과 전송
-```
-
-## ⚙️ 설정
-
-### Unity 표준 ScriptableObject 설정 관리
-
-#### 1. 설정 파일 생성
-1. **NetworkConfig.asset** 생성:
- - `Assets/Resources/` 폴더에 `NetworkConfig.asset` 파일 생성
- - Unity Editor에서 우클릭 > Create > ProjectVG > Network > NetworkConfig
-
-#### 2. 환경별 서버 주소
-- **개발 환경**: `localhost:7900`
-- **테스트 환경**: `localhost:7900`
-- **프로덕션 환경**: `122.153.130.223:7900`
-
-#### 3. 설정값들 (Editor에서 설정 가능)
-- **HTTP 타임아웃**: 30초
-- **최대 재시도**: 3회
-- **WebSocket 타임아웃**: 30초
-- **자동 재연결**: 활성화
-- **하트비트**: 활성화 (30초 간격)
-
-#### 4. 런타임 보안
-- ✅ 앱 시작 시 한 번 설정
-- ✅ 런타임 중 설정 변경 불가
-- ✅ 어디서든 동일한 설정 접근
-- ✅ ScriptableObject로 일관성 보장
-- ✅ Editor에서 설정 가능
-- ✅ 팀 협업 용이
-- ✅ NetworkConfig 강제 사용으로 일관성 보장
-
-## 🔧 플랫폼별 WebSocket 구현
-
-### 1. DesktopWebSocket (데스크톱)
-- System.Net.WebSockets.ClientWebSocket 사용
-- Windows/Mac/Linux 지원
-- 최고 성능
-- JSON 메시지만 처리
-
-### 2. WebGLWebSocket (브라우저)
-- UnityWebRequest.WebSocket 사용
-- WebGL 플랫폼 지원
-- 브라우저 제약사항 대응
-- JSON 메시지만 처리
-
-### 3. MobileWebSocket (모바일)
-- 네이티브 WebSocket 라이브러리 사용
-- iOS/Android 지원
-- 네이티브 성능
-- JSON 메시지만 처리
-
-### 4. WebSocketFactory
-- 플랫폼별 WebSocket 구현 생성
-- 컴파일 타임에 적절한 구현체 선택
-
-## 🐛 문제 해결
-
-### 플랫폼별 WebSocket
-```
-데스크톱 플랫폼용 WebSocket 생성
-WebSocket 연결 시도: ws://localhost:7900/ws
-WebSocket 연결 성공
-```
-**설명:** 플랫폼에 따라 적절한 WebSocket 구현체가 자동으로 선택됩니다.
-
-### 플랫폼별 특징
-- **Desktop**: .NET ClientWebSocket으로 최고 성능
-- **WebGL**: 브라우저 WebSocket API 사용
-- **Mobile**: 네이티브 라이브러리로 최적화
-
-### 테스트 실행 방법
-1. **NetworkTestManager** 컴포넌트를 씬에 추가
-2. **Context Menu**에서 테스트 실행:
- - `1. WebSocket 연결`
- - `2. HTTP 채팅 요청`
- - `3. HTTP 캐릭터 정보 요청`
- - `4. WebSocket 메시지 전송`
- - `5. WebSocket 연결 해제`
- - `전체 테스트 실행`
-
-## 📝 로그
-
-모든 로그는 한국어로 출력됩니다:
-- `Debug.Log("WebSocket 연결 성공")`
-- `Debug.LogError("연결 실패")`
-- `Debug.LogWarning("재연결 시도")`
-
-## 🔄 변경 사항
-
-### 주요 변경사항 (v2.0)
-1. **바이너리 방식 완전 제거**: JSON 메시지만 처리
-2. **강제된 JSON 형식**: `{type: "xxx", data: {...}}` 형식 사용
-3. **MessageRouter 제거**: WebSocketManager에서 직접 처리
-4. **단순화된 구조**: 불필요한 복잡성 제거
-5. **확장 가능한 설계**: 추후 기능 추가 용이
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/README.md.meta b/Assets/Infrastructure/Network/README.md.meta
deleted file mode 100644
index 6d02e29..0000000
--- a/Assets/Infrastructure/Network/README.md.meta
+++ /dev/null
@@ -1,7 +0,0 @@
-fileFormatVersion: 2
-guid: 4ceeee07406643741bb8b3a1e83f927f
-TextScriptImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Infrastructure/Network/Services.meta b/Assets/Infrastructure/Network/Services.meta
deleted file mode 100644
index c4ba0b4..0000000
--- a/Assets/Infrastructure/Network/Services.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: f9bc83dcef956db4784a7336ee77e17b
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Infrastructure/Network/Services/ApiServiceManager.cs b/Assets/Infrastructure/Network/Services/ApiServiceManager.cs
deleted file mode 100644
index 08f14da..0000000
--- a/Assets/Infrastructure/Network/Services/ApiServiceManager.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using UnityEngine;
-
-namespace ProjectVG.Infrastructure.Network.Services
-{
- ///
- /// API 서비스 매니저
- /// 모든 API 서비스의 중앙 관리자
- ///
- public class ApiServiceManager : MonoBehaviour
- {
- private static ApiServiceManager _instance;
- public static ApiServiceManager Instance
- {
- get
- {
- if (_instance == null)
- {
- _instance = FindFirstObjectByType();
- if (_instance == null)
- {
- GameObject go = new GameObject("ApiServiceManager");
- _instance = go.AddComponent();
- DontDestroyOnLoad(go);
- }
- }
- return _instance;
- }
- }
-
- // API 서비스 인스턴스들
- private ChatApiService _chatService;
- private CharacterApiService _characterService;
-
- // 프로퍼티로 서비스 접근
- public ChatApiService Chat => _chatService ??= new ChatApiService();
- public CharacterApiService Character => _characterService ??= new CharacterApiService();
-
- private void Awake()
- {
- if (_instance == null)
- {
- _instance = this;
- DontDestroyOnLoad(gameObject);
- InitializeServices();
- }
- else if (_instance != this)
- {
- Destroy(gameObject);
- }
- }
-
- private void InitializeServices()
- {
- // 서비스 초기화
- _chatService = new ChatApiService();
- _characterService = new CharacterApiService();
-
- Debug.Log("API 서비스 매니저 초기화 완료");
- }
-
- ///
- /// 모든 서비스 재초기화
- ///
- public void ReinitializeServices()
- {
- _chatService = new ChatApiService();
- _characterService = new CharacterApiService();
-
- Debug.Log("API 서비스 재초기화 완료");
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/Services/ApiServiceManager.cs.meta b/Assets/Infrastructure/Network/Services/ApiServiceManager.cs.meta
deleted file mode 100644
index fe19897..0000000
--- a/Assets/Infrastructure/Network/Services/ApiServiceManager.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: bc3a1165acfed50488abb14eb8dbc022
\ No newline at end of file
diff --git a/Assets/Infrastructure/Network/Services/CharacterApiService.cs b/Assets/Infrastructure/Network/Services/CharacterApiService.cs
deleted file mode 100644
index 2e9205d..0000000
--- a/Assets/Infrastructure/Network/Services/CharacterApiService.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-using System.Threading;
-using UnityEngine;
-using Cysharp.Threading.Tasks;
-using ProjectVG.Infrastructure.Network.Http;
-using ProjectVG.Infrastructure.Network.DTOs.Character;
-
-namespace ProjectVG.Infrastructure.Network.Services
-{
- ///
- /// 캐릭터 API 서비스
- ///
- public class CharacterApiService
- {
- private readonly HttpApiClient _httpClient;
-
- public CharacterApiService()
- {
- _httpClient = HttpApiClient.Instance;
- if (_httpClient == null)
- {
- Debug.LogError("HttpApiClient.Instance가 null입니다. HttpApiClient가 생성되지 않았습니다.");
- }
- }
-
- ///
- /// 모든 캐릭터 목록 조회
- ///
- /// 취소 토큰
- /// 캐릭터 목록
- public async UniTask GetAllCharactersAsync(CancellationToken cancellationToken = default)
- {
- if (_httpClient == null)
- {
- Debug.LogError("HttpApiClient가 null입니다. 초기화를 확인해주세요.");
- return null;
- }
-
- return await _httpClient.GetAsync("character", cancellationToken: cancellationToken);
- }
-
- ///
- /// 특정 캐릭터 정보 조회
- ///
- /// 캐릭터 ID
- /// 취소 토큰
- /// 캐릭터 정보
- public async UniTask GetCharacterAsync(string characterId, CancellationToken cancellationToken = default)
- {
- if (_httpClient == null)
- {
- Debug.LogError("HttpApiClient가 null입니다. 초기화를 확인해주세요.");
- return null;
- }
-
- return await _httpClient.GetAsync($"character/{characterId}", cancellationToken: cancellationToken);
- }
-
- ///
- /// 캐릭터 생성
- ///
- /// 캐릭터 생성 요청
- /// 취소 토큰
- /// 생성된 캐릭터 정보
- public async UniTask CreateCharacterAsync(CreateCharacterRequest request, CancellationToken cancellationToken = default)
- {
- return await _httpClient.PostAsync("character", request, cancellationToken: cancellationToken);
- }
-
- ///
- /// 간편한 캐릭터 생성
- ///
- /// 캐릭터 이름
- /// 캐릭터 설명
- /// 캐릭터 역할
- /// 활성화 여부
- /// 취소 토큰
- /// 생성된 캐릭터 정보
- public async UniTask CreateCharacterAsync(
- string name,
- string description,
- string role,
- bool isActive = true,
- CancellationToken cancellationToken = default)
- {
- var request = new CreateCharacterRequest
- {
- name = name,
- description = description,
- role = role,
- isActive = isActive
- };
-
- return await CreateCharacterAsync(request, cancellationToken);
- }
-
- ///
- /// 캐릭터 정보 수정
- ///
- /// 캐릭터 ID
- /// 수정 요청
- /// 취소 토큰
- /// 수정된 캐릭터 정보
- public async UniTask UpdateCharacterAsync(string characterId, UpdateCharacterRequest request, CancellationToken cancellationToken = default)
- {
- return await _httpClient.PutAsync($"character/{characterId}", request, cancellationToken: cancellationToken);
- }
-
- ///
- /// 간편한 캐릭터 수정
- ///
- /// 캐릭터 ID
- /// 캐릭터 이름
- /// 캐릭터 설명
- /// 캐릭터 역할
- /// 활성화 여부
- /// 취소 토큰
- /// 수정된 캐릭터 정보
- public async UniTask UpdateCharacterAsync(
- string characterId,
- string name = null,
- string description = null,
- string role = null,
- bool? isActive = null,
- CancellationToken cancellationToken = default)
- {
- var request = new UpdateCharacterRequest();
-
- if (name != null) request.name = name;
- if (description != null) request.description = description;
- if (role != null) request.role = role;
- if (isActive.HasValue) request.isActive = isActive.Value;
-
- return await UpdateCharacterAsync(characterId, request, cancellationToken);
- }
-
- ///
- /// 캐릭터 삭제
- ///
- /// 캐릭터 ID
- /// 취소 토큰
- /// 삭제 성공 여부
- public async UniTask DeleteCharacterAsync(string characterId, CancellationToken cancellationToken = default)
- {
- try
- {
- await _httpClient.DeleteAsync