실시간 피드백 애플리케이션

http://springsprout.org:11000

여기에 접속하시면 써볼 수 있습니다. 지금은 테스트 중이라서 임의로 발표 두 개를 등록해뒀고, 컨퍼런스 하는 날에는 실제 발표 목록을 띄워 둘 예정입니다.

1

개발은 저랑 윤군이 같이 했고, 봄싹 멤버들이 테스트 할 때 도와줬습니다.

“실시간”이라고 한 이유는 해당 발표에 들어가있으면 다른 사람들이 올리는 피드백이 바로바로 화면으로 뜨기 때문이죠.

2

아직은 기능이 별거 없지만 계속 다듬으면 쓸만해 질 것 같습니다.

사용한 기술은 다음과 같습니다.

  • node.js: 잡습 서버
  • socket.io: 실시간 통신 node 모듈
  • mongoDB: ACID가 필요없는 앱이라서 NoSQL류 중에서 사용하기 편해 보이는 걸로다가..
  • jade: node쪽에서 주로 사용한다는 뷰 템플릿
  • express: node.js 기반 웹 프레임워크
  • mongoose: node.js에서 mongoDB 사용할 때 유용한 모듈
  • nodemon: node 코드 변경되면 자동으로 재배포 해주는 유용한 툴
  • npm: node 패키지 매니저

소스 코드는 오픈 소스로~ Github에 올려뒀습니다.

https://github.com/spring-sprout/realtime-feedback

[Node.js] 윤군의 아래 코드 개선안

크하하 완전 재밌게 풀었다. 잡습도 리플렉션이 있구나..

[javascript]
var params = {‘port’:port,
‘username’:req.session.username,
‘p_id’:req.params.id,
‘title’:”,
‘diffCount ‘ : 0,
‘disCount’ : 0,
‘sameCount’ : 0,
‘likeCount’ : 0,
‘queCount’ : 0,
‘allCount’ : 0
},
presentFn = function(){
Presentations.findById(req.params.id, function(err, p){
if(!p){
res.redirect(‘/list’);
} else {
params.title = p.title;
res.render(‘presentation’,params);
}
});
},
countFn = function(args){
var arg = args[idx++];
var param = {‘to’:params.p_id};
if(arg.emotion){
param.emotion = arg.emotion;
}
Comments.find(param).count(function(err, count){
params[arg.countNm] = count;
arg.callBack.call(this,args);
});
},
functions = [{’emotion’ : ‘불만이 있습니다.’, ‘countNm’ : ‘disCount’, ‘callBack’ :countFn},
{’emotion’ : ‘다르게 생각합니다.’, ‘countNm’ : ‘diffCount’, ‘callBack’ :countFn},
{’emotion’ : ‘좋아합니다.’, ‘countNm’ : ‘likeCount’, ‘callBack’ :countFn},
{’emotion’ : ‘공감하고 있습니다.’, ‘countNm’ : ‘sameCount’, ‘callBack’ :countFn},
{’emotion’ : ‘궁금해 합니다.’, ‘countNm’ : ‘queCount’, ‘callBack’ :countFn},
{‘countNm’ : ‘allCount’, ‘callBack’ :presentFn}
],
idx = 0;

countFn(functions);
[/javascript]

하지만… 결국 돌아가는건 아래 코드랑 똑같자나. 난 직관적인 코드가 더 좋으니, 내 코드에 손을 들겠다. 음하하핫!

그렇다고 고치진 않을께. 잡습 공부하긴 좋은 코드로구나.. +_+


[Node.js] mongoose의 비동기식 처리

때문에…

[javascript]
app.get(‘/p/:id/:title’, function(req, res){
var to = req.params.id;
var disCount, diffCount, likeCount, sameCount, queCount, allCount;
Comments.find({‘to’:to, ’emotion’:’불만이 있습니다.’}).count(function(err, count){
disCount = count;
Comments.find({‘to’:to, ’emotion’:’다르게 생각합니다.’}).count(function(err, count){
diffCount = count;
Comments.find({‘to’:to, ’emotion’:’좋아합니다.’}).count(function(err, count){
likeCount = count;
Comments.find({‘to’:to, ’emotion’:’공감하고 있습니다.’}).count(function(err, count){
sameCount = count;
Comments.find({‘to’:to, ’emotion’:’궁금해 합니다.’}).count(function(err, count){
queCount = count;
Comments.find({‘to’:to}).count(function(err, count){
allCount = count;
res.render(‘presentation’, {‘port’:port, ‘username’:req.session.username, ‘p_id’:req.params.id, ‘title’:req.params.title,’disCount’:disCount, ‘diffCount’:diffCount, ‘likeCount’:likeCount, ‘sameCount’:sameCount, ‘queCount’:queCount, ‘allCount’:allCount});
});
});
});
});
});
});
});
[/javascript]

이게 뭔짓인가 싶네요.. 뭔가 깔끔한 방법 없을까요? ㅠㅠ


[Node.js] mongoos로 MongoDB에 데이터 저장하기

1. mongoose 모듈 로딩(로딩이라는 표현이 맞는지는 모르겠다. node.js에서는 뭐라고 한담?)

(1.5) db 커넥션 정의하기

2. 스키마 정의

3. 사용하기

이런 3단계가 매우 쉽다. 좀 더 구체적으로.. 모델 정보를 담을 js 파일을 만들었다. 이름은 models.js 그리고 그 안에서..

var mongoose = require(‘mongoose’);

이것으로 1번 끝.

var db = mongoose.connect(‘mongodb://localhost/rtfeedback’);

이것으로 2번 끝. 이제 스키마를 정의해보자.

var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;

var Comments = new Schema({
id :ObjectId,
from :String,
to :String,
body :String,
date :Date
});
mongoose.model(“Comments”, Comments);

이것으로 3번 끝..

마지막으로 이 models.js를 하나의 모듈처럼 사용할 수 있도록 exports에 Comments를 추가해주자. 이건 node.js의 모듈 시스템 동작 원리인데.. 뭔가 참 심플해 보인다.

var Comments = exports.Comments = db.model(‘Comments’);

이것으로 모듈화 끝.

이제 models.js를 사용할 apps.js로 넘어가자.

var models = require(‘./lib/models’),
Comments = models.Comments;

여기 보면 models.Comments라고해서 아까 위에서 exports에 추가한 것을 사용할 수 있다.

이제 저장해볼까?

var newComments = new Comments();
newComments.to = channel;
newComments.from = from;
newComments.body = msg;
newComments.date = new Date();
newComments.save(function(err){
console.log(err);
});

끝이닷!!


[Node.js] socket.io로 채널 기능 구현하기

시리즈가 되어야 할 것 같다. 우선 지금까지 구현한 상황을 공유하자면…

이렇다. 처음에는 파폭에서 메시지를 보낸뒤에, 서버에서 해당 메시지를 다시 보내주는지 확인했고, 다음에는 왼쪽에 있는 크롬 브라우저에서 입력한 값을 오른쪽에 있는 파폭으로 전달 됐는지 확인했다.

사실, 초간단 실시간 웹 앱 개발은 매우 간단하다. 그러나… 내가 개발하고자 하는 앱은 채널 개념이 필요하다. 그런데.. Socket.IO에는 채널 개념이 없어서 직접 구현해 줘야 한다.

우선 내가 세운 전략은 이렇다.

1. 브라우저에서 특정 채널이 관리하는 페이지가 뜨면, 메시지에 {‘type’:’subscribe’, ‘channel’:’1′} 이런 식으로 구독할 채널 이름과 구독하겠다는 행위를 알려준다.

– 해당 페이지를 클릭한 순간 구독자가 되는 것이고, 실시간으로 데이터를 전달 받게 된다.

– 그럼 서버가 해당 Map> 형태의 콜렉션에다 client를 집어 넣는다.

2. 해당 페이지에서 메시지를 입력하면 {‘type’:’publish’, ‘channel’:’1′, ‘msg’:’할말’} 이런식으로 메시지를 보낸다.

– 그럼 서버가 Map.get(Channel)을 호출해서 가져온 List를 순회하면서 메시지를 쫙.. send() 해준다.

– 그러면 각 클라이언트로 메시지가 전달 되고..

3. 각 클라이언트의 브라우저에서 소켓으로부터 메시지를 전달 받았을 때 console.log를 찍도록 해봤다.

오예!!! 됐~~~다!!

ps: 아침에 머리감고, 면도하고, 이빨닦는데.. 회사 가기가 무척이나 싫었다.. 그래서 급하게 연차를 내고 집에서 오전에 코딩좀 하고 오후에는 펑펑 놀려고 한다. 이제 ‘구독 해지’만 구현하면 땡이다. 놀자!!!!