$ npm init
$ npm install express moment socket.io
app.js 파일 생성 후 server 실행시 html 을 불러오기 위한 작업을 한다.
__dirname 을 console.log 로 찍어 보면 이렇게 주수가 나온다.
path.join() 을 쓰는 이유는 운영체제마다 주소의 슬레시 역슬레시가 다르기
때문에 사용한다.
server 에서 socket.io 셋팅을 해야한다.
socket.io 는 http 을 이용해서 통신해야되기 때문이 사진과 같이 io 변수에 셋팅을 해준후
io에 on() 함수를 사용해서 connection 이라는 method을 이용해서 cnnection 이 이루어지면 실행하게
작업한다.
index.html 파일에서 socket.io 파일을 연결해보자.
express 앱을 사용하고 있으니 절대 경로를 활용해서 nodemodules 파일에 있는 socket.io 를 가져올수있다.
socket.io.js 파일을 제데로 불러오는지 확인해보자!
웹에서 console 에 에러가 뜨지 않으면 잘 불러오는 거다.
만약 불러오지 못한다면
cdnjs 에서 socket.io 를 검색하고 copy script tag 를 클릭하여 복붙하면 된다.
javascript 코드를 사용하기 위한 js 파일을 따로 만들고 연결한다.
chat.js 파일을 만들고
이렇게 코드를 작성하면 server 와 연결이 된다.
emit 은 보내기 위함 method 이고 첫번째 인자값은 연결할 ID 가 오면 되고 두번째 인자값은 보낼 값을 적어주면 된다.
app.js
on() method 를 사용해서 값을 받을수 있다.
첫번째 인자값은 똑같이 연결할 인자값을 주고 두번째인자값은 애로우 함수를 이용해 받은 값을
consol.log 로 찍어보자.
io.emit method 를 사용해서 답변을 해보자.
chat.js
chat.js 파일에서 on method 를 사용해서 값을 받아온걸 찍어보자
웹에서 확인가능하다.
이렇게 하면 기본적인 주고 받는 셋팅이 준비 된것이다.
app.js
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 || 3000;
io.on("connection", (socket) => {
socket.on("chatting", (data) => {
const { name, msg } = data;
io.emit("chatting", {
name,
msg,
time: moment(new Date()).format("h:ss A")
})
})
})
server.listen(PORT, () => {
console.log(`server start ${PORT}`);
})
index.html
< !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>
chat.js
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()
chatInput.value = ""
}
})
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 LiModle(name, msg, time)
item.makeLi()
displayContainer.scroll(0, displayContainer.scrollHeight)
})
function LiModle(name, msg, time) {
this.name = name;
this.msg = msg;
this.time = time;
this.makeLi = () => {
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/200/50/any">
</span>
<span class="message">${this.msg}</span>
<span class="time">${this.time}</span>`;
li.innerHTML = dom;
chatlist.appendChild(li)
}
}
style.css
* {
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: cneter;
padding: 0.3rem;
width: 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;
}
.proffile {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.profile .user {
font-size: 10px;
margin-bottom: 0.3rem;
}
.profile .image {
border-radius: 50%;
object-fit: cover;
width: 50px;
height: 50px;
}
.message {
border-radius: 5px;
padding: 0.5rem;
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;
}
이렇게 작동하는 것을 확인할수 있다.