github.com/jokj624/CustomEmojiChatting
프로토타입 채팅 전체 코드는 위 깃헙 저장소에 있습니다.
블로그 스킨을 오랜만에 바꾼김에 쓰자쓰자 해놓고 맨날 미룬 채팅 구현방법 포스팅을 작성하려합니다.
연구실에서 진행한 프로토타입인데 이 중에 1대 1 채팅을 구현하는 방법만 빼서 소개해보려 합니다.
1편은 텍스트 채팅에 대해서만 설명해보고, 2편에서 이모티콘(나는 특정 목적 때문에 이모티콘이었고, 사실 그냥 이미지 전송이다) 이미지를 Multer-s3 , AWS S3를 이용해 전송해보는 법을 설명해보려합니다.
** 저도 하나하나 구글링해가고, 책을 통해 찾아가며 구현한 거라 정확하지 않거나 비효율적일 수도 있습니다. 다 같이 공부해나가는 학생이니까 이해 부탁 dream
1. 최종 구현 화면 (텍스트 채팅)
짜잔 진짜 카톡 같죠? 아님 말구요.
아무튼 이런식으로 두개의 브라우져에서 실시간으로 채팅이 가능합니다.
이걸 잘 활용하신다면 후에 다른 웹에 채팅을 추가하거나 쪽지 대화 이런 기능을 추가할 수 있을 듯 합니다.
2. Dependencies
"dependencies": {
"aws-sdk": "^2.834.0",
"express": "^4.17.1",
"multer": "^1.4.2",
"multer-s3": "^2.9.0",
"ngrok": "^3.4.0",
"socket.io": "^3.0.5"
}
이 중에서 텍스트 채팅만 사용하신다면 express + socket.io 만 있으면 됩니다!
설치 법은
npm install --save express
npm install --save socket.io
3. Node js + Express 로 서버 생성 + Socket.io로 웹 소켓 사용
Project__ package.json
|__ node_modules
|__ server.js
|__ public ___ index.html
|___ customemoji.js (채팅 js)
|___ customemoji.css
구조를 이런식으로 잡았습니다.
server.js 코드를 봅시다.
const express = require('express');
const app = express();
app.set('port', process.env.PORT || 4000);
express 모듈을 실행해 app 변수에 할당해줍시다.
서버가 실행될 포트를 4000으로 설정합니다.
app.use(express.static(__dirname + '/public'));
static 미들웨어는 정적 파일들을 제공하는 라우터 역할을 합니다. 따라서 우리가 만든 public 폴더 내부에 정적인 파일 (js,html,css,image 등) 을 두고 express 객체 안에서 static을 꺼내쓰면 됩니다.
책에 따르면
public/css/style.css는 http://localhost:3000/css/style.css 로 접근한다고 합니다.
실제 요청 주소에는 public이 없는데 이는 보안상의 이유라고 합니다. 외부인이 쉽게 구조를 파악할 수 없게 하기 위해서래요.
const socket = require('socket.io');
const http = require('http');
const server = http.createServer(app);
const io = socket(server);
server.listen(4000, function() {
console.log('Server On !');
});
실시간 통신을 위해서는 웹 소켓을 사용해야합니다. 편리하게 사용 할 수 있는 Socket.io를 사용합시다.
io 객체를 통해 다양한 소켓 이벤트를 구현할 수 있습니다.
let socketList = [];
io.on('connection', function(socket) {
socketList.push(socket);
console.log('User Join');
socket.on('SEND', function(msg) {
socketList.forEach(function(item, i) {
console.log(item.id);
if (item != socket) {
item.emit('SEND', msg);
}
});
});
...
}
connection 은 클라이언트가 접속했을 때 발생하는 이벤트 리스너 입니다.
콜백함수에는 socket 객체를 사용할 수 있습니다.
socketList 배열은 단체 채팅일 때 사용자를 구분하기 위해 필요한데 사실 지금은 일대일 채팅이라 무의미합니다.
단체 채팅일 경우 socketList 에 socket을 넣어 후에 구분이 가능합니다.
브라우저가 열릴 때마다 (사용자가 들어올 때 마다) 콘솔에 User join이 찍힙니다.
socket.on('SEND', function(msg) {
socketList.forEach(function(item, i) {
console.log(item.id);
if (item != socket) {
item.emit('SEND', msg);
}
});
});
SEND 이벤트를 보면 자신이 메세지를 송신할 시 자신을 제외한 다른 모두에게 emit 메서드로 메시지를 보내게 됩니다.
socket.on('disconnect', function() {
socketList.splice(socketList.indexOf(socket), 1);
});
연결이 종료되면 socketList에서 없애줍니다.
전체코드 (이미지는 다음편에)
const express = require('express');
const socket = require('socket.io');
const upload = require('./multer');
const app = express();
app.set('port', process.env.PORT || 4000);
const http = require('http');
const server = http.createServer(app);
const io = socket(server);
let socketList = [];
app.use(express.static(__dirname + '/public'));
server.listen(4000, function() {
console.log('Server On !');
});
io.on('connection', function(socket) {
socketList.push(socket);
console.log('User Join');
socket.on('SEND', function(msg) {
socketList.forEach(function(item, i) {
console.log(item.id);
if (item != socket) {
item.emit('SEND', msg);
}
});
});
...중략
socket.on('disconnect', function() {
socketList.splice(socketList.indexOf(socket), 1);
});
}
4. html + js
채팅화면은 어느정도 알아서 구현하실 거라 생각하기에 자바 스크립트 위주로 설명할게요.
<form id = "chatform" onsubmit="return false">
<div style="display: inline-block;">
<input type="text" id="input_box" contenteditable="true" autocomplete="off">
</div>
<input type = "submit" id="sendmsg" class="btn btn-warning btn-sm" value="Send">
... 중략
</form>
html 은 이런식의 form 구조를 가지고 있습니다.
var msgText = $('#input_box');
if (msgText.val() == '') {
return;
} else {
socket.emit('SEND', msgText.val());
var msgLine = $('<div class="msgLine">');
var msgBox = $('<div class="me">');
msgBox.append(msgText.val());
msgBox.css('display', 'inline-block');
msgLine.css('text-align', 'right');
msgLine.append(msgBox);
$('#msg').append(msgLine);
msgText.val('');
chatView.scrollTop = chatView.scrollHeight;
}
});
form을 제출할 시 입력한 글자를 input_box에서 가지고 와서 socket.emit을 통해 보내주면 됩니다.
이미 server.js에서 이벤트를 구현해놨기 때문에 바로 호출해주시면 됩니다.
밑에는 제 화면에서 제가 송신한 텍스트를 오른쪽에 예쁘게 보여주기 위해 사용한 코드입니다.
socket.on('SEND', function(msg) {
var msgLine = $('<div class="msgLine">');
var msgBox = $('<div class="msgBox">');
msgBox.append(msg);
msgBox.css('display', 'inline-block');
msgLine.append(msgBox);
$('#msg').append(msgLine);
}
SEND 이벤트로 수신 시에는 마찬가지로 왼쪽에 보여주게끔 했습니다.
전체 코드
chatForm.addEventListener('submit', function() {
var msgText = $('#input_box');
if (msgText.val() == '') {
return;
} else {
socket.emit('SEND', msgText.val());
var msgLine = $('<div class="msgLine">');
var msgBox = $('<div class="me">');
msgBox.append(msgText.val());
msgBox.css('display', 'inline-block');
msgLine.css('text-align', 'right');
msgLine.append(msgBox);
$('#msg').append(msgLine);
msgText.val('');
chatView.scrollTop = chatView.scrollHeight;
}
});
socket.on('SEND', function(msg) {
var msgLine = $('<div class="msgLine">');
var msgBox = $('<div class="msgBox">');
msgBox.append(msg);
msgBox.css('display', 'inline-block');
msgLine.append(msgBox);
$('#msg').append(msgLine);
chatView.scrollTop = chatView.scrollHeight;
});
5. 마무리
이렇게 까지만 하셔도 실시간 텍스트 채팅이 가능합니다!!
저도 오랜만에 다시 열어보니 참 코드를 비효율적으로 작성한 것 같아 반성하게 되네요.
이때는 사실 오랜만에 자바스크립트 만져서 es6문법도 잘 몰랐거든요 var만 주구장창 쓴거 보이시죠. 이러지 마세요.
(지금은 그래도 es6문법에 어느정도 적응했답니다)
지금 짜라하면 이렇게 안짜지~
이 글을 보신다면 꼭 붙여넣기 하지 마시고 더 좋은 코드로 다듬어 보세요!
저도.. 졸업 작품 끝나고 채팅 코드를 더 수정해봐야겠어요.
'DEV > Node.js' 카테고리의 다른 글
[CI/CD] AWS CodeDeploy, CodePipeline 으로 node.js, ec2, git 배포 자동화하기 (4) | 2021.12.16 |
---|---|
[Node.js] Express, TypeScript, MongoDB 회원가입 (1) (3) | 2021.06.18 |
Node.js , express, mongoDB, typescript 초기 설정 (0) | 2021.05.26 |
Node.js + Koa + Typescript 로 슬랙 봇 개발해보기 (1) (0) | 2021.04.19 |
React, Mongoose(MongoDB), Node js 게시판 검색 구현 (2) | 2021.03.13 |