mychat 입장, 퇴장, 채팅
mychat.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Swan's Chat</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link
href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css"
rel="stylesheet" type="text/css">
<style type="text/css">
.discussion {
list-style: none;
background: #ededed;
margin: 0;
padding: 0 0 50px 0;
}
.discussion li {
padding: 0.5em;
overflow: hidden;
display: flex;
}
.discussion .avatar {
width: 40px;
position: relative;
}
.discussion .avatar img {
display: block;
width: 100%;
}
.other .avatar:after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 0;
height: 0;
border: 5px solid white;
border-left-color: transparent;
border-bottom-color: transparent;
}
.self {
justify-content: flex-end;
align-items: flex-end;
}
.self .messages {
order: 1;
border-bottom-right-radius: 0;
}
.self .avatar {
order: 2;
}
.self .avatar:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 0;
border: 5px solid white;
border-right-color: transparent;
border-top-color: transparent;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
}
.messages {
background: white;
padding: 10px;
border-radius: 2px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.messages p {
font-size: 0.8em;
margin: 0 0 0.2em 0;
}
.messages time {
font-size: 0.7em;
color: #ccc;
}
</style>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- socket.io참조------------------------------------------------- -->
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<!-- -------------------------------------------------------------- -->
<script type="text/javascript">
var socket;
var mynick; // 내 닉네임을 보관할 변수
$(function(){
socket=io.connect();
disableChat();//방에 입자하기 전에는 채팅을 비활성화
$('#btnRoomMake').click(function(){
//alert('a');
//방 이름 얻어오기
var roomName=$('#roomname').val();
//닉네임 얻어오기
var nickName=$('#nickname').val();
var bool = check(roomName,nickName);
if(bool){
//서버에 데이터를 보내기
//데이터를 json형태로 만들자
var str={
cmd:'create',
roomName: roomName,
nickName: nickName
};
socket.emit('room',str);
//room이벤트를 발생시켜 데이터를 보내자.
}
});
//#방 생성
socket.on('response',function(data){
console.dir(data);
showStatus("응답 데이터를 받았습니다: "+data.cmd+", "+data.code+", "+data.message);
var code=parseInt(data.code);
if(code==100){
//방을 만든 것
$('#btnRoomMake').prop('disabled',true);//방만들기 버튼 비활성화
}else if(code==300){
//방이 있는 것
alert(data.message)
$('#roomname').select();
}else if(code==500){
//클이 방을 퇴장했다면
disableChat();
$('#ulist').html('');
$('#taMsg').html('');
$('#btnRoomMake').prop('disabled',false);
$('#btnEnter').prop('disabled',false);
}
})//response end()
socket.on('room',function(data){
console.dir(data);
if(data.cmd=='ulist'){
//방에 참여한 유저 목록을 보내주었다면
var userCnt=data.users.length;
var str1="<p>입장한 User: "+userCnt+"명</p>";
str1+="<ul>";
for(var i=0;i<userCnt;i++){
var userNick=data.users[i];
str1+="<li>";
str1+=userNick;
str1+="</li>";
}
str1+="</ul>";
$('#ulist').html(str1);
}
})
socket.on('message',function(data){
var sender=data.sender;
var type=data.type;
var msg=data.msg;
var time=data.time;
/* if(type=='text'){
var str=sender+">>"+msg+' ['+time+']<br>';
$('#taMsg').append(str);
} */
if(sender!=mynick){
//다른 사람이 메시지를 보냈다면
var str="<p><label class='label label-danger'>"+sender+"</label>";
str+=" "+msg+"</p>";
addMessage('other',str,time);
}
})
//#방 입장하기
$('#btnEnter').click(function(){
//입장할 방이름, 닉네임 얻기
var roomName=$('#roomname').val();
//닉네임 얻어오기
var nickName=$('#nickname').val();
var bool = check(roomName,nickName);
if(bool){
enableChat();
mynick=nickName;
var str={
cmd:'enter',
roomName:roomName,
nickName:nickName
};
socket.emit('room',str);
$('#myinfo').html("MyInfo: #방이름: "+roomName+", Nick: "+nickName)
.addClass('text-primary');
$('#btnRoomMake').prop('disabled',true);
$('#btnEnter').prop('disabled',true);
}
})//방입장------------
//#3. 방 나가기 버튼 클릭시
$("#btnExit").click(function(){
var roomName=$('#roomname').val();
var nickName=$('#nickname').val();
var str={
cmd:'exit',
roomName:roomName,
nickName:nickName
};
socket.emit('room',str);
})
//#4. 방 삭제 버튼 클릭
//#5. 대화내용 입력후 엔터를 쳤을 때
$('#inputMsg').keydown(function(e){
if(e.keyCode==13){//엔터를 눌렀다면
//서버에 메시지 전송
var msg=$('#inputMsg').val();
var roomName=$('#roomname').val();
var nickName=$('#nickname').val();
var receiver='groupchat';
var str={
roomName:roomName, //방이름
sender:nickName, //송신자 닉네임
receiver:receiver, //수신자=>groupChat(전체), sendone(귓속말)
type:'text', //데이터 유형 (text,icon)
msg:msg //전송 메시지
}
/*서버에 'message'이벤트를 발생시켜 보내기*/
socket.emit('message',str);
$('#inputMsg').val('');
//내가 쓴 메시지를 스타일 줘서 오른쪽에 출력하기
var time=getTime();
var mymsg="<label class='label label-primary'>"+str.sender+"</label>";
mymsg+=" "+msg;
addMessage('self' ,mymsg,time);
}
})//대화메시지 전송
})//$()end ---
var getTime = function(){
//년-월-일 시-분-초
var mdate=new Date();
var str=mdate.getFullYear()+"-"+(mdate.getMonth()+1)+"-"+mdate.getDate();
str+=" "+mdate.getHours()+":"+mdate.getMinutes()+":"+mdate.getSeconds();
return str;
}
var addMessage=function(writer,msg,time){
var img='<img src="images/me.png">';
if(writer==="other"){
img='<img src="images/others.png">'
}
var str="<li class='"+writer+"'>";
str+="<div class='avatar'>";
str+=img;
str+="</div>";
str+="<div class='message'>";
str+="<p>"+msg+"</p>";
str+="<time>"+time+"</time>";
str+="</div>";
str+="</li>";
$('#taMsg').append(str);
}
function showStatus(str){
$('#status').html(str)
.css('color','tomato')
.css('font-weight','bold');
}
//채팅 비활성화 => 방 퇴장시
function disableChat(){
$('#inputMsg').attr('readonly',true);
$('#taMsg').attr('readonly',true);
}
//채팅 활성화 => 방 입장시
function enableChat(){
$('#inputMsg').attr('readonly',false);
$('#taMsg').attr('readonly',false);
}
//유효성 체크하는 함수
function check(roomName, nickName){
if(!roomName){
alert("방 이름을 입력하세요");
$('#roomname').focus();
return false;
}
if(!nickName){
alert("닉네임을 입력하세요");
$('#nickname').focus();
return false;
}
return true;
}
</script>
</head>
<body>
<div class="container">
<div class="section">
<div class="row">
<div class="col-md-12">
<h1 class="text-center text-primary">
<a><i class="fa fa-fw fa-heart-o fa-lg hub"></i></a>Swan's
Chatting<a><i class="fa fa-fw fa-heart-o fa-lg hub"></i></a>
</h1>
<div class="panel-group" style="margin-top: 30px;">
<div class="panel panel-danger col-md-7" id="roommake"
style="height: 250px;">
<div class="panel-heading">
<a style="color: #d9534f;"><i
class="fa fa-2x fa-fw hub fa-home"></i></a>방만들기
</div>
<div class="panel-body">
<div class="row">
<label class="col-md-3" for="roomname">방이름 :</label>
<div class="col-md-9">
<input id="roomname" type="text" class="form-control"
placeholder="방이름">
</div>
</div>
<div class="row" style="margin-top: 8px; margin-bottom: 10px">
<label class="col-md-3" for="nickname">닉네임 :</label>
<div class="col-md-9">
<input id="nickname" type="text" class="form-control"
placeholder="닉네임">
</div>
</div>
<div class="row">
<div class="col-md-12 text-right">
<input id="btnRoomMake" type="button" value="방만들기"
class="btn btn-primary">
<button class="btn btn-warning" id="btnRename">방이름 변경</button>
<button class="btn btn-danger" id="btnRemove">방 삭제</button>
<button class="btn btn-info" id="btnEnter">방에 입장</button>
<button class="btn btn-success" id="btnExit">방나가기</button>
</div>
</div>
</div>
</div>
<div class="panel panel-warning col-md-4" id="room"
style="height: 250px; overflow: auto; margin-left: 10px">
<div class="panel-heading">
<a style="color: #d9534f;"><i class="fa fa-2x fa-fw fa-list"></i></a>개설된
방목록
</div>
<div class="panel-body">
<div id="roomlist">
<!-- <ol >
<li>One</li>
<li>Two</li>
<li>Three</li>
</ol> -->
</div>
</div>
</div>
<div class="panel panel-info col-md-11" id="chatroom"
style="margin-top: 13px">
<div class="panel-heading">
<a><i class="fa fa-3x fa-fw fa-comments-o"></i></a>:::Chat:::
<div id="myinfo"></div>
<div id="status"></div>
</div>
<div class="panel-body">
<div id="chatmsg" class="col-md-10 col-md-offset-1">
<div class="row">
<label class="col-md-3 text-right" for="nickname">메시지
:</label>
<div class="col-md-9">
<input id="inputMsg" type="text" class="form-control"
placeholder="메시지를 입력하세요">
</div>
</div>
<div class="row" style="margin-top: 10px">
<div class="col-md-3" id="ulist">
</div>
<div class="col-md-9">
<div id="taMsg"
class="discussion" style="width:100%;height:400px;overflow: auto" readonly class="form-control"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
mychat.js
var http=require('http')
, fs=require('fs')
, path=require('path')
, socketio=require('socket.io')
, static = require('serve-static')
, express = require('express');
var app = express();
//미들웨어
app.use('/',static(path.join(__dirname,'../public')));
app.get('/',function(req,res){
fs.readFile('./public/mychat.html','utf8',function(err,data){
if(err) throw err;
res.send(data);
});
})
//웹서버 생성 후 가동
var server = http.createServer(app).listen(3333,function(){
console.log('http://localhost:3333');
})
var io = socketio.listen(server);
var users= [];
io.sockets.on('connection',function(socket){
console.log("클이 접속함...");
socket.on('room',function(data){
//console.dir(data);
if(data.cmd=='create'){//방만들기라면
console.log('socket.id== '+socket.id);
console.dir(io.sockets.adapter.rooms);
var isExist=io.sockets.adapter.rooms[data.roomName];
if(isExist){
//생성한 방이 이미 존재하는 경우
sendResponse(socket,'room',300,data.roomName+"은 이미 존재하는 방입니다.");
}else{
//새로 만드는 방인 경우
//socket.join('방이름') ==> 방생성
socket.join(data.roomName);
users.push({
roomName:data.roomName,
bangjang:data.nickName,
ulist:[] //방에 입장한 사람들 목록
})
//console.log('create users[0].ulist: '+users[0].ulist)
sendResponse(socket,'room','100',
'['+data.roomName+'] 방이 생성 됐어요 방장: ['+data.nickName+']');
}
}//create------
else if(data.cmd=='enter'){
console.dir(data);
socket.join(data.roomName);
//방금 입장한 사람의 방 이름과 기존에 입장한 사람의 방이름이 같으면 해당 방의 참여자로 join
for(var i=0;i<users.length;i++){
var u =users[i];
console.log('u.roomName'+u.roomName);
if(u.roomName==data.roomName){
u.ulist.push(data.nickName);
//u.ulist==>배열, 해당 방에 입장한 유저들의 닉네임을 보관하는 배열
}
console.dir(u.ulist);
}
//해당 방에 입장한 유저 목록을 가져와서 해당 방의 참여자들에게 전송하기
var userList=getUserList(data.roomName);
var str={
cmd:'ulist',
users:userList,
};
//roomName에 속한 사람들에게만 이벤트를 발생시킴
io.sockets.in(data.roomName).emit('room',str);
sendResponse(socket,'room',200,'#'+data.nickName+"님이 입장#");
}//eneter-------
else if(data.cmd=='exit'){
console.log(123);
//방 퇴장시--
//users안에 ulist(방에 참여한 닉네임 보관)에서 퇴장하는 사람의 닉네임과
//같은 사람이 있는지 검색해서 있다면 삭제 처리
for(var i=0;i<users.length;i++){
var u=users[i];
if(u.roomName==data.roomName){
var uarr=u.ulist;
for(var j=0;j<uarr.length;j++){
if(uarr[j]==data.nickName){
//ulist에서 삭제 처리
u.ulist.splice(j,1);
break;
}
}
}
console.log('after exit ulist>>>');
console.dir(u.ulist);
}
var userList =getUserList(data.roomName);
var str={
cmd:'ulist',
roomName:data.roomName,
users:userList
};
io.sockets.in(data.roomName).emit('room',str);
//퇴장한 사람의 응답 보내기
var msg = data.nickName+"님이"+data.roomName+"에서 나갔습니다.";
sendResponse(socket,'room',500,msg);
//소켓에서 퇴장 처리
//1)방생성, 입장 ==>socket.join(방이름)
//2)방에서 퇴장 ==> socket.leave(방이름)
socket.leave(data.roomName);
}//exit--
})//.on('room') end -------------
//클로부터 메시지가 올 경우
socket.on('message',function(data){
console.dir(data);
if(data.receiver=='groupchat'){
//수신자가 'groupchat'이라면 방 안에 있는 모든 클에게 메시지를 전송
// io.socket.in('방이름').emit('message',데이터)
var str={
sender:data.sender,
type:data.type,
msg:data.msg,
time:getTime()
}
/////////////////////////////////
io.sockets.in(data.roomName).emit('message',str);
/////////////////////////////////
sendResponse(socket,"message",400,'방['+data.roomName+']의 모든 클에게 메시지를 전송');
}
})
})//.on('connection') end-----------
var getTime = function(){
//년-월-일 시-분-초
var mdate=new Date();
var str=mdate.getFullYear()+"-"+(mdate.getMonth()+1)+"-"+mdate.getDate();
str+=" "+mdate.getHours()+":"+mdate.getMinutes()+":"+mdate.getSeconds();
return str;
}
//클에게 응답을 전송하는 함수
var sendResponse = function(socket, command, code, msg){
//클에게 보낼 응답 데이터 만들기
var str={cmd:command,code:code,message:msg};
socket.emit('response',str); //클에게 응답 데이터 전송
}//sendResponse()--------------
var getUserList = function(roomName){
for(var i=0 ;i< users.length;i++){
var u =users[i];
if(u.roomName==roomName){
return u.ulist;
}
}
}//getUserList()-------------
'개발자 > 국비지원 SW' 카테고리의 다른 글
국비지원 96일차 - 온라인강의 환경설정, Vue.JS, MVVM패턴, Vue객체 (0) | 2020.09.09 |
---|---|
국비지원 95일차 - Spring Mapping, 변수 객체로 받기, Component, 동적 MyBatis (0) | 2020.08.28 |
국비지원 93일차 - Spring MVC 요청 처리 과정 (0) | 2020.08.26 |
국비지원 92일차 - NodeJS socket기능, mychat 방생성 (0) | 2020.08.25 |
국비지원 91일차 - Spring 흐름도, shop만들기 환경설정, POJO객체, Controller에 Service 생성하고 주입 MyBatis 작동 확인 (0) | 2020.08.24 |