@@ -103,28 +103,97 @@ private async Task RegisterConnection(Guid userId, WebSocket socket)
103103 await _webSocketService . ConnectAsync ( userId . ToString ( ) ) ;
104104 }
105105
106- /// <summary>
107- /// 세션 루프 실행
106+ /// <summary>
107+ /// 세션 루프 실행
108108 /// </summary>
109109 private async Task RunSessionLoop ( WebSocket socket , string userId )
110110 {
111- var buffer = new byte [ 1024 ] ;
111+ var buffer = new byte [ 1024 * 4 ] ; // Increase buffer size for better performance
112+ var cancellationTokenSource = new CancellationTokenSource ( ) ;
113+
114+ // Set a reasonable timeout for WebSocket operations
115+ cancellationTokenSource . CancelAfter ( TimeSpan . FromMinutes ( 30 ) ) ;
116+
112117 try {
113- while ( socket . State == WebSocketState . Open ) {
114- var result = await socket . ReceiveAsync ( new ArraySegment < byte > ( buffer ) , CancellationToken . None ) ;
118+ _logger . LogInformation ( "WebSocket 세션 시작: {UserId}" , userId ) ;
119+
120+ // Send initial connection confirmation without exposing user ID
121+ var welcomeMessage = System . Text . Encoding . UTF8 . GetBytes ( "{\" type\" :\" connected\" ,\" status\" :\" success\" }" ) ;
122+ await socket . SendAsync (
123+ new ArraySegment < byte > ( welcomeMessage ) ,
124+ WebSocketMessageType . Text ,
125+ true ,
126+ cancellationTokenSource . Token ) . ConfigureAwait ( false ) ;
127+
128+ while ( socket . State == WebSocketState . Open && ! cancellationTokenSource . Token . IsCancellationRequested )
129+ {
130+ WebSocketReceiveResult result ;
131+ using var ms = new MemoryStream ( ) ;
132+ do
133+ {
134+ result = await socket . ReceiveAsync ( new ArraySegment < byte > ( buffer ) , cancellationTokenSource . Token )
135+ . ConfigureAwait ( false ) ;
136+ if ( result . MessageType == WebSocketMessageType . Close )
137+ {
138+ _logger . LogInformation ( "연결 종료 요청: {UserId}" , userId ) ;
139+ break ;
140+ }
141+ ms . Write ( buffer , 0 , result . Count ) ;
142+ } while ( ! result . EndOfMessage ) ;
143+
144+ if ( result . MessageType == WebSocketMessageType . Close ) break ;
145+
146+ // WebSocket의 기본 제어 메시지들 처리
147+ if ( result . MessageType == WebSocketMessageType . Binary ) {
148+ _logger . LogDebug ( "Binary 메시지 받음: {UserId}" , userId ) ;
149+ continue ;
150+ }
115151
116- if ( result . MessageType == WebSocketMessageType . Close ) {
117- _logger . LogInformation ( "연결 종료 요청: {UserId}" , userId ) ;
118- break ;
152+ // Handle heartbeat/ping messages
153+ if ( result . MessageType == WebSocketMessageType . Text ) {
154+ var message = System . Text . Encoding . UTF8 . GetString ( ms . ToArray ( ) ) ;
155+ // 매우 단순한 ping 판별 → 추후 JSON 파싱으로 교체 권장
156+ if ( string . Equals ( message , "ping" , StringComparison . OrdinalIgnoreCase ) ||
157+ message . Contains ( "\" type\" :\" ping\" " , StringComparison . OrdinalIgnoreCase ) ) {
158+ var pongMessage = System . Text . Encoding . UTF8 . GetBytes ( "{\" type\" :\" pong\" }" ) ;
159+ await socket . SendAsync (
160+ new ArraySegment < byte > ( pongMessage ) ,
161+ WebSocketMessageType . Text ,
162+ true ,
163+ cancellationTokenSource . Token ) . ConfigureAwait ( false ) ;
164+ }
119165 }
120166 }
121167 }
168+ catch ( OperationCanceledException ) {
169+ _logger . LogWarning ( "WebSocket 세션 타임아웃: {UserId}" , userId ) ;
170+ }
171+ catch ( WebSocketException ex ) {
172+ _logger . LogWarning ( ex , "WebSocket 연결 오류: {UserId}" , userId ) ;
173+ }
122174 catch ( Exception ex ) {
123- _logger . LogError ( ex , "세션 루프 오류: {UserId}" , userId ) ;
175+ _logger . LogError ( ex , "세션 루프 예상치 못한 오류: {UserId}" , userId ) ;
124176 }
125177 finally {
126- _logger . LogInformation ( "연결 해제: {UserId}" , userId ) ;
127- await _webSocketService . DisconnectAsync ( userId ) ;
178+ _logger . LogInformation ( "WebSocket 연결 해제: {UserId}" , userId ) ;
179+
180+ try {
181+ await _webSocketService . DisconnectAsync ( userId ) . ConfigureAwait ( false ) ;
182+ _connectionRegistry . Unregister ( userId ) ;
183+
184+ if ( socket . State == WebSocketState . Open || socket . State == WebSocketState . CloseReceived ) {
185+ await socket . CloseAsync (
186+ WebSocketCloseStatus . NormalClosure ,
187+ "Connection closed" ,
188+ CancellationToken . None ) . ConfigureAwait ( false ) ;
189+ }
190+ }
191+ catch ( Exception ex ) {
192+ _logger . LogError ( ex , "WebSocket 정리 중 오류: {UserId}" , userId ) ;
193+ }
194+ finally {
195+ cancellationTokenSource ? . Dispose ( ) ;
196+ }
128197 }
129198 }
130199 }
0 commit comments