node.js 채팅 구현

파일구조

app.js

//채팅에 필요한 모듈s
const express = require('express');
const http = require('http');
const app = express();
const server = http.createServer(app);
const fs = require('fs');
const io = require('socket.io')(server);


app.use(express.static('src'));

app.get('/', function (req, res) {

    fs.readFil('./src/index.html', (err, data) => {

        if (err) throw err;

        res.writeHead(200, {
            'Content-Type': 'text/html'
        })
            .write(data)
            .end();
    });
});



io.sockets.on('connection', function (socket) {

    console.log('소켓연결완료');

    socket.on('newUserConnect', function (name) {

        console.log('채팅방 입장');

        socket.name = name;
        var message = name + '님이 접속했습니다';

        io.sockets.emit('updateMessage', {
            name: 'SERVER',
            message: message
        });
    });

    socket.on('disconnect', function () {

        var message = socket.name + '님이 퇴장했습니다';

        socket.broadcast.emit('updateMessage', {
            name: 'SERVER',
            message: message

        });
    })

    socket.on('sendMessage', function (data) {

        console.log("send message");

        data.name = socket.name;
        io.sockets.emit('updateMessage', data);
    });
});

/**/

server.listen(8000, function () {

    console.log('서버 실행중...');

});

 

 

index.js

'use strict';

var socket = io();


// 접속 되었을 때 실행
socket.on('connect', function () {
    var name = prompt('대화명을 입력해주세요.', '');
    socket.emit('newUserConnect', name);
});

var chatWindow = document.getElementById('chatWindow');
socket.on('updateMessage', function (data) {
    if (data.name === 'SERVER') {
        var infoEl = document.getElementById('info');
        infoEl.innerHTML = data.message;

        setTimeout(() => {
            infoEl.innerText = '';
        }, 3000);
    } else {
        var chatMessageEl = drawChatMessage(data);
        chatWindow.appendChild(chatMessageEl);
        chatWindow.scrollTop = chatWindow.scrollHeight;
    }
});

function drawChatMessage(data) {

    var wrap = document.createElement('P');
    var message = document.createElement('span');
    var name = document.createElement('span');

    name.innerText = data.name;
    message.innerText = data.message;

    name.classList.add('output__user__name');
    message.classList.add('output__user__message');

    wrap.classList.add('output__user');
    wrap.dataset.id = socket.id;

    wrap.appendChild(name);
    wrap.appendChild(message);

    return wrap;
}

var sendButton = document.getElementById('chatMessageSendBtn');
var chatInput = document.getElementById('chatInput');

sendButton.addEventListener('click', sendChattingMessage);

chatInput.addEventListener('keydown', function (key) {

    if (key.keyCode == 13) {
        sendChattingMessage();
    }
})

function sendChattingMessage() {
    var message = chatInput.value;

    if (!message) return false;

    socket.emit('sendMessage', {
        message
    });
    chatInput.value = '';

}/**/

 

index.css

더보기

@charset "utf-8".app__wrapmargin0 autopadding50px 0 0positionrelativewidth100%max-width350pxmin-width200pxfont-size14pxborder-top20px solid #5c007abox-sizingborder-boxbox-shadow1px 1px 5px rgba(0,0,0,0.1); } .app__infopositionabsolutetop0width100%height50pxtext-aligncenterline-height50pxcolor#fffbackground#8e24aa; } .app__windowoverflow-yautopadding10px 20pxheight400pxbackground#e1e2e1; } .output__usermargin0margin-bottom10px; } .output__user__namemargin-right:10pxfont-weight:700; } .app__input__wrappadding10pxbackground#f5f5f6; } .app__input__wrap:aftercontent:''display:blockclear:both; } .app__inputfloatleftdisplayblockwidth80%height25pxborder1px solid #cccbox-sizingborder-box; } .app__buttonfloatleftdisplayblockwidth20%height25pxborder1px solid #cccborder-left0background#fffbox-sizingborder-boxcursorpointer; }

 

 

index.html

더보기

<!DOCTYPE html>

<html lang="ko">

 

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <link rel="stylesheet" href="http://ptest.popomon.com:8000/css/index.css">

    <title>chat-app</title>

</head>

 

<body>

    <div class="app__wrap">

        <div id="notice" class="app__info"></div>

        <div id="chatWindow" class="app__window"></div>

        <div class="app__input__wrap">

            <input id="chatInput" type="text" class="app__input" placeholder="대화를 입력해주세요." autofocus>

            <button id="chatMessageSendBtn" class="app__button">전송</button>

        </div>

    </div>

    <script src="http://ptest.popomon.com:8000/socket.io/socket.io.js"></script>

    <script src="http://ptest.popomon.com:8000/js/index.js"></script>

</body>

 

</html>

 

참고

https://codevkr.tistory.com/61?category=719250 

 

https://okayoon.tistory.com/entry/Express-Socketio%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EC%B1%84%ED%8C%85%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0-2-%EC%84%9C%EB%B2%84-%EA%B8%B0%EB%B3%B8-%EC%84%B8%ED%8C%85?category=835827 

 

★참고2

https://ssocoit.tistory.com/category/%23%20%ED%95%99%EC%8A%B5%20%EB%82%B4%EC%9A%A9%20%EC%A0%95%EB%A6%AC/Zoom%20CloneCoding%28JS%29

 

roomId

 

https://fred16157.github.io/node.js/nodejs-socketio-communication-room-and-namespace/

 

 

댓글

Designed by JB FACTORY