1 2 3 4 5 6 L

Page Header > Subtitle

[Node.js] [MongoDB] Application / Mongoose를 이용하여 간단한 채팅 프로그램 개발

1. Node.js 패키지 설치하기

 

Windows에서 console(Mac에서는 Terminal)을 실행하여 프로젝트 폴더로 이동한다.

다음 세 개의 명령어를 입력하여 "connect", "socket.io", "mongoose" 패키지를 다운받는다.

$npm install connect
$npm install socket.io
$npm install mongoose

 

3. HTML 코드 이해 

<span><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Message</title>
<meta name = "viewport" content="width=device-width, initial-scale = 1" />
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src = "http://code.jquery.com/jquery-1.7.1.js"></script>
<script src="/socket.io/socket.io.js"></script>
 
<script>
	$(document).ready(function(){
		var socket = io.connect();
		socket.on('message',function(data){
			var output = '';
			output += '<div class="alert alert-info"><strong>';
			output += data.name;
			output += '</strong> : ';
			output += data.message;
			output += '</div>';
			$(output).prependTo('#content');
		});
 
		socket.on('preload',function(data){
			var output = '';
			output += '<div class="alert alert-info"><strong>';
			output += data.name;
			output += '</strong> : ';
			output += data.message;
			output += '</div>';
			$(output).prependTo('#content');
		});
 
 
		$('#button').click(function(){
			socket.emit('message',
			{
				name: $('#name').val(),
				message:$('#message').val()
			}
			);
			$('#message').val('');
		});
 
		$('#message').keydown(function(e) {
		    if (e.which == 13) {/* 13 == enter <a href="mailto:key@ascii">key@ascii</a> */
		        socket.emit('message',{
					name: $('#name').val(),
					message:$('#message').val()
				});
				$('#message').val('');
		    }
		});
	});
</script>
</head>
 
<body>
	<div style="width:500px;margin:50px">
		<h1>Message</h1>
		<div class="form-group">
		    <label for="User Name">user name</label>
		    <input type="text" class="form-control" id="name" placeholder="User Name"/>
	  	</div>
	  	<div class="form-group">
	  		<label for="Message">message</label>
		    <input type="text" class="form-control" id="message" placeholder="Message"/>
	    </div>
	    <div class="form-group">
	    	<button id = 'button' type="button" class="btn btn-default" style="width:100%">send message</button>
	    </div>
	    <div id="content">
	    <div>
  	</div>
</body>
</html>​ 

 

(1) HTML 도큐먼트가 준비 완료 시 실행: $(document).ready(function(){...}

(2) 사용자로부터 "User Name"과 "Message"를 받아 ID="content"를 갖는 <div> 태그에 계속 등록 / 등록 시 jQuery의 prepentTo() 함수를 이용하여 신규 메시지는 가장 위로 등록한다.

(3) Message를 등록하는 텍스트 박스에서 키보드 "enter(ASCII key = 13)"를 입력하거나 "send message" 버튼을 마우스 클릭할 때 데이터(name, message)를 socket.io 모듈의 "socket.emit()" 메써드를 통해 "app.js"에서 처리할 수 있도록 전달한다.

(4) (3)번에서 "socket.emit()" 메써드를 통해 데이터가 전달된 후 Message 텍스트 박스의 내용 제거한다.

(5) "socket.on(...)" 메써드를 살펴보면 입력 파라미터로 하나는 'message', 다른 하나는 'preload'를 볼 수 있다. 이 입력 인자는 "app.js" 코드 내용과도 관련이 있는데 이 부분은 "app.js" 내용 설명 시 자세히 다루기로 우선 역할에 대해서만 설명하도록 하겠다.

(6) socket.on('message', function(data){...}); : 사용자로부터 신규 메시지 등록 시 실행되며 클라이언트 페이지에 "User Name : Message" 형식으로 등록된다.

(7) socket.on('preload',function(data){...}); : 새로운 사용자가 채팅 페이지를 열었을 때 실행되며 기존 사용자들의 기록된 대화 내용을 DB로부터 가져와 표시한다.

(8) $('#button').click(function(){...}); : id="button"을 갖는 메시지 전송 버튼 클릭 시 발생되며, 사용자 이름('name')과 메시지('message')를 socket.io로 "app.js"에서 처리할 수 있도록 전달

(9) $('#message').keydown(function(e) {...}); : id="message"를 갖는 메시지 입력 박스에서 메시지 작성 후 키보드의 ENTER키를 누를 때 실행되며, 역할은 (8)과 같다. 

 

3. "app.js" JavaScript 코드 이해 

 

<span><span>// opens file system
var fs = require('fs');
 
// creates WebServer
var http = require('http');
var connect = require('connect');
var app = connect();
var socketio = require('socket.io');
 
// open mongoose
var mongoose = require('mongoose');
 
// connects to MongoDB / the name of DB is set to 'messsage'
mongoose.connect('mongodb://localhost/message');
 
// get the connection from mongoose
var db = mongoose.connection;
 
// gets notified if error occurs
db.on('error', console.error.bind(console, 'connection error:'));
 
// executed when the connection opens
db.once('open', function callback () {
	// if connection open succeeds print out the following in the console
  	console.log("open: success");
});
 
// creates DB schema for MongoDB / requires 'username' & 'message'
var userSchema = mongoose.Schema({
    username: 'string',
    message: 'string'
});
 
// compiles our schema into a model
var Chat = mongoose.model('Chat', userSchema);
 
// request from web browser
app.use('/', function(req,res,next){
	if(req.url != '/favicon.ico'){
		fs.readFile(__dirname+'/message.html', function(error, data){
			res.writeHead(200, {'Content-Type':'text/html'});
			res.write(data);
			res.end();
		});
	}
});
 
// creates server
var server = http.createServer(app);
server.listen(8008, function(){
	console.log('server listen on port 8008');
});
 
// creates WebSocket Server
var io = socketio.listen(server);
 
// executed on connection
io.sockets.on('connection', function(socket) {
 
	// receives message from DB
	Chat.find(function (err, result) {
		for(var i = 0 ; i < result.length ; i++) {
			var dbData = {name : result[i].username, message : result[i].message};
			io.sockets.sockets[socket.id].emit('preload', dbData);
		}
	});
 
 
	// sends message to other users + stores data(username + message) into DB
	socket.on('message', function(data) {
 
		io.sockets.emit('message', data);
		// add chat into the model
		var chat = new Chat({ username: data.name, message: data.message });
 
		chat.save(function (err, data) {
		  if (err) {// TODO handle the error
		  	console.log("error");
		  }
		  console.log('message is inserted');
		});
 
	});
});​ 

 

Line 1 - 27 : Node.js와 MongoDB를 연동하는 방법을 참고하시기 바란다.

Line 30 - 34 : Schema를 설정하는 부분이다. 데이터는 "username"과 "message"이다.

Line 36 : 방금 설정한 Schema를 Mongoose model로 컴파일한다. 컴파일 된 model은 "Chat"이라는 변수에 저장된다.

Line 39 - 48 : 웹 브라우저 주소창에 (web host + '/') 입력 시 실행된다. 만약 local host를 사용 중이라면 주소창에 "localhost:<server port number>/" 또는 "127.0.0.1:<server port number>/" 입력 시 실행된다. 참고로 "/"는 브라우저 주소 창에서 생략되더라도 자동으로 입력된 것으로 판단한다. 실행 시 Node.js의 file system 모듈(var fs = require('fs');)에 의해 "message.html" 파일을 읽는다.

Line 50 - 53 : Server를 생성하고 8008번 포트를 연다.

Line 55 : Web socket을 열고 방금 생성한 server와 연결한다.

Line 59 : Web socket이 연결되는 순간 실행된다.

Line 61 - 64 : DB로부터 데이터를 가져온다. 가져온 데이터는 "result"에 포함되며 전체 아이템 수(result.length)를 반복하며 각 아이템에 대해 "name"(name : result[i].username)과 "message"(message : result[i].message)로 분류하여 dbData에 저장 후 socket.io 모듈 메써드(io.sockets.sockets[socket.id].emit('preload', dbData);)를 통해 HTML로 데이터를 전달한다. 이 때 "emit(... , ...)" 메써드의 첫번째 입력 인자로 "preload"를 두번째 입력 인자로 "dbData" 사용하였는데 이는 HTML의 "socket.on(...)" 메써드와 짝이 되어 HTML측에 dbData를 전달한다.

Line 70 - 84 : HTML측에서 "message"가 event 발생 시, (1) 채팅 정보(username / message)를 다른 사용자에게 전달하여 각 사용자의 HTML 페이지에 렌더링(io.sockets.emit('message', data);) (2) 현재DB의 collection(model)에 추가(var chat = new Chat({ username: data.name, message: data.message });) 후 저장(chat.save(function (err, data) {...});)한다. 만약 저장 시 에러가 발생하면 "error" 메시지가 출력되며 성공하면 "message is inserted"가 출력된다. 

 

0
0
이 글을 페이스북으로 퍼가기 이 글을 트위터로 퍼가기 이 글을 카카오스토리로 퍼가기 이 글을 밴드로 퍼가기
captcha
자동등록방지 숫자입력

JS/Node.js

번호 제목 글쓴이 날짜 조회수
39 javascript [javascript] async, await를 사용하여 비동기 javascript를 동기식으로 만들자 미도어묵 02-18 1,022
38 javascript JavaScript 합집합, 교집합, 차집합, 대칭차 미도어묵 11-23 1,270
37 javascript jQuery 플러그인 부트스트랩의 콤포넌트(modal) 미도어묵 10-04 1,132
36 javascript Javascript 숫자에 천단위로 콤마(,) 찍기 미도어묵 08-20 791
35 javascript 함수형 프로그래밍 - 함수형으로 전환 미도어묵 08-09 856
34 Node.js nodejs & api call example 미도어묵 06-25 814
33 javascript jQuery 핸드폰 번호 체크하기 미도어묵 06-25 843
32 Node.js Node.js 업그레이드 미도어묵 04-23 761
31 Node.js node.js cross 도메인 header 처리 미도어묵 03-12 804
30 javascript hls.js 및 데모 미도어묵 02-22 795
29 Node.js node.js memcached_guide 미도어묵 01-02 799
28 Node.js clustering node + socket.io + redis 사용법 미도어묵 09-29 1,597
27 javascript script sample 예제 관리자 09-20 818
26 Node.js 커넥션 연결 확인 관리자 09-01 754
25 javascript [문법] [TypeScript] Electron + Vue.js 예제 관리자 07-24 1,082
24 javascript 웹 풀스택 입문을 위한 약 500페이지 분량의 교재 관리자 07-11 903
23 javascript [TypeScript] 타입스크립트 기초 세미나 자료 관리자 06-10 876
22 javascript javascript 함수 지향 관리자 04-08 787
21 Node.js Node.js 로 웹 사이트 데이터 가져오기 관리자 04-06 826
20 Node.js [MongoDB] Application / Mongoose를 이용하여 간단한 채팅 프로그램 개발 관리자 03-30 878