Node.js 채팅 기본코드를 좀 더 수정 보완하고 Web 채팅과 안드로이드 채팅이 동시에 되는 걸 확인했다.
Node.js 설치 및 Express, socket.io 설치에 대한 사항은 이전 게시글을 참조하면 된다.
서버 chat.js
const express = require('express'), http = require('http'), app = express(), server = http.createServer(app), io = require('socket.io').listen(server);
app.get('/', (req, res) => { res.sendFile(__dirname+'/index.html'); });
var numUsers=0; var usernames=[]; io.on('connection', (socket) => { var addedUser = false; socket.on('join', function (username) { if (addedUser) return; socket.username = username; ++numUsers; addedUser = true; usernames.push(socket.username); console.log(socket.username + "님이 접속하셨습니다."); console.log('접속한 사용자수 : '+numUsers+'명'); socket.broadcast.emit('userjoinedthechat', socket.username + "님이 접속하셨습니다."); updateUsernames(); });
function updateUsernames(){ io.sockets.emit('usernames', usernames); }
socket.on('messagedetection', (senderNickname, messageContent) => { // 서버 콘솔상에 메시지 보여주기 console.log(senderNickname + " :" + messageContent); //message object 생성 let message = {"message": messageContent, "senderNickname": senderNickname} // 클라이언트(Web, Android)로 메시지 전송 io.emit('message', message); // 나를 포함한 모든 클라이언트에게 전송 });
socket.on('disconnect', function () { if (addedUser) { --numUsers; usernames.splice(usernames.indexOf(socket.username), 1); } console.log(socket.username+"님이 퇴장했습니다"); console.log('접속한 사용자수 : '+numUsers+'명'); socket.broadcast.emit("userdisconnect", socket.username + "님이 퇴장했습니다"); // 나를 제외한 모든 클라이언트에게 전송 updateUsernames(); });
});
server.listen(3000, () => { console.log('Node chat app is running on port 3000'); }); |
Web Chatting UI
- css 파일을 별도 분리하여 인식시켰더니 감지를 못하더라. 그래서 같은 파일에 추가했다.
- 채팅 메시지가 많으면 자동으로 가장 하단의 메시지 내용이 보이도록 처리
- 줄바꿈 처리 기능 코드 추가 (스마트폰에서는 엔터키 입력 안되게 처리 코드 추가)
- Web 채팅과 Android 채팅 동시에 가능
- 반응형 화면으로 스마트폰과 PC에서 보이는 화면이 다르게 처리 (커스터마이징 필요)
<!DOCTYPE html> <html> <head> <title>Web Chat Messenger</title> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" type="text/css" rel="stylesheet"> <style type="text/css"> .container{max-width:1170px; margin:auto;} img{ max-width:100%;}
.messaging { padding: 0 0 50px 0;}
.inbox_msg { border: 1px solid #c4c4c4; clear: both; overflow: hidden; } .inbox_people { background: #f8f8f8 none repeat scroll 0 0; float: left; overflow: hidden; width: 35%; border-right:1px solid #c4c4c4; } .top_spac{ margin: 20px 0 0;}
.headind_srch{ padding:10px 29px 10px 20px; overflow:hidden; border-bottom:1px solid #c4c4c4;} .recent_heading {float: left; width:100%;} .recent_heading h4 { color: #05728f; font-size: 21px; margin: auto; }
.inbox_chat { height: 550px; overflow-y: scroll;}
.mesgs { float: left; padding: 20px 5px 5px 10px; width: 65%; } .msg_history { height: 500px; overflow-y: auto; background: #FFFFFF; }
.incoming_msg_img { display: inline-block; width: 6%; } .received_msg { display: inline-block; padding: 0 0 0 10px; vertical-align: top; width: 92%; } .received_withd_msg { width: 77%;} .received_withd_msg p { background: #F3E2A9 none repeat scroll 0 0; border-radius: 3px; color: #646464; font-size: 14px; margin: 0; padding: 5px 10px 5px 12px; width: 100%; } .time_date { color: #747474; display: block; font-size: 12px; margin: 8px 0 0; }
.type_msg {border-top: 1px solid #c4c4c4;position: relative;} .sent_msg { float: right; width: 76%; } .sent_msg p { background: #05728f none repeat scroll 0 0; border-radius: 3px; font-size: 14px; margin: 0; color:#fff; padding: 5px 10px 5px 12px; width:100%; } .outgoing_msg{ overflow:hidden; margin:26px 0 26px;} .input_msg_write input { background: rgba(0, 0, 0, 0) none repeat scroll 0 0; border: medium none; color: #4c4c4c; font-size: 15px; min-height: 48px; width: 100%; }
.msg_send_btn { background: #05728f none repeat scroll 0 0; border: medium none; border-radius: 50%; color: #fff; cursor: pointer; font-size: 17px; height: 33px; position: absolute; right: 0; top: 11px; width: 33px; }
@media screen and (max-width: 800px) { .inbox_msg { display: block; width: 100%; } .inbox_people {width: 100%;} .inbox_chat { width: 100%;height: 250px;}
.mesgs { display: block; width: 100%; padding: 20px 0px 10px 0px; } .msg_history {width: 100%;height: 450px;} .type_msg {width: 100%;}
}
</style> </head>
<body> <div class="container"> <!--Form to enter UserName--> <div class="row" id="nickWrap"> <div class="col-xs-9"> <form id="setNick"> <input id="username" class="form-control" placeholder="사용자명을 입력하세요"/> <input type="submit" class="btn btn-primary"> </form> </div> </div> <!--end username--> <div class="messaging" id="contentWrap"> <h3 class=" text-center" id="msg_leave">Messaging</h3> <div class="inbox_msg"> <div class="inbox_people"> <div class="headind_srch"> <div class="recent_heading"> <h4>접속 사용자 현황</h4> </div> </div>
<div class="inbox_chat"> <div class="panel panel-default"> <div class="panel-body" id="users"></div> </div> </div> </div>
<div class="mesgs"> <div class="msg_history" id="chat"> </div>
<div class="type_msg"> <form id="send-message"> <div class="input_msg_write"> <textarea rows="3" id="message" class="form-control" placeholder="메시지를 입력하세요" /></textarea> <button class="msg_send_btn" type="button"><i class="fa fa-paper-plane-o" aria-hidden="true"></i></button> </div> </form> </div> </div> </div>
<!--node.js and Jquery code--> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js"></script> <script> $(function () { var socket = io(); var myname; var i; var filter = "win16|win32|win64|mac|macintel";
$('#contentWrap').hide();
$('#setNick').submit(function () { myname = $('#username').val(); if(myname.length == 0) { alert('이름을 입력하세요'); return false; } socket.emit('join', myname); $('#nickWrap').hide(); $('#contentWrap').show(); return false; });
//List of users socket.on('usernames', function (message) { var html = ''; for (i = 0; i < message.length; i++) { html += message[i] + '<br/>' } $('#users').html(html); });
$('.msg_send_btn').click(function (e) { e.preventDefault(); msg_send(); });
$('#message').keypress(function (e) { if ( navigator.platform ) { // 모바일 접속이면 엔터키를 동작 안되게 처리 if(filter.indexOf( navigator.platform.toLowerCase() ) > 0){ if (e.which == 13 && !e.shiftKey) { // Shift + Enter키이면 줄바꿈처리 가능 msg_send(); return false; } } } });
function msg_send(){ if($('#message').val().length ==0){ alert('메시지가 입력되지 않았습니다'); $('#message').focus(); return false; } socket.emit('messagedetection', myname, $('#message').val()); $('#message').val(''); // 메시지를 전송하고 메시지 전송 창 내용을 비운다. }
socket.on('message', function (msg) { msg.message = msg.message.replace(/(?:\r\n|\r|\n)/g, '<br />'); // 줄바꿈 처리 if(myname == msg.senderNickname){ // 내가 전송한 메시지 $('#chat').append('<div class="outgoing_msg"><div class="sent_msg"><p> '+ msg.message +'</p><span class="time_date">'+new Date().toLocaleString()+'</span></div></div>'); } else { // 상대방이 보낸 메시지 $('#chat').append('<div class="incoming_msg"><div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div><div class="received_msg"><div class="received_withd_msg"><p>'+ msg.message +'</p><span class="time_date">'+msg.senderNickname+', '+new Date().toLocaleString()+'</span></div></div></div>'); } $("#chat").scrollTop($("#chat")[0].scrollHeight); // 최근 메시지 출력된 내용이 보이게 처리 });
socket.on('userjoinedthechat', function (msg) { $('#chat').append('<div class="incoming_msg"><div class="incoming_msg_img"></div><div class="received_msg"><div class="received_withd_msg"><p>'+ msg +'</p><span class="time_date">'+new Date().toLocaleString()+'</span></div></div></div>'); $("#chat").scrollTop($("#chat")[0].scrollHeight); // 최근 메시지 출력된 내용이 보이게 처리 }); socket.on('userdisconnect', function (msg) { $('#chat').append('<div class="incoming_msg"><div class="incoming_msg_img"></div><div class="received_msg"><div class="received_withd_msg"><p>'+ msg +'</p><span class="time_date">'+new Date().toLocaleString()+'</span></div></div></div>'); $("#chat").scrollTop($("#chat")[0].scrollHeight); // 최근 메시지 출력된 내용이 보이게 처리 });
}); </script> </body> </html>
|
채팅 UI는 bootstrap 코드를 검색해서 원하는 코드로 변경하면 모바일 Web에서도 깔끔하게 보이게 처리할 수 있을 것이다.