티스토리 뷰

MongoDB Change Stream

DB에 변동사항이 생기면 서버에 알려줌 -> 사용자에게 데이터 전송

 

1. Change Stream 설정

<server.js>

// const pipeline = [{ $match: {} }]; // 컬렉션 안의 원하는 document만 감시하고 싶으면 $match에 넣어주면 됨
const pipeline = [{ $match: { 'fullDocument.parent': 요청.params.id } }]; // 원하는 document(ex) parent: 요청.params.id)에 fullDocument. 붙여주기
const collection = db.collection('message');
const changeStream = collection.watch(pipeline); // watch(): 실시간 감시해줌

changeStream.on('change', (result) => {
    console.log(result.fullDocument);
    응답.write('event: test\n');
    응답.write('data:' + JSON.stringify([result.fullDocument]) + '\n\n');
}); // 해당 컬렉션에 변동사항이 생기면 여기 코드를 실행

 

더보기
app.get('/message/:id', 로그인했니, function (요청, 응답) {
    응답.writeHead(200, {
        'Connection': 'keep-alive',
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
    });
    db.collection('message')
        .find({ parent: 요청.params.id })
        .toArray()
        .then((결과) => {
            응답.write('event: test\n'); // 사용자에게 데이터 전송 - event: 보낼데이터이름\n
            // 응답.write('data:' + 결과 + '\n\n'); // 사용자에게 데이터 전송 - data: 보낼데이터\n\n
            // -> 이렇게 보내면 toArray()때문에 깨짐. 서버에서 실시간 전송시 문자자료만 전송 가능
            응답.write('data: ' + JSON.stringify(결과) + '\n\n'); // JSON으로 보내기
        });

    // Change Stream 설정
    // const pipeline = [{ $match: {} }]; // 컬렉션 안의 원하는 document만 감시하고 싶으면 $match에 넣어주면 됨
    const pipeline = [{ $match: { 'fullDocument.parent': 요청.params.id } }]; // 원하는 document(ex) parent: 요청.params.id)에 fullDocument. 붙여주기
    const collection = db.collection('message');
    const changeStream = collection.watch(pipeline); // watch(): 실시간 감시해줌

    changeStream.on('change', (result) => {
        console.log(result.fullDocument);
        응답.write('event: test\n');
        응답.write('data:' + JSON.stringify([result.fullDocument]) + '\n\n');
    }); // 해당 컬렉션에 변동사항이 생기면 여기 코드를 실행
});

 

2. 채팅 페이지 - 뷰

<chat.ejs>

<div class="col-8 p-0">
    <div class="chat-room border" style="max-height: 25rem; overflow-y: scroll">
        <div class="card m-4 border border-0" style="width: 18rem; height: 25rem">
            <ul class="list-group list-group-flush chat-content">
                <li class="list-group-item list-group-item-secondary mt-2 mb-2">
                    <span class="chat-box">채팅방1 내용</span>
                </li>
            </ul>
        </div>
    </div>
    <div class="input-group mt-3">
        <input class="form-control" id="chat-input" />
        <button class="btn btn-secondary" id="send">전송</button>
    </div>
</div>

 

3. 서버에서 보낸 데이터 모두 가져오기

<chat.ejs>

var 가져온거 = JSON.parse(e.data); // 서버에서 보낸 데이터
가져온거.forEach((i) => {
    $('.chat-content').append(
        '<li class="list-group-item list-group-item-secondary mt-2 mb-2"><span class="chat-box">' +
            i.content +
            '</span></li>'
    );
});

 

4. 채팅방 입장한 상태에서 채널 나가기

<chat.ejs>

$('.list-group-item').click(function () {
    지금누른채팅방id = this.dataset.id;
    $('.chat-content').html('');
    if (eventsource != undefined) {
        // 채팅방에 입장한 상태에서 채널 나가기
        eventsource.close();
    }
    ...

 

더보기
var 지금누른채팅방id;
var eventsource;

// 채팅방 하나 클릭하면
$('.list-group-item').click(function () {
    지금누른채팅방id = this.dataset.id;
    $('.chat-content').html('');

    if (eventsource != undefined) {
        // 채팅방에 입장한 상태에서 채널 나가기
        eventsource.close();
    }

    // 여기 채널로 입장
    eventsource = new EventSource('/message/' + 지금누른채팅방id);
    eventsource.addEventListener('test', function (e) {
        var 가져온거 = JSON.parse(e.data); // 서버에서 보낸 데이터
        가져온거.forEach((i) => {
            $('.chat-content').append(
                '<li class="list-group-item list-group-item-secondary mt-2 mb-2"><span class="chat-box">' +
                    i.content +
                    '</span></li>'
            );
        });
    });
});
$('#send').click(function () {
    var 채팅내용 = $('#chat-input').val();
    var 보낼거 = {
        parent: 지금누른채팅방id,
        content: 채팅내용,
    };
    $.post('/message/' + 지금누른채팅방id, 보낼거).then(() => {
        console.log('전송 성공');
    });
});

 

 

 

댓글