์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- JavaScript
- Java
- ์นดํ๋๊ฐ
- ์ฑ
- ํ์ด์ฌ
- Python
- ๋ฐฐ์์ ๋ฐฐ์
- ๊ฐ๋ฐ
- ์๋ฐ
- ๊ฐ์ดํ ์ข ๋ญ๊ฐ๋น
- html
- ์ฝ๋ฉ
- ์ค๋ผํด
- ์๋ฐ์คํฌ๋ฆฝํธ
- ํฐ์คํ ๋ฆฌ์ฑ๋ฆฐ์ง
- ์ํ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค
- ํ๋ก๊ทธ๋๋ฐ
- ๋๊ฐ
- ํ์ฒ์ ๋ฆฌํธ๋ฆฌํธ
- ๋ฐ์ํ
- ์ค๋ธ์
- ์ํ์ฃผ
- ์นํผ๋ธ๋ฆฌ์ฑ
- ์ ๋ฆฌํธ๋ฆฌํธ
- css
- ๊น๋ฏธ๊ฒฝ์๋งํ์์
- ๋ ์
- database
- K๋ฐฐํฐ๋ฆฌ๋ ๋ณผ๋ฃจ์
- Today
- Total
JiYoung Dev ๐ฅ
[Node.js] ์ฑํ ๋ฐฉ ๋ง๋ค๊ธฐ (sequelize, socket.io, express-session, nunjucks) (2023.07.11~13) ๋ณธ๋ฌธ
[Node.js] ์ฑํ ๋ฐฉ ๋ง๋ค๊ธฐ (sequelize, socket.io, express-session, nunjucks) (2023.07.11~13)
Shinjio 2023. 7. 13. 14:11app.js
//๋ชจ๋์ฌ์ฉ
const express = require('express') //express
const session = require('express-session') //session
const fileStore = require('session-file-store')(session) //session ์ ์ฅ
const {sequelize} = require('./models') //sequelize (ORM)
const webSocket = require('./socket') //socket
const nunjucks = require('nunjucks') //nunjucks - ํ
ํ๋ฆฟ์์ง
const bodyParser = require('body-parser') //jsonํ์
body ํ์ฑ
//router
const indexRouter = require('./routes') //./routes/index
const memberRouter = require('./routes/member')
const chatRouter = require('./routes/chat')
const app = express()
//sequelize DB ์ฐ๊ฒฐ
//force : false -> ๊ธฐ์กด ํ
์ด๋ธ์ ๊ฑด๋ค์ง ์์
sequelize.sync({force:false})
.then(()=>{console.log('DB ์ฐ๊ฒฐ ์ฑ๊ณต!');})
.catch((err)=>{console.log(err);})
//nunjucks ์ค์
//view๋ indexRouter์์ ์ฌ์ฉํ๋ฏ๋ก ์์ชฝ์์ ์์ฑํด์ผ ํจ
app.set('views', __dirname+'/views')
app.set('view engine', 'html')
nunjucks.configure('views', {
express : app,
watch : true
})
//์ธ์
์ค์
app.use(
session({
httpOnly: true,
secret: "secretkey",
resave: false,
cookie:{
httpOnly: true,
},
store: new fileStore(),
})
);
app.use(express.urlencoded({extended:true})) //post์์ฒญ - req.body ํ์ฑ
app.use(bodyParser.json()) //jsonํ์์ body ํ์ฑ
//router ์ฐ๊ฒฐ
app.use('/', indexRouter)
app.use('/member', memberRouter)
app.use('/chat', chatRouter)
//์ ์ ํ์ผ ๊ฒฝ๋ก ์ค์
app.use(express.static(__dirname+'/public'))
//์๋ฒ ์ฐ๊ฒฐ
app.set('port', process.env.PORT||8888)
const server = app.listen(app.get('port'), ()=>{
console.log(app.get('port'), '๋ฒ ํฌํธ์์ ์๋ฒ ์ฐ๊ฒฐ ๋๊ธฐ์ค...');
})
//์์ผ ์ฐ๊ฒฐ
//์์ผ์ ์ธ๋ถ์์ ์ฌ์ฉํ ์ ์๋๋ก app์ ํจ๊ป ์ ๋ฌ
//app์ ๋ณ์ ์ ์ฅํ๋ฉด ์ด๋์๋ ์ฌ์ฉํ ์ ์์
webSocket(server, app)
models (sequelize => ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทผ)
index : ๊ธฐ๋ณธ ์ค์
const Sequelize = require('sequelize')
const Member = require('./member')
const Room = require('../models/room')
const Chat = require('../models/chat')
const env = process.env.NODE_ENV || 'development'
//[env] : development๋ง ์ฌ์ฉํ๊ธฐ ์ํด key๊ฐ ์ง์
const config = require('../config/config.json')[env] //๊ฐ๋ฐ์ฉ DB ์ฌ์ฉ
//Sequelize ๊ฐ์ฒด ์์ฑ
//member init ํธ์ถ์ ์ฌ์ฉ
const sequelize = new Sequelize(config.database, config.username, config.password, config)
//sequelize๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํ ๊ฒ์ธ๊ฐ
const db = {} //app (model, sequelize - db ์ฐ๊ฒฐ์ ๋ณด)
db.sequelize = sequelize
db.Member = Member
db.Room = Room
db.Chat = Chat
//ํ
์ด๋ธ ์์ฑ ํ ์ฐ๊ด๊ด๊ณ ์ค์ ๊ฐ๋ฅ >>> init ์งํ ํ associate
//init, associate ์คํ
Member.init(sequelize) //ํ
์ด๋ธ ์์ฑ
//associate๋ ๋ค๋ฅธ ํ
์ด๋ธ๊ณผ์ ๊ด๊ณ ์ค์ ํด์ผ ํ๋ฏ๋ก ๋ค๋ฅธ ํ
์ด๋ธ์ ๋ํ ์ ๋ณด๊ฐ ํ์ํจ => db์์ ๋ด๊ฒจ์ ธ ์์ => ๋งค๊ฐ๋ณ์๋ก db
Room.init(sequelize)
Chat.init(sequelize)
Member.associate(db) //ํ
์ด๋ธ ์ฐ๊ด๊ด๊ณ ์ค์
Room.associate(db)
Chat.associate(db)
module.exports = db
member, chat, room model class ์์ฑ ํ index.js ์ ์ฐ๊ฒฐ
index.js (indexRouter)
1. ๊ธฐ๋ณธ ๊ฒฝ๋ก์ผ ๊ฒฝ์ฐ login.html ํ์ด์ง ๋ ๋๋ง
2. /rooms๋ก ๋ค์ด์ค๋ฉด Room ํด๋์ค๋ก ์ ์ฒด room ์กฐํ ํ rooms.html์ result๋ฅผ ๋ด์์ ํ๋ฉด ๋ ๋๋ง
const express = require('express')
const Room = require('../models/room')
const router = express.Router()
//์ฒซํ์ด์ง
router.get('/', (req, res)=>{
res.render('login') //login.html ๋ ๋๋ง
})
//rooms ๋ณด์ฌ์ฃผ๋ ํ์ด์ง (DB์์ ์ฑํ
๋ฐฉ ๋ฆฌ์คํธ ๋ถ๋ฌ์์ผ ํจ!)
router.get('/rooms', async(req, res, next)=>{
try{
const result = await Room.findAll()
// console.log(result);
//result๋ฅผ html๋ก ๋ณด๋ด์ค์ผ ํจ
res.render('rooms', {rooms:result})
}catch(err){
next(err)
}
})
module.exports = router
member.js
๋ก๊ทธ์ธ ์ฑ๊ณต์ session์ ๋ฐ์ดํฐ ์ ์ฅ ํ /rooms๋ก ์ด๋
const express = require('express')
const Member = require('../models/member')
const router = express.Router()
router.post('/login', async(req, res, next)=>{
console.log(req.body)
let {id, pw} = req.body
try{
const result = await Member.findOne({
where : {id : id, pw : pw}
//id, pw๋ก๋ง ์์ฑํด๋ ๋ค์ด๊ฐ
})
req.session.member = result
req.session.save(function(){
if(result){
res.redirect('/rooms')
}else{
res.redirect('/')
}
})}catch(err){
next(err)
}
})
module.exports = router;
chat.js
const express = require('express')
const Chat = require('../models/chat')
const router = express.Router()
router.get('/:roomid', async(req, res, next)=>{
console.log(req.params.roomid);
//์ง๊ธ๊น์ง ์งํ๋ ์ฑํ
๋ด์ฉ ๋ถ๋ฌ์ค๊ธฐ
try{
const chats = await Chat.findAll({
where : {roomid : req.params.roomid}
})
// console.log('์ฑํ
์ ์ฒด๋ด์ฉ',chats);
//nunjucks์์๋ ๋ฐ๋ก session์ฌ์ฉ ๋ถ๊ฐ๋ฅ -> ๊ฐ์ด ๋ณด๋ด์ค์ผ ํจ
res.render('chat', {roomid : req.params.roomid, userid : req.session.member.id, chats : chats})
}catch(err){
next(err)
}
})
router.post('/:roomid/insert', async(req, res, next)=>{
let roomid = req.params.roomid;
let chat = req.body.chat;
let userid = req.session.member.id;
console.log(roomid, chat, userid);
try{
//์ฑํ
db์ ๋ฐ์ดํฐ ์ฝ์
-> ๋ค๋ฅธ ํด๋ผ์ด์ธํธ ํ๋ฉด์ ๋ณด์ด์ง ์์
const chats = await Chat.create({
roomid : roomid,
chat : chat,
userid : userid
})
//socket ์ฌ์ฉ -> ์ด ์ฑํ
์ ์
๋ ฅํ ํด๋ผ์ด์ธํธ์ ๊ฐ์ ๋ฃธ์ ์๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฐ์ดํฐ ๋ฟ๋ ค์ฃผ๊ธฐ! (์ค์๊ฐ)
//๋ฐ์ดํฐ ๋ฟ๋ฆฌ๊ธฐ (๋ค๋ฅธ ํด๋ผ์ด์ธํธ ํ๋ฉด์ ๋ฐ์ดํฐ ๋ณด์ด๋๋ก)
req.app.get('io').of('/chat').to(roomid).emit('chat', {userid : userid, chat:chat, roomid:roomid})
res.send('OK')
}catch(err){
next(err)
}
})
module.exports = router
์๋ฒ์ธก socket
const socketIO = require('socket.io')
//server : app์์ ์์ฑํ express server
//app : ์ด๋์๋ io ๊ฐ์ฒด ์ฌ์ฉํ ์ ์๋๋ก app ๊ฐ์ ธ์์
module.exports = (server, app)=>{
//express server - socket ์ฐ๊ฒฐ
//1) ์์ผ ๊ฐ์ฒด ์์ฑ
const io = socketIO(server, {path : '/socket.io'})
// ์์ผio ๊ฐ์ฒด๋ฅผ ์ธ๋ถ(๋ผ์ฐํฐ)์์ ์ฌ์ฉํ ์ ์๋๋ก ๋ง๋ค๊ธฐ > app์ ๋ณ์ ์ค์
// -> app์ ๊ฐ์ ธ์์ ์ฌ์ฉํด์ผ ํจ
app.set('io', io)
//2) io ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์ ์ ์ฑ๊ณต, ์ ์ ํด์ , ์๋ฌ ์ด๋ฒคํธ ์ถ๊ฐ
// ๋ผ์ฐํ
(-> ๋ค์์คํ์ด์ค : ๊ธฐ๋ฅ ๊ตฌ๋ถ, ๊ฒฝ๋ก์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ณณ์์ ์ฒ๋ฆฌ)
// - ์ฑํ
๊ธฐ๋ฅ -> /chat
// - ์ค์๊ฐ ์๋ฆผ -> /alarm
// - ํต์งธ๋ก ์ฒ๋ฆฌํ๊ณ ์ถ์ ๋ io.on
// - namespace ์ค์ : io.of('๊ฒฝ๋ก')
const chat = io.of('/chat') //์ฑํ
๊ด๋ จ ๋ค์์คํ์ด์ค
chat.on('connection', (socket)=>{
//์ฐ๊ฒฐ์ด ๋๋ฉด ํด๋ผ์ด์ธํธ์ ์ฐ๊ฒฐํ๋ ์์ผ์ด ์์ฑ๋จ(์์ผ์ด ํด๋ผ์ด์ธํธ์ ์ ๋ณด ๋ด๊ณ ์์)
console.log('chat ๋ค์์คํ์ด์ค ์ ์ ์ฑ๊ณต ');
//room ์ค์ (room ๊ธฐ๋ฅ์ socket.io์์ ์ ๊ณตํ๊ณ ์์)
// -> ๋ฐฉ์ด๋ฆ(roomid) ์ค์ -> ํด๋ผ์ด์ธํธ์ ์์ฒญ ๊ฒฝ๋ก(request)์ ํฌํจ
//room์ ๋ค์ด๊ฐ ํด๋ผ์ด์ธํธ๋ผ๋ฆฌ๋ง ์ํตํ ์ ์๋๋ก!
const ref = socket.request.headers.referer //ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญํ ์ฃผ์
const roomid = ref.split('/')[ref.split('/').length-1];
console.log(roomid);
//roomid์ ๋ฐ๋ผ์ ๋ฃธ์ ๋ง๋ค์ด์ค - roomid๊ฐ ๊ฐ์ผ๋ฉด ๊ฐ์ ๋ฐฉ์ผ๋ก ๋ค์ด๊ฐ!
socket.join(roomid)
//ํด๋ผ์ด์ธํธ๋ง๋ค ์์ผ ์์ฑ๋๋ฏ๋ก socket์ ์ด๋ฒคํธ ๋ถ์ฌ
socket.on('disconnect', ()=>{
console.log('chat ๋ค์์คํ์ด์ค์์ ์ ์ ํด์ ');
})
//chat ์ด๋ฒคํธ : ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๊ฐ(data)์ ๋ฟ๋ ค์ค
socket.on('chat', (data)=>{
// console.log('socket.js : ',data);
socket.to(roomid).emit(data)
})
}) //์ฑํ
์ฐ๊ฒฐ ์ด๋ฒคํธ
}
socket ํด๋ผ์ด์ธํธ ์ธก - chat.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<fieldset>
<legend>์ฑํ
๋ด์ฉ</legend>
<!-- class ์ง์ : mine -> ๋์ ์ฑํ
๋ด์ฉ (์ค๋ฅธ์ชฝ์ ์ถ๋ ฅ), other -> ๋ค๋ฅธ ์ฌ๋์ ์ฑํ
๋ด์ฉ(์ผ์ชฝ ์ถ๋ ฅ) -->
<div id="chat-list">
{%for chat in chats%}
{%if chat.userid === userid%}
<div class="mine">
<div>{{chat.userid}}</div>
<div>{{chat.chat}}</div>
</div>
{%else%}
<div class="other">
<div>{{chat.userid}}</div>
<div>{{chat.chat}}</div>
</div>
{%endif%}
{%endfor%}
</div>
</fieldset>
<!--๋น๋๊ธฐ ๋ฐฉ์
action : ๋๊ธฐ๋ฐฉ์ -->
<form id="chat-form">
<input type="text" id="chat-input" name="chatinput">
<input type="submit" value="์ ์ก">
</form>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
//ํด๋ผ์ด์ธํธ ์์ผ ๊ฐ์ฒด ์์ฑ (์์ผ ์ฐ๊ฒฐ)
const socket = io.connect('http://localhost:8888/chat', { //chat : chat namespace ์ง์
path: '/socket.io'
})
socket.on('chat', function (data) {
console.log(data);
const div = document.createElement('div')
if (data.userid == '{{userid}}') { //๋ก๊ทธ์ธํ ํด๋ผ์ด์ธํธ๊ฐ ์
๋ ฅํ ์ฑํ
์ด๋ผ๋ฉด
div.classList.add('mine')
} else { //๋ค๋ฅธ ํด๋ผ์ด์ธํธ๊ฐ ์
๋ ฅํ ์ฑํ
์ด๋ผ๋ฉด
div.classList.add('other')
}
//Id ์ถ๋ ฅ div
const divId = document.createElement('div')
divId.textContent = data.userid
div.appendChild(divId) //์์ div๋ก ์ถ๊ฐ
//์ฑํ
์ถ๋ ฅ div
const divChat = document.createElement('div')
divChat.textContent = data.chat
div.appendChild(divChat) //divId ์์์ผ๋ก ์ถ๊ฐ๋จ
//#chat-list์ div ์ถ๊ฐ
document.getElementById('chat-list').appendChild(div)
})
//submit ๋ฒํผ์ ๋๋ ์ ๋ form์ input ๋ด์ฉ์ ๊ฐ์ง๊ณ ์์ผํ๋ค!
document.getElementById('chat-form').addEventListener('submit', function (e) {
//submit ๊ธฐ๋ณธ๊ธฐ๋ฅ : ๋๊ธฐ ๋ฐฉ์์ผ๋ก ์๋ฒ๋ก ์์ฒญ >> ๋ง๊ธฐ
//e(event) > submit event
e.preventDefault() //์๋ฒ๋ก ์์ฒญํ๋ submit์ ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ ๋ง๊ธฐ
// console.log(e.target.chatinput.value); //์๋ฒ๋ก ๋ณด๋ด์ DB๋ก ์ ์ฅ
console.log(e)
if (e.target.chatinput.value) {
//์๋ฒ๋ก ์ฑํ
๋ด์ฉ ์ ์ก
axios.post('/chat/{{roomid}}/insert', {
chat: e.target.chatinput.value
//jsonํํ๋ก ์ ์ก
})
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err);
})
}
})
</script>
</body>
</html>
์์ผ ํต์ ์ ๋ฆฌ
socket.js ์์ฑ - ์๋ฒ๋จ
1. socket.io ๋ชจ๋ ๊ฐ์ ธ์ค๊ธฐ
2. exports = (server, app) => {}
express server์ ์์ผ ์ฐ๊ฒฐํ๊ธฐ ์ํด server ๋งค๊ฐ๋ณ์๋ก ์ฌ์ฉ,
router์์ ์ฌ์ฉํ๊ธฐ ์ํด app ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ => app์์ ๋ณ์๋ก ์ ์ฅํ๋ฉด ์ด๋์๋ ์ฌ์ฉํ ์ ์์
2.1. ์์ผ ๋ชจ๋๋ก ์์ผ ๊ฐ์ฒด ์์ฑ. ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋, server์ path๋ฅผ ๋งค๊ฐ๋ณ์๋ก ์ ์ฅ
: ์ฌ๊ธฐ์ path์ ์๋ฏธ๋???
app.set์ผ๋ก ์์ผ ๊ฐ์ฒด ์ ์ฅ
2.2
chat ๋ค์์คํ์ด์ค ์ค์ - io.of('/chat')
์ฑํ
์ ์ฐ๊ฒฐ๋๋ฉด > ํด๋ผ์ด์ธํธ๋ง๋ค ์์ผ ์์ฑ > ์์ผ์ ๋ํ์ฌ ๋ฃธ์์ฑ, ์ ์ํด์ , chat์ด๋ฒคํธ ์ง์
chat.on('connection', (socket)=>{} //์ฐ๊ฒฐ์ด ๋๋ฉด ํด๋ผ์ด์ธํธ์ ์ฐ๊ฒฐํ๋ ์์ผ ์์ฑ๋จ
์์ฑ๋ ์์ผ์์ ์ฃผ์ ๊ฐ์ ธ์์ roomid๋ฅผ ๊บผ๋ด...
socket.join(roomid) => ๋ฃธ ์์ฑ
socket.on('disconnect') => ์ ์ ํด์
socket.on('chat' (data)=>{socket.to(roomid).emit(data) => chat ์ด๋ฒคํธ : roomid์
------------------------------------
chat.html - ํด๋ผ์ด์ธํธ๋จ
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> //axios ํต์
<script src="/socket.io/socket.io.js"></script> //socket ํต์
ํด๋ผ์ด์ธํธ ์์ผ ๊ฐ์ฒด ์์ฑํ์ฌ ์ฐ๊ฒฐ - io.connect(http://localhost:8888/chat) => ์ฌ๊ธฐ๋ ๋ค์ด์ค๋ฉด ์์ผ ์์ฑ
socket.on('chat', function(data)}{
๋ฒํผ ๋๋ ์ ๋ ์ด๋ฒคํธ
= > axios.post (chat/{{roomid}}/insert)๋ก chat ๋ด์ฉ ์ ์ก
}} //chat ์ด๋ฒคํธ - ์๋ฒ๋จ ์์ผ์์ emitํ ๋ฐ์ดํฐ ๋ถ๋ฌ์์ ์ฌ์ฉ
---------------------------------
app.js socket ์ฌ์ฉ ์ค์
const webSocket = require('./socket') //์์ผ ํ์ผ ๊ฐ์ ธ์ค๊ธฐ
//์์ผ์ ์ธ๋ถ์์ ์ฌ์ฉํ ์ ์๋๋ก app์ ํจ๊ป ์ ๋ฌ
//app์ ๋ณ์ ์ ์ฅํ๋ฉด ์ด๋์๋ ์ฌ์ฉํ ์ ์์
webSocket(server, app)