Skip to content

Commit 578399d

Browse files
committed
fix: WebSocket 메시지 조각화 처리 개선
- EndOfMessage 확인으로 완전한 메시지 수신 보장 - MemoryStream 사용한 프래그먼트 누적 처리 - 긴 메시지 손실 방지 및 데이터 무결성 보장 - ping/pong 메시지 처리 로직 개선 (JSON 구조 지원) 기존: 첫 번째 프래그먼트만 처리하여 메시지 손실 가능 개선: do-while 루프로 완전한 메시지 복원
1 parent 37545f3 commit 578399d

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

ProjectVG.Api/Middleware/WebSocketMiddleware.cs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,23 @@ await socket.SendAsync(
125125
true,
126126
cancellationTokenSource.Token).ConfigureAwait(false);
127127

128-
while (socket.State == WebSocketState.Open && !cancellationTokenSource.Token.IsCancellationRequested) {
129-
var result = await socket.ReceiveAsync(
130-
new ArraySegment<byte>(buffer),
131-
cancellationTokenSource.Token).ConfigureAwait(false);
132-
133-
if (result.MessageType == WebSocketMessageType.Close) {
134-
_logger.LogInformation("연결 종료 요청: {UserId}", userId);
135-
break;
136-
}
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;
137145

138146
// WebSocket의 기본 제어 메시지들 처리
139147
if (result.MessageType == WebSocketMessageType.Binary) {
@@ -143,8 +151,10 @@ await socket.SendAsync(
143151

144152
// Handle heartbeat/ping messages
145153
if (result.MessageType == WebSocketMessageType.Text) {
146-
var message = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);
147-
if (message.Contains("ping")) {
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)) {
148158
var pongMessage = System.Text.Encoding.UTF8.GetBytes("{\"type\":\"pong\"}");
149159
await socket.SendAsync(
150160
new ArraySegment<byte>(pongMessage),

0 commit comments

Comments
 (0)