1. 에디터 : Visual Studio Code를 이용
2. node 버전 : 14.16
const express = require('express');
const http = require('http');
const app = express();
const path = require('path');
const server = http.createServer(app);
const socketIO = require('socket.io');
const moment = require('moment');
const io = socketIO(server);
app.use(express.static(path.join(__dirname, "src")));
const PORT = process.env.PORT || 5000;
io.on ("connection", (socket) => {
socket.on('chatting', (data) => {
const {name, msg} = data;
io.emit('chatting', {
name,
msg,
time: moment(new Date()).format("hh:mm A")
});
});
});
server.listen(PORT, () => console.log(`server is running : ${PORT}`));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="wrapper">
<div class="user-container">
<label for="nickname">대화명</label>
<input type="text" id="nickname">
</div>
<div class="display-container">
<ul class="chatting-list">
</ul>
</div>
<div class="input-container">
<span>
<input type="text" class="chatting-input">
<button class="send-button">전송</button>
</span>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script src="js/chat.js"></script>
</body>
</html>
"use strict"
const socket = io();
const nickname = document.querySelector("#nickname");
const chatList = document.querySelector(".chatting-list");
const chatInput = document.querySelector(".chatting-input");
const sendButton = document.querySelector(".send-button");
const displayContainer = document.querySelector(".display-container");
chatInput.addEventListener("keypress", (event) => {
if(event.keyCode === 13) {
send();
}
});
function send() {
const param = {
name : nickname.value,
msg: chatInput.value
};
socket.emit("chatting", param);
}
sendButton.addEventListener("click", send());
socket.on('chatting', (data) => {
const {name, msg, time} = data;
const item = new LiModel(name, msg, time);
item.makeLi();
displayContainer.scrollTo(0, displayContainer.scrollHeight);
});
function LiModel(name, msg, time) {
this.name = name;
this.msg = msg;
this.time = time;
this.makeLi = () => {
console.log(`nickname: ${nickname.value} / name: ${this.name}`);
const li = document.createElement("li");
li.classList.add(nickname.value === this.name ? "sent" : "received");
const dom = `
<span class="profile">
<span class="user">${this.name}</span>
<img class="image" src="https://placeimg.com/50/50/any" alt="any">
</span>
<span class="message">${this.msg}</span>
<span class=time>${this.time}</span>
`;
li.innerHTML = dom;
chatList.appendChild(li);
};
}
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
.wrapper {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
.user-container {
background: #a9bdce;
flex: 1;
display: flex;
justify-content: flex-start;
align-items: center;
padding: 0.5rem;
}
.user-container label {
font-size: 14px;
margin-right: 1rem;
}
.user-container input {
border-radius: 3px;
border: none;
height: 100%;
}
.display-container {
flex: 12;
background: #b2c7d9;
overflow-y: scroll;
}
.input-container {
flex: 1;
display: flex;
justify-content: stretch;
align-items: center;
}
.input-container span {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 0.3rem;
width: 100%;
height: 100%;
}
.chatting-input {
font-size: 12px;
height: 100%;
flex: 8;
border: none;
}
.send-button {
flex: 1;
background: #ffeb33;
border: none;
height: 100%;
border-radius: 3px;
}
.chatting-list li {
width: 90%;
padding: 0.3rem;
display: flex;
justify-content: flex-start;
align-items: flex-end;
margin-top: 0.5rem;
}
.profile {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex: 1;
}
.profile .user {
font-size: 10px;
margin-bottom: 0.2rem;
}
.profile .image {
border-radius: 50%;
object-fit: cover;
width: 50px;
height: 50px;
}
.message {
border-radius: 5px;
padding: 0.4rem;
font-size: 12px;
margin: 0 5px;
flex: 7;
}
.time {
font-size: 10px;
margin: 0 5px;
}
.sent {
flex-direction: row-reverse;
float: right;
}
.sent .message {
background: #ffeb33;
}
.received .message{
background: #fff;
}
댓글 영역