그누보드5에 실시간 채팅 구축하기
컨텐츠 정보
- 42,035 조회
- 13 댓글
- 2 추천
- 목록
본문
현재 제 홈페이지에 있는 실시간 채팅 기능 적용방법을 알려드리겠습니다.
원래 기능이 더 업그레이드되면 올리려고 했는데, 언제 업그레이드가 될지 몰라 먼저 올립니다. ㅎㅎ
업그레이드 되어도 같은 방식으로 구축하면 되니 괜찮을 것 같습니다.
아시겠지만 웹서버에 nodejs가 설치되고, node 명령어를 내릴 수 있어야됩니다.
일반적인 웹호스팅 환경에서는 불가능합니다.
채팅 소스 : https://sir.kr/g5_plugin/7029
와칸다포에버님의 소스를 조윤진님이 수정한 버전입니다.
사용자 채팅 차단 기능이 있어 전체 채팅에 충분히 쓸만합니다.
저는 도커를 이용하고 있는데, 방화벽만 오픈되어 있다면 어디서든 가능할 것 같습니다.
그리고 HTTPS 환경에서 구축하는 방법도 포함되어 있습니다.
마지막으로 현재 제가 사용 중인 도커의 셋팅까지 알려드립니다.
설치방법
1. 채팅 소스를 받고 chat 폴더를 그대로 그누보드 루트에 복사합니다.
2. node 폴더를 그누보드가 아닌 다른 폴더에 복사합니다.
예를들어 그누보드가 /var/www/gnuboard 에 있다면, /var/www/node 이런 식으로 넣으면 됩니다.
데이터베이스 생성하기
phpmyadmin에서 생성하는 것이 제일 편합니다.
phpmyadmin에 로그인 후 자신의 DB를 클릭하고, SQL 탭으로 들어갑니다.
create table `g5_livechat` (
`lc_id` int not null auto_increment primary key,
`lc_mb_id` varchar(1024) not null,
`lc_msg` text not null,
`lc_date` datetime not null
)default charset=utf8 engine=MyISAM;
create table `g5_livechat_banlist` (
`lb_id` int not null auto_increment primary key,
`lb_mb_id` varchar(1024) not null unique key,
`lb_reason` text not null
)default charset=utf8 engine=MyISAM;
위 명령어를 각각 내려주면 됩니다.
그누보드를 설치할 때 DB 테이블 접두사를 g5가 아닌 다른 것으로 선택했다면 적절하게 수정해주세요.
charset은 utf8mb4로 바꿔도 되는데, 이모지는 어짜피 출력이 안되므로 utf8로 둬도 됩니다.
참고로 이모지 입력시 전체 새로고침됩니다. ^^;;
engine 부분은 InnoDB로 변경해도 됩니다.
DB 내용 입력하기
/node/config.js 파일을 열어서 자신의 DB 내용을 입력합니다.
로컬에 mysql을 설치했을 경우
this.host는 127.0.0.1 그대로 두면 됩니다.
this.port는 3306 그대로 두면 됩니다.
this.user는 DB의 유저 이름을 넣으면 됩니다.
this.password는 DB의 비밀번호를 넣으면 됩니다.
this.dbname는 DB 이름을 넣으면 됩니다.
this.port는 nodejs 채팅 프로그램의 포트를 결정하는 것입니다. chat 폴더에 있는 내용과 맞추면 되므로 아무 포트나 넣으면 됩니다.
다만 외부에서 접속할 수 있는 포트를 선택해야 합니다.
반드시 방화벽을 열어야 합니다.
이 글에서는 기본인 1121포트로 하겠습니다.
mysql을 도커에 설치했을 경우
this.host는 mysql 컨테이너 이름을 넣으면 됩니다.
this.port는 ''로 비워두면 됩니다.
this.user는 DB의 유저 이름을 넣으면 됩니다.
this.password는 DB의 비밀번호를 넣으면 됩니다.
this.dbname는 DB 이름을 넣으면 됩니다.
this.port는 nodejs 채팅 프로그램의 포트를 결정하는 것입니다. chat 폴더에 있는 내용과 맞추면 되므로 아무 포트나 넣으면 됩니다.
다만 외부에서 접속할 수 있는 포트를 선택해야 합니다.
반드시 방화벽을 열어야 합니다.
그리고 도커에서도 포트를 열어줘야됩니다.
이 글에서는 기본인 1121포트로 하겠습니다.
수정방법
HTTPS를 기준으로 할 것이므로 node폴더에 있는 파일들을 먼저 정할 것입니다.
/node/server.js 파일에서 5번째에서 13번째 줄이
const app = require('express');
const http = require('http').createServer(app);
const io = require('socket.io')(http);
const mysql = require('mysql').createConnection({
host:cfg.db.host,
port:cfg.db.port,
user:cfg.db.user,
password:cfg.db.password,
database:cfg.db.dbname
위와 같이 되어 있는데
var fs = require('fs');
var privateKey = fs.readFileSync('/etc/letsencrypt/live/yourdomain/privkey.pem')
var certificate = fs.readFileSync('/etc/letsencrypt/live/yourdomain/fullchain.pem');
var credentials = {key: privateKey, cert: certificate};
const app = require('express');
const https = require('https').createServer(credentials,app);
const io = require('socket.io')(https);
const mysql = require('mysql').createConnection({
host:cfg.db.host,
port:cfg.db.port,
user:cfg.db.user,
password:cfg.db.password,
database:cfg.db.dbname
});
위와 같이 수정합니다.
/etc/letsencrypt/live/yourdomain/ 경로는 반드시 자신의 SSL 인증서가 있는 폴더를 지정해야 합니다.
상대경로도 되고, 절대경로도 됩니다.
/그누보드루트/chat/js/common.js 제일 첫번째 줄을
var socket = io.connect('wss://'+location.hostname+':1121/index.acnh?mb_id='+mb_id);
위와 같이 ws를 wss로 바꾸면 됩니다.
아까 위에서 this.port를 다른 포트로 바꿨다면 1121를 다른 숫자로 바꾸면 됩니다.
CSS 수정하기
css를 적절하게 수정하였습니다.
/그누보드루트/chat/css/common.css 파일을 열어서
html {overflow-y:auto}
html, body {height:100%}
ul li{list-style:none;}
.send_button{width:40px;height:40px;line-height:38px;text-align:center;border-radius:999px;display:inline-block;font-size:17px;position:relative;bottom:14px;right:-6px;}
.send_button:hover{color:#323c46;}
.user_tag{color:#a300ff;}
.wrap_chat {height:100%}
.wrap_chat .cont_chat{margin-bottom:15px;}
.wrap_chat .header {background-color:#323c46;position:fixed;top:0;left:0;z-index:10;width:100%}
.wrap_chat .header>.title_area {display:flex;align-items:center;justify-content:center;min-height:50px;font-size:14px;font-weight:bold;color:#fff}
.wrap_chat .cont_chat {overflow-y:auto;overflow-x:hidden;position:absolute;left:0;bottom:53px;width:100%;top:50px;padding-bottom:10px}
.wrap_chat .cont_chat>ul {padding:8px 15px 8px;}
.wrap_chat .cont_chat>ul>li {padding:8px 0;}
.wrap_chat .cont_chat>ul>li.notice {color:#959595;text-align:center}
.wrap_chat .cont_chat>ul>li>.inner_talk {display:block;float:left;clear:both;margin-bottom:15px;}
.wrap_chat .cont_chat>ul>li>.inner_talk>.user_thumb {display:inline-block}
.wrap_chat .cont_chat>ul>li>.inner_talk>.user_thumb>a {overflow:hidden;position:relative;width:40px;height:40px;border-radius:50%;display:block;margin-bottom:15px}
.wrap_chat .cont_chat>ul>li>.inner_talk>.user_thumb>a:after {position:absolute;top:0;left:0;right:0;bottom:0;border:1px solid rgba(0, 0, 0, 0.06);border-radius:50%;content:'';margin-bottom:10px}
.wrap_chat .cont_chat>ul>li>.inner_talk>.talk_info {padding-left:7px;display:inline-block;}
.wrap_chat .cont_chat>ul>li>.inner_talk>.talk_info>.name {font-size:13px;white-space:nowrap;}
.wrap_chat .cont_chat>ul>li>.inner_talk>.talk_info>.bubble {margin-top:5px;overflow:hidden;z-index:0;max-width:100%;border-radius:3px 20px 20px;font-size:13px;background-color:#ececec;word-break:break-all;word-break:break-word;word-wrap:break-word;vertical-align:bottom}
.wrap_chat .cont_chat>ul>li.me>.inner_talk{float:right;}
.wrap_chat .cont_chat>ul>li.me>.inner_talk>.talk_info>.bubble{border-radius:20px 20px 3px;background-color:#afdefd;}
.wrap_chat .cont_chat>ul>li>.inner_talk>.talk_info>.bubble>.txt {padding:9px 12px;white-space:pre-wrap;word-break:break-all;}
.wrap_chat .cont_chat>ul>li>.inner_talk>.talk_info>.bubble:after {content:'';display:block;clear:both}
.wrap_chat .box_chat {position:fixed;left:0;bottom:0;width:100%;}
.wrap_chat .box_chat>.frame_msg {position:relative;background-color:#fff;-webkit-box-shadow: 0px -3px 17px 0px rgba(179,179,179,0.51);-moz-box-shadow: 0px -3px 17px 0px rgba(179,179,179,0.51); box-shadow: 0px -3px 17px 0px rgba(179,179,179,0.51);}
.wrap_chat .box_chat>.frame_msg textarea {outline: none;}
.wrap_chat .box_chat>.frame_msg>.tf_msg {width:calc(100% - 105px);overflow-y:auto;height:39px;/*position:fixed;bottom:0;*/padding:8px 12px;margin:14px 15px;margin-bottom:0;border:0 none;font-size:13px;resize:none;/*border:1px solid #000;*/border-radius:100px;background-color: whitesmoke;}
위와 같이 변경합니다.
자신이 원하는대로 수정하면 됩니다 ^^;;
nodejs 실행방법
SSH 접속 후 node 폴더로 가서
npm init -y && npm install express mysql socket.io -- save && nohup node server.js > /dev/null 2>&1 &
위 명령어로 package.json 및 package-lock.json를 생성하고, express mysql socket.io 패키지를 설치하고, 백그라운드로 node를 실행합니다.
우분투 기준인데, 다른 운영체제를 사용한다면 nohup 대신 다른 명령어를 써야될 수도 있습니다.
어쨋든 screen 방식으로 server.js를 실행해야 합니다.
도커에서 실행하는 방법은 제일 밑에 따로 적어두겠습니다.
접속방법
위 경로로 접속하면 됩니다.
접속 링크 생성하기
<a href="javascript:window.open('/chat/','','width=500,height=700')" ;return="" false;=""><strong>실시간 채팅</strong></a>
PC 접속의 경우 위와 같이 넣으면 깔끔하게 나옵니다.
<a href="<?php echo G5_URL;?>/chat/" target="_blank">
모바일 접속의 경우 위와 같이 넣어주면 깔끔하게 나옵니다.
도커 설정
현재 제 홈페이지는 100% 도커화되어 있습니다.
nodejs도 도커로 설치하면 순식간에 설치가 되고 좋습니다. ㅎㅎ
docker-compose.yml 파일이 있는 곳에 소스에 있는 node 폴더를 복사합니다.
node폴더에 start.sh 스크립트를 생성합니다.
npm init -y && npm install express mysql socket.io -- save && node server.js
위 내용을 넣고 저장합니다.
docker-compose.yml 파일을 열어서
nodejs:
container_name: nodejs
image: node:alpine
restart: unless-stopped
working_dir: /home/node/app
environment:
- NODE_ENV=production
ports:
- "1121:1121"
command: sh start.sh
volumes:
- ./node:/home/node/app
- /etc/letsencrypt/live/yourdomain:/etc/letsencrypt/live/yourdomain
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
위에서 수정할 부분은 /etc/letsencrypt/live/yourdomain 입니다. SSL 인증서가 있는 폴더를 지정하면 됩니다.
위 내용을 넣고
sudo docker-compose up -d nodejs
위 명령어를 넣어주면 nodejs가 실행이 됩니다. -d 명령어로 백그라운드에서 실행하게 됩니다. 참쉽죠?
-
등록일 2020.10.10그누보드 SMTP 외부메일 설정하는 방법댓글 26
-
등록일 2020.10.03그누보드5에 실시간 채팅 구축하기댓글 13
-
등록일 2020.09.26
-
등록일 2020.09.24도커로 메일서버 구축하기댓글 4
관련자료
-
서명우성짱의 NAS를 운영하고 있습니다.
저의 즐거움이 여러분의 즐거움이면 좋겠습니다.
-
링크
89430849님의 댓글
HTTPS를 기준으로 변경은 어떻게 바꿔 적어야 하나요?
const cfg = require('./config'); // 설정파일
// 모듈
const app = require('express');
const fs = require('fs');
const G5ChatListener = require('./controllers/G5ChatListener');
const http = cfg.main.useHttps ? require('https').createServer({
cert:fs.readFileSync(cfg.main.httpsCredentials.cert),
key:fs.readFileSync(cfg.main.httpsCredentials.key)
},app) : require('http').createServer(app);
const io = require('socket.io')(http,{
cors:{
origin:'*'
}
});
const main = io.of('/index.goza');
new G5ChatListener(main);
http.listen(cfg.main.port,function(){
console.log(`${cfg.main.useHttps ? 'HTTPS' : 'HTTP'} Server is running. port: ${cfg.main.port}`);