실시간 서버 만들기 websocket

이태규·2022년 3월 15일
0

vue

목록 보기
16/21

웹 소켓이란

웹 소켓은 HTML5에 새로 추가된 스펙으로 실시간 양방향 데이터 전송을 위한 기술이며, HTTP와 다르게 WS라는 프로토콜을 사용한다. 처음에 웹 소켓 연결이 이루어지고 나면 그다음부터는 계속 연결된 상태로 있으므로 따로 업데이트가 있는지 요청을 보낼 필요가 없다. 업데이트할 내용이 생겼다면 서버에서 바로 클라이언트에 알린다. HTTP 프로토콜과 포트를 공유할 수 있으므로 다른 포트에 연결할 필요도 없다.

웹 소켓이 나오기 이전에는 HTTP 기술을 사용하여 실시간 데이터 전송을 구현했다. 그중 한 가지가 폴링. HTTP가 클라이언트에서 서버로 향하는 단방향 통신이므로 주기적으로 서버에 새로운 업데이트가 있는지 확인하는 요청을 보낸 후, 있다면 새로운 내용을 가져오는 단순 무식한 방법

참고로 서버센트 이벤트(SSE)라는 기술도 등장. 서버에서 클라이언트로 데이터를 보내는 단방향 통신

1. 모듈 설치하기

npm i --socket.io => 벡엔드
npm i --socket.io-client@4.4.1 => 프런트

백엔드, 프론트 버젼 맞추기

2. express에서 라우터 만들고 설정하기

var express = require('express');
var router = express.Router();

const app = express();
const http = require('http');
const httpServer = http.createServer(app);

const {Server} = require('socket.io');
const io = new Server(httpServer, {path:'/socket'});

httpServer.listen(3001, ()=>{
    console.log("http:127.0.0.1:3001/socket");
})

// 클라이언트가 접속했을 수행됨
io.on('connection', (socket) =>{
    console.log(socket);
})

module.exports = router;

app.js에서 router 등록

require('./routes/chat'); //rest apt가 아님, url 필요없음

다음과 같은 코드는 웹이 아니라서 지워도 됨.

// /* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});

3. vue.confing.js에서 설정하기

module.exports = {
    devServer:{
        proxy : {
            '/member' : { 
                target:'http://localhost:3000',
                changeOrigin :true,
                logLevel : 'debug'
            },
            
            '/socket' : { 
                target:'http://localhost:3001',
                changeOrigin :true,
                logLevel : 'debug'
            },
        },
    }

rest => 데이터 요청 주고 받기
socket.io, websocket => 문자나 파일을통신
webrtc => 실시간 화상채팅

4. vue main.js에 사용등록하기

import io from 'socket.io-client';
const socket = io("/", {transports:['websocket'], path: '/socket'});



const app = createApp(App);
app.config.globalProperties.$socket = socket;

컴포넌트에서 사용가능하도록 설정

5. 사용하기

<template>
    <div>
        <h3>채팅</h3>
        <hr />

    </div>
<template>
    <div>
        <h3>채팅</h3>
        <hr />

        <table border="1">
            <tr v-for="tmp in state.list" :key="tmp">
                <td>{{tmp.userid}}</td>
                <td>{{tmp.username}}</td>
            </tr>
        </table>

        <input type="text" v-model="state.userid" @keyup.enter="handleSendMessage"/>
        <input type="text" v-model="state.message" @keyup.enter="handleSendMessage"/>
    </div>
</template>

<script>
import {getCurrentInstance, onMounted, reactive} from '@vue/runtime-core';
export default {
    setup () {

        const handleSendMessage = ()=>{
            // 서버로 보내기
            socket.emit('publish', {
                data: {userid: state.userid, username: state.message}
            })
        }

        onMounted(()=>{
            // 서버에서 오는 값 받기
            socket.on('subscribe', (recv) =>{
                console.log(recv)
                state.list.push(recv)
                
            })
        })


        const state = reactive({
            message: '',
            list : [],
        })
        const app = getCurrentInstance();
        const socket = app.appContext.config.globalProperties.$socket;
        // main.js에 담겼던 게 일로 온거임
        console.log(socket);

        return {
            state,
            handleSendMessage,
            }
    }
}
</script>

<style lang="scss" scoped>

</style>

publish와 subscribe는 백엔드 chat.js에서 임의로 설정한 메소드 이름이다.
chat.js에서 'aaa'로 설정했으면 chatview.vue에서도 aaa로 받아야 한다.

profile
한 걸음씩 나아가자

0개의 댓글