Socket.io Node에서 하는 방법 (연결 시 이벤트)

2021. 8. 26. 20:19Node.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 연결 파일 생성

 

파일 경로
socket.js

 

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 파일

//./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. 결과

ejs 페이지
console

 

* 추가 :

블로그를 작성하다보니 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

 

728x90
반응형