2021. 8. 26. 20:19ㆍNode.js, Express
Socket.io는 실시간 양방향 서버와 클라이언트간 통신이 가능해 상호작용이 가능한 기술이다.
환경 : express-generator, ejs
express : 서버 ejs : 클라이언트
순서 :
socket.js 파일 생성 => ./bin/www 에서 require, import하여 함수 실행 => 클라이언트 ejs 파일 생성
작동 :
클라이언트에서 이름, 나이, 채널 을 가진 정보로 해당하는 채널명에 맞춰 유저가 접속 한 후,
해당 채널명을 입력 해 주면 해당 채널에 들어간 유저들을 불러온다.
설치 :
npm i socket.io
1. ./socket/socket.js socket.io 연결 파일 생성
const socketIo = require('socket.io')
module.exports = (server) => {
const io = socketIo(server)
const list = {}
// io.on 클라이언트가 연결되면 발생
io.on('connection', async (socket)=>{
// emit 클라이언트에 first 이벤트 발생
await socket.emit('one', `${socket.id} 입니다~ `)
// cOne 이벤트를 서버에서 받음
// 유저가 채널 접속
await socket.on('cOne', (data)=>{
//해당 채널명이 없다면 채널을 만들어서 유저를 저장하고 채널이 있다면 채널에 접속
if(!list[`${data.channal}`]){
list[`${data.channal}`] = []
}
list[`${data.channal}`].push(data)
socket.join(data.channal)
})
// 채널에있는 유저 목록 확인
await socket.on('cTow',(data)=>{
//채널명을 받아 해당 채널 유저를 전송
const channal = list[`${data.channal}`]
console.log(channal, '채널')
console.log(data.channal, '채널 명')
socket.emit('two',{list:channal, channalName: data.channal})
})
})
}
1-1. socket.io 주요 함수
socket.on : socket.on('이벤트 명', Callback Function) : 해당 이벤트를 받고 콜백함수를 실행
socket.emit : socket.emit('이벤트 명', Data) : 이벤트 명을 지정하고 데이터를 전송
이벤트를 연결하려면 서버와 클라이언트가 같은 이벤트 이름으로 지정하면된다.
1-2. socket.io 주요 이벤트
connection : Client 와 연결되었을 때 발생
disconnection : Client 와 연결해제되었을 때 발생
1-3 room 를 사용하지 않은 이유
참여 인원 수나 방의 수를 구하는 것이 불안정하기 때문에 서버상에 배열곽 객체를 만들어 관리하는것이 편할꺼같다는 다른 블로그 글이 있다.
2. socket.js 함수 사용
http.createServer(app) 를 받아 socket.js에 파라미터 값으로 넣어 준다.
현재 환경은 express - generator 이라서 ./bin/www 파일에서 넣어준다.
* 만약 generator 환경이 아니라면 app.js에서 파라미터를 넣어주면 된다.
//./bin/www
...
/**
* Create HTTP server.
*/
//socket을 선언하여 server 값을 넣어준다.
var server = http.createServer(app);
const socket = require('../socket/socket')
socket(server)
...
3. 클라이언트 생성 (ejs 사용)
cdn으로 socket.io를 사용하고 데이터를 전송 주소에 보낸다.
ejs, html 둘다 사용가능
상호작용을 위해 서버와 클라이언트간 이벤트 명을 맞춰주었다.
./views/test.ejs
<!-- ./views/test.ejs -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Socket.io Test</title>
<script src="https://cdn.socket.io/socket.io-3.0.1.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
* {
box-sizing: border-box;
}
#chatContent {
border: 1px solid #000;
width: 100%;
height: 200px;
margin-bottom: 10px;
overflow-y: auto;
}
#chatContent1 {
border: 1px solid #000;
width: 100%;
height: 200px;
margin-bottom: 10px;
overflow-y: auto;
}
#myChat {
width: 100%;
}
</style>
</head>
<body>
<div id="chatContent">
</div>
<input id="name" type="text">
<input id="age" type="text">
<input id="channal" type="text">
<button id="btn" onclick="submit()" >save Data</button>
<p><input id="channalFind" type="text"></p>
<p><button id="Donebtn" onclick="Donebtn()">check Btn</button></p>
</div>
<script>
var socket = io.connect('ws://localhost:3000');
socket.on('one', function (data) {
$("#chatContent").append(`${data}<br>`);
});
socket.on('two', function (data) {
console.log(`채널 명 : ${data.channalName}`)
console.log(`채널 유저목록 : `,data.list)
});
const submit = () => {
const name = $('#name').val()
const age = $('#age').val()
const channal = $('#channal').val()
$("#chatContent").append(`Client : "${name}, ${age},${channal}" 보냅니다.<br>`);
socket.emit('cOne', {name , age, channal});
}
const Donebtn = () => {
const name = $('#name').val()
const channal = $('#channalFind').val()
socket.emit('cTow', {name, channal});
}
</script>
</body>
</html>
4. 결과
* 추가 :
블로그를 작성하다보니 socket.io가 실제 rest api서버에서 같이 사용을 하면 메모리를 먹기 때문에 나누는게 좋다는 의견이 있었다.
그러므로 express 및 여러가지 라이브러리를 설치하는 express-generator 말고
express만 있는 서버를 구성하여 진행하는게 좋을꺼 같다.
참고 :
https://jsikim1.tistory.com/165
https://programmerdaddy.tistory.com/66
https://lgphone.tistory.com/123
https://www.zerocho.com/category/NodeJS/post/57edfcf481d46f0015d3f0cd
'Node.js, Express' 카테고리의 다른 글
Passport-jwt Cookie에 저장된 토큰 값 사용 방법 (2) | 2022.05.16 |
---|---|
ES5 | ES6 import/export, CommonJs require 방법 (0) | 2021.08.30 |
failed to parse private key 오류 해결 (firebases .env파일) dotenv (0) | 2021.08.18 |
node, pm2를 설치하고 명령어를 찾지 못 할 때 (0) | 2021.03.15 |
dayjs사용하기 (moment 대체) (0) | 2021.02.24 |