대용량 데이터를 처리하기 위해 스트림 방식으로 데이터를 전송 및 처리하는 예제를 아래에 제공합니다. 이는 메모리 사용량을 줄이고, 효율적으로 데이터를 처리할 수 있는 방법입니다.
C# 서버 코드
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
[HttpPost("stream-data")]
public async Task StreamData()
{
// 응답의 ContentType을 JSON으로 설정
Response.ContentType = "application/json";
var testData = new TestData
{
key = "exampleKey",
data = new DataClass
{
chartkey = 1,
chartdatalist = GenerateLargeChartData()
}
};
// JSON 데이터를 스트림으로 직렬화
await JsonSerializer.SerializeAsync(Response.Body, testData, new JsonSerializerOptions
{
WriteIndented = false // JSON 크기를 줄이기 위해 줄 바꿈 제거
});
await Response.Body.FlushAsync(); // 스트림 완료
}
private List<ChartData> GenerateLargeChartData()
{
var chartDataList = new List<ChartData>();
for (int i = 0; i < 2000000; i++)
{
chartDataList.Add(new ChartData { x = i * 1.1f, y = i * 2.2f });
}
return chartDataList;
}
}
public class TestData
{
public string key { get; set; }
public DataClass data { get; set; }
}
public class DataClass
{
public int chartkey { get; set; }
public List<ChartData> chartdatalist { get; set; }
}
public class ChartData
{
public float x { get; set; }
public float y { get; set; }
}
JavaScript 클라이언트 코드
async function fetchStreamData() {
// Fetch API로 스트림 데이터 요청
const response = await fetch('https://yourapi.com/api/test/stream-data', {
method: 'POST'
});
if (!response.ok) {
console.error('HTTP Error:', response.status);
return;
}
// 스트림 데이터 처리
const reader = response.body.getReader();
const decoder = new TextDecoder('utf-8');
let jsonText = "";
while (true) {
// 스트림의 데이터 청크를 읽음
const { done, value } = await reader.read();
if (done) {
break; // 스트림이 끝났을 경우 루프 종료
}
// 받은 데이터 청크를 문자열로 디코딩
jsonText += decoder.decode(value, { stream: true });
}
try {
// 최종적으로 전체 JSON 문자열을 파싱
const jsonData = JSON.parse(jsonText);
console.log(jsonData);
} catch (error) {
console.error('JSON Parsing Error:', error);
}
}
fetchStreamData();
코드 설명
C# 서버
- JsonSerializer.SerializeAsync 사용:
- 대량 데이터를 직렬화하며, 클라이언트로 스트림 방식으로 데이터를 전송합니다.
- Response.Body.FlushAsync():
- 직렬화된 데이터를 클라이언트에 강제적으로 보내도록 요청합니다.
- 대량 데이터 생성:
- GenerateLargeChartData 메서드를 통해 200만 개의 데이터를 생성.
JavaScript 클라이언트
- fetch 사용:
- 서버에 스트림 데이터를 요청합니다.
- response.body.getReader():
- 스트림을 읽기 위해 Reader를 사용.
- TextDecoder:
- 스트림 데이터를 텍스트 형식으로 변환.
- JSON 조립:
- 받은 청크 데이터를 모두 합친 후, JSON으로 파싱하여 처리.
장점
- 스트림 방식은 전체 데이터를 메모리에 저장하지 않고, 청크 단위로 처리하여 메모리 사용량을 최소화합니다.
- JavaScript와 C# 모두 네트워크 대역폭과 처리 성능을 최적화합니다.
이 방식으로 대용량 데이터 전송 문제를 효과적으로 해결할 수 있습니다.