[]
        
(Showing Draft Content)

Operation (Op)

Operation(Op)은 클라이언트와 서버 간 통신의 핵심 개념입니다. 클라이언트는 문서에 대한 변경 사항을 설명하기 위해 Op를 제출하고, 서버는 이 Op를 처리·저장·동기화합니다. 이 문서에서는 다음 내용을 소개합니다.

  • Op의 정의

  • 클라이언트와 서버 간 Op의 차이

  • 서버 측 추가 필드의 역할

정의

Op는 문서 상태에 대한 단일 변경 사항을 설명합니다. 일반적인 작업은 다음과 같습니다.

  • 문서 콘텐츠 삽입 또는 수정: 예를 들어, 문서의 특정 위치에 텍스트를 삽입

  • 문서 생성: 새 문서 초기화

  • 문서 삭제: 기존 문서 제거

Op의 정의는 클라이언트와 서버에서 다릅니다.

  • 클라이언트 측 Op: 삽입 위치와 텍스트 내용처럼 작업의 구체적인 콘텐츠를 설명

  • 서버 측 Op: 클라이언트 측 Op에 src, seq, v와 같은 추가 메타데이터를 포함하여 확장하며, 이는 작업의 고유 식별, 버전 관리, 불안정한 네트워크 환경에서의 중복 제출 감지에 사용됨

차이점

클라이언트 측 Op

클라이언트 측 Op는 사용자의 문서 수정 내용을 직접적으로 설명하며, 일반적으로 작업의 구체적인 콘텐츠만 포함합니다. 아래는 Op의 예시입니다.

다음 예제의 Op는 설명을 단순화한 것입니다. 실제 환경에서는 문서 타입, 작업 복잡도, 구현 방식에 따라 Op의 구조와 내용이 달라질 수 있습니다.

예제 1: 텍스트 삽입

문서의 특정 위치에 텍스트를 삽입합니다.

sharedDoc.submitOp({ pos: 1, text: 'hello' })
  • pos: 1: 문서의 1번 위치에 콘텐츠를 삽입함을 의미

  • text: 'hello': 삽입되는 텍스트 내용이 "hello"임을 의미

예제 2: 문서 생성

새 문서를 초기화합니다.

sharedDoc.create('Hi!', textType.uri);
  • 'Hi!': 새 문서의 초기 콘텐츠

  • textType.uri: 문서의 OT 타입(예: 텍스트 타입)

예제 3: 문서 삭제

sharedDoc.del();

서버 측 Op

서버는 클라이언트로부터 Op를 수신한 후, 다음과 같은 메타데이터 필드를 추가하여 Op를 확장합니다.

  • src: 작업의 출처 식별자로, 일반적으로 클라이언트를 구분하기 위한 고유 ID

  • seq: 해당 클라이언트가 제출한 작업의 시퀀스 번호로, 작업 제출 순서를 나타냄 (srcseq의 조합은 작업의 고유 식별자가 됨)

  • v: 작업이 적용될 당시의 문서 버전 번호로, 버전 관리 및 충돌 해결에 사용됨

이 메타데이터 필드의 역할은 다음과 같습니다.

  • 고유 식별: srcseq를 사용하여 불안정한 네트워크 환경에서의 중복 제출을 감지하고 동일 작업의 중복 적용을 방지

  • 버전 관리: v를 사용하여 작업이 올바른 순서로 적용되도록 보장하고, 동시 수정으로 인한 충돌을 처리

다음은 클라이언트 측 Op에 대응하여 서버에서 수신된 Op의 예시입니다.


예제 1: 문서 생성(서버 측)

클라이언트에서 제출된 문서 생성 작업은 서버에서 다음과 같이 나타납니다.

documentServices.use('submit', async (context, next) => {
    console.log(context.request.op);
    // 출력: { src: '51pX43yjKUiMmSoHAAAB', seq: 1, v: 0, create: { type: 'text-type', data: 'Hi!' } }
    await next();
});
  • create: { type: 'text-type', data: 'Hi!' }: 문서 생성을 위한 원본 작업 내용

  • src: '51pX43yjKUiMmSoHAAAB': 클라이언트의 고유 식별자

  • seq: 1: 해당 클라이언트의 첫 번째 작업

  • v: 0: 작업 적용 시점의 문서 버전 번호

예제 2: 텍스트 삽입(서버 측)

클라이언트에서 제출된 텍스트 삽입 작업은 서버에서 다음과 같이 나타납니다.

documentServices.use('submit', async (context, next) => {
    console.log(context.request.op);
    // 출력: { src: '51pX43yjKUiMmSoHAAAB', seq: 2, v: 1, op: { pos: 1, text: 'hello'} }
    await next();
});
  • op: { pos: 1, text: 'hello' }: 클라이언트가 제출한 원본 작업 내용

  • src, seq, v: 앞선 예제와 동일하며, 식별 및 버전 관리에 사용됨

예제 3: 문서 삭제(서버 측)

클라이언트에서 제출된 문서 삭제 작업은 서버에서 다음과 같이 나타납니다.

documentServices.use('submit', async (context, next) => {
    console.log(context.request.op);
    // 출력: { src: '51pX43yjKUiMmSoHAAAB', seq: 3, v: 2, del: true }
    await next();
});
  • del: true: 문서 삭제를 의미하는 원본 작업 내용

  • src, seq, v: 앞선 예제와 동일하며, 식별 및 버전 관리에 사용됨