[]
        
(Showing Draft Content)

메시지 송수신

js-collaboration클라이언트–서버 간 양방향 통신을 지원하며, 서버가 하나의 룸(room)에 속한 모든 클라이언트에게 메시지를 브로드캐스트할 수 있도록 합니다. 이 문서는 다음 기술 구현에 대해 설명합니다.

  • 클라이언트가 서버로 메시지를 전송

  • 서버가 메시지를 수신하고 응답

  • 메시지 브로드캐스트


기본 송수신

클라이언트 → 서버

클라이언트는 connection.send() 메서드를 사용하여 서버로 메시지를 전송합니다.

메시지는 문자열, 일반 객체, 숫자, 배열 등 다양한 데이터 타입을 지원합니다.

// 클라이언트 측
// 서버로 메시지 전송
connection.send('hello, world!');

서버는 message 훅을 통해 클라이언트 메시지를 수신할 수 있습니다.

// 서버 측
server.on('message', ({ connection, data }) => {
    console.log('클라이언트로부터 수신한 메시지:', data);
});

서버 → 클라이언트

클라이언트는 connection.on('message') 메서드를 사용하여 서버로부터 메시지를 수신합니다.

// 클라이언트 측
connection.on('message', (data) => {
    console.log('서버로부터 수신한 메시지:', data);
});

서버는 connection.send() 메서드를 사용하여 클라이언트로 메시지를 전송합니다.

// 서버 측
server.on('connect', ({ connection }) => {
    connection.send('hello, world!');
});

서버 브로드캐스팅

서버는 단일 클라이언트에게 메시지를 보내는 것뿐만 아니라,

connection.broadcast() 메서드를 사용하여 같은 룸에 속한 모든 클라이언트에게 메시지를 브로드캐스트할 수 있습니다.


송신자를 제외한 브로드캐스트

connection.broadcast()roomId만 제공하면, 기본 동작은 송신자를 제외한 클라이언트에게만 메시지를 브로드캐스트하는 것입니다.

messages_sending_and_receiving-broadcast1.1a1948.png

// 클라이언트 측
connection.on('message', (data) => {
    console.log('서버로부터 수신한 메시지:', data);
});
// 서버 측
server.on('connect', ({ connection, roomId }) => {
    // 클라이언트가 연결되면, 같은 룸의 모든 클라이언트에게 메시지를 브로드캐스트 (송신자 제외)
    connection.broadcast(`${connection.id} join ${roomId}`);
});

송신자를 포함한 브로드캐스트

송신자를 포함하여 룸의 모든 참여자에게 메시지를 브로드캐스트하려면,

includeSelf: true 옵션을 설정합니다.

messages_sending_and_receiving-broadcast2.a16051.png

// 클라이언트 측
connection.on('message', (data) => {
    console.log('서버로부터 수신한 메시지:', data);
});
// 서버 측
server.on('connect', ({ connection, roomId }) => {
    // 클라이언트가 연결되면, 같은 룸의 모든 클라이언트에게 메시지를 브로드캐스트 (송신자 포함)
    connection.broadcast(`${connection.id} join ${roomId}`, '', true);
});

broadcast()의 두 번째 매개변수는 메시지 타입(선택 사항)이며, 이 예제에서는 빈 문자열을 사용합니다.


메시지 타입

메시지 타입은 메시지의 목적이나 범주를 식별하는 데 사용되며,

수신자가 해당 메시지가 자신에게 관련이 있는지 판단할 수 있도록 합니다.


예를 들어 동시 작업 시나리오에서는 문서 업데이트 메시지와 사용자 상태 메시지를 구분하기 위해

"my-document" 또는 "my-presence" 같은 타입을 사용할 수 있습니다.

// 문서 업데이트 전송
connection.send({ content: 'New paragraph' }, 'my-document');
// 온라인 상태 전송
connection.send({ userId: 'user1', active: true }, 'my-presence');
// 메시지 수신 및 타입별 처리
connection.on('message', (data, type) => {
    if (type === 'my-document') {
        console.log('문서 업데이트:', data);
    } else if (type === 'my-presence') {
        console.log('상태 업데이트:', data);
    }
});

메시지 순서

js-collaboration메시지가 전송된 순서대로 전달됨을 보장합니다.

예를 들어 다음과 같이 메시지를 전송하면,

connection.send('msg1');
connection.send('msg2');
connection.send('msg3');

수신자는 항상 다음 순서로 메시지를 받습니다.

msg1 → msg2 → msg3

메시지 전달 보장

전달 보장 방식

js-collaborationAt-Most-Once Delivery(최대 한 번 전달) 메커니즘을 구현합니다. 이는 다음을 의미합니다.

  • 연결이 끊긴 상태에서 메시지가 전송되면, 수신자가 해당 메시지를 받았는지 보장할 수 없습니다.

  • 연결이 복구된 후에도, 이전에 전달되지 않은 메시지는 자동으로 재전송되지 않습니다.


클라이언트 동작 방식

연결이 끊기면 클라이언트는 전송되지 않은 메시지를 유지하기 위한 버퍼링 전략을 사용합니다.

  • 미전송 메시지 버퍼링

    connection.send() 호출 시 네트워크 오류 등으로 연결이 불가능하면,

    메시지는 즉시 폐기되지 않고 클라이언트 로컬에 버퍼링됩니다.

  • 재연결 후 전송

    연결이 복구되면, 버퍼링된 메시지가 원래 순서대로 전송됩니다.


서버 동작 방식

서버는 메시지 버퍼링 메커니즘을 제공하지 않습니다.

  • 메시지 버퍼링 없음

    서버가 connection.send() 또는 connection.broadcast()로 메시지를 보낼 때

    대상 클라이언트가 연결되어 있지 않으면 해당 메시지는 즉시 유실됩니다.

  • 재전송 없음

    클라이언트가 재연결하더라도, 서버는 연결 끊김 동안 놓친 메시지를 재전송하지 않습니다.


메시지 유실 대응 전략

At-Most-Once Delivery 특성상, 비즈니스 요구사항에 따라 추가적인 신뢰성 메커니즘을 설계해야 합니다.

다음은 일반적으로 사용되는 전략입니다.

애플리케이션 계층 확인 메커니즘

  • 방법: 송신자가 메시지에 고유 식별자(예: 메시지 ID)를 포함하고, 수신자는 확인(ACK) 메시지를 응답

  • 구현: 확인 응답을 받지 못하면 송신자가 재전송

  • 사용 사례: 문서 변경과 같은 중요 메시지

// 클라이언트가 ID를 포함한 메시지 전송
connection.send({ id: 'msg123', type: 'update', content: 'xxx' });

// 서버에서 확인 응답 전송
server.on('message', ({ connection, data }) => {
    connection.send({ id: data.id, type: 'ack' });
});

// 클라이언트에서 확인 응답 검사
connection.on('message', (data) => {
    if (data.type === 'ack' && data.id === 'msg123') {
        console.log('메시지 전달 완료');
    }
});