공부한 내용정리/기타

Project - Socket과 ElasticSearch 를 활용한 채팅 사이트 개발일지 [1]

JinHee Han 2022. 4. 9. 14:09

개요

교육받는 기간에 파이널 프로젝트로 제출했던 그룹웨어 프로젝트에서 개발한 채팅 기능을 좀더 정리하여 기록한다.

 

 

프로젝트 변경 목표

- Node.js 로 개발된 채팅기능을 React.js로 새로 개발한다.

- Oracle DB와 연동하여 활용했던 채팅기능을 ElasticSearch로 변경하여 적용한다.

- 개발완료된 부분은 git command로 항상 commit 한다.

 


프로젝트 생성 및 준비

NPM 설치

  • npm init
  • npm install express
  • npm install http
  • npm install fs
  • npm install elasticsearch
  • npm install socket.io
  • npm install app-root-path

GIT remote 

  • git init
  • git add *
  • git commit -m "first commit"
  • git remote add origin (Git repos link)
  • git push -u origin master

프로젝트 개발 

- 메인 app.js 생성

const express = require('express');
const http = require('http');
const fs = require('fs');
const approot = require('app-root-path');
const socket = require('socket.io');
const app = express();

const server = http.createServer(app);

app.use('/css', express.static('./css'))
app.use('/image', express.static('./image'))

app.get('/', (req, res) => {
    fs.readFile('./index.html', function(err,data){
        if(err){
            res.send('Error')
        }else{
            res.writeHead(200, {'Content-Type' : 'text/html'})
            res.write(data)
            res.end()
        }
    })
});

server.listen(3000, () => {
    console.log('Connected at 3000');
});
  • 같은 디렉토리에 index.html 생성 ( body 태그 안에 Test Title 입력 )
  • express 서버 오픈 ( 터미널 : node app.js 실행 ) , 포트 접속해서 정상적으로 뜨는지 확인


- ElasticSearch를 연결할 js 생성

const elasticsearch = require('elasticsearch');

let elasticClient;
let setElasticClient = ()=>{
	// elasticsearch 기본 포트 9200에 연결
    let elasticSet = [{"IP": "localhost", "PORT":"9200"}];
    let elasticUrl = [];
    elasticSet.forEach((item, index) => {
        elasticUrl.push(item.IP + ":" + item.PORT);
    });
    elasticClient = new elasticsearch.Client({
        hosts: elasticUrl
    })
    console.log(elasticUrl);
}

setElasticClient();

module.exports = {
    ping: ()=> {
        elasticClient.ping({
            requestTimeout: 30000,
        }, (error) => {
            if(error) {
                console.log('elasticsearch cluster is down!');
            }
            console.log('All is well at Service');
        });
    },

    // ElasticSearch Index 내의 신규 document 생성
    addDocument: (indexName, _id, payload) => elasticClient.index({
        index: indexName,
        id: _id,
        refresh: 'wait_for',
        body: payload
    }).catch((err) => {
        console.log(err);
        throw err;
    }).then((message) => {
        console.log(message);
    }),

    // ElasticSearch Index에서 id에 해당하는 document 수정
    update: async (indexName, _id, payload) => elasticClient.update({
        index: indexName,
        id: _id,
        body: payload
    }).catch((err) => {
        console.log(err);
        throw err;
    }),

    // ElasticSearch 에서 Index 대상으로 search 실행 
    search: async (indexName, payload) => elasticClient.search({
        index: indexName,
        body: payload
    }).catch((err) => {
        console.log("Error " + err);
    })
    
}

- Socket.io 적용 및 ElasticSearch 연동 확인

 

  •  app.js 에 아래 코드 추가 ( 위에서 작성한 elastic.service.js를 불러옴 )
const io = socket(server);
const esService = require(`${approot}/elasticsearch.service.js`);

 

  • app.js 에 아래 코드 추가 ( socket 요청을 받는 부분 추가 )
io.on('connection', (socket) => {
    socket.on('check', () => {
        console.log('connected Page');
    });
});

 

  • index.html 에 아래 코드 추가 ( app.js의 socket에 요청 )
        <script src="/socket.io/socket.io.js"></script>
        <script>
            const socket = io();
            socket.emit('check'); // 위의 app.js에서 check라는 이름으로 요청
        </script>

 

  • visual code 터미널에서 나타난 log 확인 ( socket 실행 여부 확인 용도) 

상단의 localhost:9200 로그는 elasticsearch.service.js 를 불러와 실행된 로그

 

  • app.js socket 부분 ( io.on ) 수정 ( ElasticSearch 연동 확인용 Es에 있는 index상의 전체 document 불러오기 )
io.on('connection', (socket) => {
    socket.on('check', () => {
        console.log('connected Page');
    });

    socket.on('checkEsConn', () => {
        let checkIndex = esService.search("testindex", {
            "query": {
                    "match_all" : {}
                }
        });
        //Promise 형태로 나타난 checkIndex 값을 출력
        checkIndex.then(function(result){
            console.log(result.hits.hits[0]);
        })
    })
});

 

  • index.html 수정
        <script src="/socket.io/socket.io.js"></script>
        <script>
            const socket = io();
            socket.emit('check'); // check 요청
            socket.emit('checkEsConn');
        </script>

 

 

  • 페이지 접속(localhost:3000) 및 visual code 터미널에서 나타난 log 확인  

왼쪽: Visual Code 터미널에서 확인되는 Log , 오른쪽: Kibana 에서 확인가능한 내용

 

( Kibana에서 ES 의 testindex에서 확인되는 내용을 Log로 확인할 수 있으면 ES가 연동되었다는 것을 알 수 있다.)

 


다음 구현 목표

  • 메인 화면 및 로그인 , 회원 가입 기능 구현
  • 채팅방 하나를 임시로 만들고 두 사용자 간의 채팅 구현 (우선 Node로 구현 예정)