본문 바로가기
ETC/develop

node.js & Express Develop#3

by asdf12345 2021. 3. 16.

[ node.js 개발일지 3일 ]

Table of contents

#0 Concept

#1 Develop

#0. Concept

포트 설정, express 프레임워크에서의 routing 개념

 

  • 포트 설정

경로 /bin/www.js 소스코드 내용

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
  • Routing

Routing이란? view와 URL을 연결

 

 

#1.  Develop

Client2Server 송/수신 로직 분석을 위한 Routing & Template 문법 습득, DB, Redis 이용

  • Routing

Routing이란? view와 URL을 연결

 

1. View 생성

view를 veiws 폴더하위에 template 생성

경로 : view/test.jade

extends layout

block content
    h1= title
    p 테스트 페이지입니다! HOW WONDER!

2. Routing

view와 URL을 연결해주기 위해 index.js에 routing코드 추가

경로 : routes/index.js 

router.get('/test', function(req, res, next) {
  res.render('test', { title: 'Test' });
}); 

 

 

  • Template 문법

1. Template 문법#0 ( Tag 명, Class, Text )

1) Pug 문법 

html
    head
    body
    div#goormDiv1 Hello Pug! //Tag 고유명 + Text
    div#goormDiv2.divStyle1 
    .divStyle2 //Class명

2) Html 결과

<html>
    <head> </head>
    <body> 
        <div id="goormDiv1">Hello Pug!</div>
        <div class="divStyle2"></div>
    </body>
</html>    

 

2. Template 문법#1 ( 동적 콘텐츠(Express가 Pug Engine에 JSON Data 전송 시, 처리) 표기 )

1. Pug 문법

html
    head
        title= title
    body
        div#subject #{title} //HTML Character Entities 변환
        div#msg !{message} //HTML Character Entities 미변환 -> XSS삽입 가능

2. Html 결과

<html>
    <head> </head>
    <body>
        <div id="subject">goorm</div>
        <div id="msg">Welcome to GoormEdu</div>
    </body>
</html>

 

 

  • Client & Server (이벤트 등록 & 이벤트 발생 시, 실행)

1. Client2Server

Client Side에서 "전송" 버튼 클릭 시, chat 함수 실행되며, socket.emit()를 통해 name, message값을 서버로 전송

2. Server2Client

Client 측에서 name, message 값 전송 시, Server 측에서 값 수신 후 Server Console에 로그 생성

io.emit()의 인자 값인 receive message 이벤트를 호출함

Client 는 receive message함수를 실행하여 chatLog Tag 명을 찾은 후 msg 값을 추가해줌.

3. Example

Server

// server.js

var express = require('express');
var app = express();
var http = require('http').Server(app); 
var io = require('socket.io')(http);    
var path = require('path');

app.set('views', './views');
app.set('view engine', 'pug');
app.use(express.static(path.join(__dirname, 'public')));

app.get('/', (req, res) => {  
  res.render('chat');
});

var count=1;
io.on('connection', function(socket){ 
  	console.log('user connected: ', socket.id);  
  	var name = "익명" + count++;                 
	socket.name = name;
  	io.to(socket.id).emit('create name', name);   
	io.emit('new_connect', name);
	
	socket.on('disconnect', function(){ 
	  console.log('user disconnected: '+ socket.id + ' ' + socket.name);
	  io.emit('new_disconnect', socket.name);
	});

	socket.on('send message', function(name, text){ 
		var msg = name + ' : ' + text;
		if(name != socket.name)
			io.emit('change name', socket.name, name);
		socket.name = name;
    	console.log(msg);
    	io.emit('receive message', msg);
	});
	
});

http.listen(3000, function(){ 
	console.log('server on..');
});

Client

doctype 5
html
  head
    title= 'Chat'
    link(rel='stylesheet', href='/stylesheets/style.css')
    link(rel="stylesheet", href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css", integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous")
    script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js", integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous")
    script(src='/socket.io/socket.io.js')
    script(src='//code.jquery.com/jquery-1.11.1.js')
  body
    center
      div
        button.btn.btn-info(type='button') Goorm 채팅방
      div
        textarea#chatLog.form-control(readonly='')
      form#chat
        input#name.form-contorl(type='text')
        input#message.form-contorl(type='text')
        button.btn.btn-primary(type='submit') 전송
      #box.box
	  
    script.
      var socket = io(); 
	  
      $('#chat').on('submit', function(e){ 
      socket.emit('send message', $('#name').val(), $('#message').val());
      $('#message').val('');
      $('#message').focus();
      e.preventDefault();
      });
	  
      socket.on('create name', function(name){ 
      $('#name').val(name);
      });
	  
      socket.on('change name', function(oldname, name){ 
      $('#name').val(name);
      $('#chatLog').append('<알림> ' + oldname + '님이 ' + name +'님으로 닉네임을 변경했습니다.\n');
      });
	  
      socket.on('receive message', function(msg){ 
      $('#chatLog').append(msg+'\n');
      $('#chatLog').scrollTop($('#chatLog')[0].scrollHeight);
      });
	  
      socket.on('new_disconnect', function(name){
      $('#chatLog').append('<알림> ' + name + '님이 채팅창을 떠났습니다.\n');
      });
	  
      socket.on('new_connect', function(name){
      $('#chatLog').append('<알림> ' + name + '님이 채팅창에 접속했습니다.\n');
      });

 

  • DB 연결 (NoSQL MongoDB)

모듈 import

var mongoose = require('mongoose');

DB 연결

mongoose.connect('mongodb+srv://[Atlas 주소 붙여넣고 패스워드 수정, 클러스터 이름 수정]', {useNewUrlParser: true});
var db = mongoose.connection;
db.on('error', console.error.bind(console, "connection error:"));
db.once('open', () => {
	console.log("DB connected");
});

DB Data 처리

mongoose.connect('mongodb://[mLab 홈페이지에서 복사한 코드 붙여넣은 후 user부분과 비밀번호 부분 수정]', {useNewUrlParser: true});
var db = mongoose.connection;
db.on('error', console.error.bind(console, "connection error:"));
db.once('open', () => {
	console.log("DB connected");
});

var Schema = mongoose.Schema;

var Memo = new Schema({
	author: String,
	contents: String,
	date: Date
});

var memoModel = mongoose.model('Memo', Memo);

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

router.get('/load', function(req, res, next) {
	memoModel.find({}, function(err, data){
		res.json(data);
	});
});

router.post('/write', function(req,res,next) {
	var author = req.body.author;
	var contents = req.body.contents;
	var date = Date.now();
	var memo = new memoModel();
	
	memo.author = author;
	memo.contents = contents;
	memo.date = date;
	memo.comments = [];
	
	memo.save(function (err) {
		if (err) {
			throw err;
		}
		else {
			res.json({status: "SUCCESS"});
		}
	});
});

router.post('/del', function(req, res, next) {
	var _id = req.body._id;
	
	memoModel.remove({_id: _id}, function(err, result) {
		if(err) {
			throw err;
		}
		else {
			res.json({status: "SUCCESS"});
		}
	});
});

router.post('/modify', function(req, res, next) {
	var _id = req.body._id;
	var contents = req.body.contents;
	
	memoModel.findOne({_id: _id}, function(err, memo) {
		if(err) {
			throw err;
		}
		else {
			memo.contents = contents;
			
			memo.save(function (err) {
				if (err) {
					throw err;
				}
				else {
					res.json({status: "SUCCESS"});
				}
			});
		}
	});
});

module.exports = router;

 

  • Redis 이용

Redis란 ? 메모리에 존재하는 키-값의 쌍으로, 빠른 속도로 데이터 저장 및 관리 가능하게 해주는 도구

// redis.js


var redis = require('redis');
    // 클라이언트 객체 생성
    var client = redis.createClient();
    client.on('error', function (err) {
       console.log('Error ' + err);
    });

    // 값을 저장 (일반, 해쉬 테이블 저장)
    client.set('String Key', 'String Value', redis.print);
    client.hset('Hash Key', 'HashTest 1', '1', redis.print);
    client.hset(['Hash Key', 'HashTest 2', '2'], redis.print);

    // 값을 가져옴
    client.get('String Key', function (err, reply) {
       console.log(reply.toString());
    });

    // 해시 테이블의 값을 가져옴
    client.hkeys('Hash Key', function (err, replies) {
       console.log(replies.length + ' replies:');
       replies.forEach(function (reply, i) {
          console.log('  ' + i + ': ' + reply);
       });

    });

    // 키값으로 배열 형태로 얻음.
    client.hgetall('Hash Key', function (err, obj) {
       console.dir(obj);
    });

 

CLEAR~!

 

'ETC > develop' 카테고리의 다른 글

Flutter Application Develop just For me:D#1  (0) 2023.05.11
node.js & Express Develop#2  (0) 2021.03.14
node.js & Express Develop#1  (0) 2021.03.12
node.js & Express Develop#0  (0) 2021.03.11