-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
417 lines (300 loc) · 11.8 KB
/
app.js
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
/**
* 채팅하기
*
* 그룹 채팅하기
*
* 'room' 이벤트 처리 (command에 방 입장 기능 추가 : join)
*
* @date 2016-11-10
* @author Mike
*/
// Express 기본 모듈 불러오기
var express = require('express')
, http = require('http')
, path = require('path');
// Express의 미들웨어 불러오기
var bodyParser = require('body-parser')
, cookieParser = require('cookie-parser')
, static = require('serve-static')
, errorHandler = require('errorhandler');
// 에러 핸들러 모듈 사용
var expressErrorHandler = require('express-error-handler');
// Session 미들웨어 불러오기
var expressSession = require('express-session');
//===== Passport 사용 =====//
var passport = require('passport');
var flash = require('connect-flash');
// 모듈로 분리한 설정 파일 불러오기
var config = require('./config/config');
// 모듈로 분리한 데이터베이스 파일 불러오기
var database = require('./database/database');
// 모듈로 분리한 라우팅 파일 불러오기
var route_loader = require('./routes/route_loader');
// Socket.IO 사용
var socketio = require('socket.io');
// cors 사용 - 클라이언트에서 ajax로 요청 시 CORS(다중 서버 접속) 지원
var cors = require('cors');
// 익스프레스 객체 생성
var app = express();
//// 전달하고자 하는 데이터 생성
//var inputData = { data1 : 'node to tomcat testdata1', data2 : 'node to tomcat testdata2'};
//
//
//var opts = {
// host: '127.0.0.1',
// port: 8080,
// method: 'POST',
// path: '/start',
// headers: {'Content-type': 'application/json'},
// body: inputData
//};
//===== 뷰 엔진 설정 =====//
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
console.log('뷰 엔진이 ejs로 설정되었습니다.');
//===== 서버 변수 설정 및 static으로 public 폴더 설정 =====//
console.log('config.server_port : %d', config.server_port);
app.set('port', process.env.PORT || 3000);
// body-parser를 이용해 application/x-www-form-urlencoded 파싱
app.use(bodyParser.urlencoded({ extended: false }))
// body-parser를 이용해 application/json 파싱
app.use(bodyParser.json())
// public 폴더를 static으로 오픈
app.use('/public', static(path.join(__dirname, 'public')));
// cookie-parser 설정
app.use(cookieParser());
// 세션 설정
app.use(expressSession({
secret:'my key',
resave:true,
saveUninitialized:true
}));
//===== Passport 사용 설정 =====//
// Passport의 세션을 사용할 때는 그 전에 Express의 세션을 사용하는 코드가 있어야 함
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
//클라이언트에서 ajax로 요청 시 CORS(다중 서버 접속) 지원
app.use(cors());
//라우팅 정보를 읽어들여 라우팅 설정
var router = express.Router();
route_loader.init(app, router);
// 패스포트 설정
var configPassport = require('./config/passport');
configPassport(app, passport);
// 패스포트 라우팅 설정
var userPassport = require('./routes/user_passport');
userPassport(router, passport);
//===== 404 에러 페이지 처리 =====//
var errorHandler = expressErrorHandler({
static: {
'404': './public/404.html'
}
});
app.use( expressErrorHandler.httpError(404) );
app.use( errorHandler );
//===== 서버 시작 =====//
//확인되지 않은 예외 처리 - 서버 프로세스 종료하지 않고 유지함
process.on('uncaughtException', function (err) {
console.log('uncaughtException 발생함 : ' + err);
console.log('서버 프로세스 종료하지 않고 유지함.');
console.log(err.stack);
});
// 프로세스 종료 시에 데이터베이스 연결 해제
process.on('SIGTERM', function () {
console.log("프로세스가 종료됩니다.");
app.close();
});
app.on('close', function () {
console.log("Express 서버 객체가 종료됩니다.");
if (database.db) {
database.db.close();
}
});
// 시작된 서버 객체를 리턴받도록 합니다.
var server = http.createServer(app).listen(process.env.PORT || app.get('port'), function(){
console.log('서버가 시작되었습니다. 포트 : ' + app.get('port'));
// 데이터베이스 초기화
database.init(app, config);
});
//===== Socket.IO를 이용한 채팅 테스트 부분 =====//
// 로그인 아이디 매핑 (로그인 ID -> 소켓 ID)
var login_ids = {};
// socket.io 서버를 시작합니다.
var io = socketio.listen(server);
console.log('socket.io 요청을 받아들일 준비가 되었습니다.');
// 클라이언트가 연결했을 때의 이벤트 처리
io.sockets.on('connection', function(socket) {
console.log('connection info :', socket.request.connection._peername);
// 소켓 객체에 클라이언트 Host, Port 정보 속성으로 추가
socket.remoteAddress = socket.request.connection._peername.address;
socket.remotePort = socket.request.connection._peername.port;
// 'login' 이벤트를 받았을 때의 처리
socket.on('login', function(login) {
console.log('login 이벤트를 받았습니다.');
console.dir(login);
// 기존 클라이언트 ID가 없으면 클라이언트 ID를 맵에 추가
console.log('접속한 소켓의 ID : ' + socket.id);
login_ids[login.id] = socket.id;
socket.login_id = login.id;
console.log('접속한 클라이언트 ID 갯수 : %d', Object.keys(login_ids).length);
// 응답 메시지 전송
sendResponse(socket, 'login', '200', '로그인되었습니다.');
});
// 'message' 이벤트를 받았을 때의 처리
socket.on('message', function(message) {
console.log('message 이벤트를 받았습니다.');
console.dir(message);
if (message.recepient == 'ALL') {
// 나를 포함한 모든 클라이언트에게 메시지 전달
console.dir('나를 포함한 모든 클라이언트에게 message 이벤트를 전송합니다.')
io.sockets.emit('message', message);
} else {
// command 속성으로 일대일 채팅과 그룹채팅 구분
if (message.command == 'chat') {
// 일대일 채팅 대상에게 메시지 전달
if (login_ids[message.recepient]) {
io.sockets.connected[login_ids[message.recepient]].emit('message', message);
// 응답 메시지 전송
sendResponse(socket, 'message', '200', '메시지를 전송했습니다.');
} else {
// 응답 메시지 전송
sendResponse(socket, 'login', '404', '상대방의 로그인 ID를 찾을 수 없습니다.');
}
} else if (message.command == 'groupchat') {
// 방에 들어있는 모든 사용자에게 메시지 전달
io.sockets.in(message.recepient).emit('message', message);
// 응답 메시지 전송
sendResponse(socket, 'message', '200', '방 [' + message.recepient + ']의 모든 사용자들에게 메시지를 전송했습니다.');
}
}
});
// 'room' 이벤트를 받았을 때의 처리
socket.on('room', function(room) {
console.log('room 이벤트를 받았습니다.');
console.dir(room);
if (room.command === 'create') {
if (io.sockets.adapter.rooms[room.roomId]) { // 방이 이미 만들어져 있는 경우
console.log('방이 이미 만들어져 있습니다.');
} else {
console.log('방을 새로 만듭니다.');
socket.join(room.roomId);
var curRoom = io.sockets.adapter.rooms[room.roomId];
curRoom.id = room.roomId;
curRoom.name = room.roomName;
curRoom.owner = room.roomOwner;
}
} else if (room.command === 'update') {
var curRoom = io.sockets.adapter.rooms[room.roomId];
curRoom.id = room.roomId;
curRoom.name = room.roomName;
curRoom.owner = room.roomOwner;
} else if (room.command === 'delete') {
socket.leave(room.roomId);
if (io.sockets.adapter.rooms[room.roomId]) { // 방이 만들어져 있는 경우
delete io.sockets.adapter.rooms[room.roomId];
} else { // 방이 만들어져 있지 않은 경우
console.log('방이 만들어져 있지 않습니다.');
}
} else if (room.command === 'join') { // 방에 입장하기 요청
socket.join(room.roomId);
// 응답 메시지 전송
sendResponse(socket, 'room', '200', '방에 입장했습니다.');
} else if (room.command === 'leave') { // 방 나가기 요청
socket.leave(room.roomId);
// 응답 메시지 전송
sendResponse(socket, 'room', '200', '방에서 나갔습니다.');
}
var roomList = getRoomList();
var output = {command:'list', rooms:roomList};
console.log('클라이언트로 보낼 데이터 : ' + JSON.stringify(output));
io.sockets.emit('room', output);
});
});
function getRoomList() {
console.dir(io.sockets.adapter.rooms);
var roomList = [];
Object.keys(io.sockets.adapter.rooms).forEach(function(roomId) { // for each room
console.log('current room id : ' + roomId);
var outRoom = io.sockets.adapter.rooms[roomId];
// find default room using all attributes
var foundDefault = false;
var index = 0;
Object.keys(outRoom.sockets).forEach(function(key) {
console.log('#' + index + ' : ' + key + ', ' + outRoom.sockets[key]);
if (roomId == key) { // default room
foundDefault = true;
console.log('this is default room.');
}
index++;
});
if (!foundDefault) {
roomList.push(outRoom);
}
});
console.log('[ROOM LIST]');
console.dir(roomList);
return roomList;
}
// 응답 메시지 전송 메소드
function sendResponse(socket, command, code, message) {
var statusObj = {command: command, code: code, message: message};
socket.emit('response', statusObj);
}
io.on('connection', function (socket) {
console.log('한명의 유저가 접속을 했습니다.');
socket.on('disconnect', function () {
console.log('한명의 유저가 접속해제를 했습니다.');
});
socket.on('send_msg', function (writer, msg) {
//콘솔로 출력을 한다.
console.log(msg);
//다시, 소켓을 통해 이벤트를 전송한다.
io.emit('send_msg', msg);
});
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
//// 포트 81 에서는 톰캣 서버가 대기하고 있다.
//// 스프링 컨트롤러에서 '/start' URI 에 매핑하는 메소드를 두었다.
//// 전달 방식은 json 형태로 하였다.
//
//var resData = '';
//var req = http.request(opts, function(res) {
//
// res.on('end', function() {
// console.log(resData);
// });
//});
//
//opts.headers['Content-Type'] = 'application/x-www-form-urlencoded';
//req.data = opts ;
//opts.headers['Content-Length'] = req.data.length;
//
//req.on('error', function(err) {
// console.log("에러 발생 : " + err.message);
//});
//
//
//app.use(bodyParser.urlencoded({ extended: false}));
//
//app.use(bodyParser.json());
//
//app.use(function (req,res,next) {
// //console.log("ㅊㅊㅊㅊ");
//
// res.writeHead('200',{'Content-Type':'text/html;charset=utf8'});
// res.end('<h1>sssss</h1>');
// console.log(req.body);
//
//});
//
//// 요청 전송
//req.write(JSON.stringify(req.data.body));
//
//req.end();
//
//http.createServer(app).listen(3000, function(){
// console.log('Server is running...');
//});