๐Ÿ’ป BackEnd/๐ŸŸฉ NodeJS

[Network] [NodeJS] Socket.IO๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์†Œ๋ฌธ์ž๋ฅผ ๋ณด๋‚ด๋ฉด ๋Œ€๋ฌธ์ž๋กœ ๋ฐ”๊พธ๊ธฐ

Dbswnstjd 2022. 4. 21. 17:48

Socket.IO


Client.HTML

<!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;
      }

      #myChat {
        width: 100%;
      }
    </style>
  </head>

  <body>
    <div id="chatContent"></div>
    <input id="myChat" type="text" />

    <script>
      const socket = io.connect('http://localhost:3000');

      socket.on('msg', function (data) {
        $('#chatContent').append(`${data}<br>`);
      });

      $('#myChat').on('keyup', function () {
        if (window.event.keyCode == 13) {
          $('#chatContent').append(`Client : "${$(this).val()}" ๋ณด๋ƒ…๋‹ˆ๋‹ค.<br>`);
          socket.emit('msg', $(this).val());
          $(this).val('');
        }
      });
    </script>
  </body>
</html>

๋จผ์ € ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ณด์—ฌ์ค„ ๊ฐ„๋‹จํ•œ ํ™”๋ฉด์„ ๋งŒ๋“ค์–ด ๋ณด์•˜๋‹ค. 

const socket = io.connect('http://localhost:3000');

htmlํŒŒ์ผ์€ ๋งค์šฐ ๊ธฐ๋ณธ์ ์ธ ๋‚ด์šฉ๋งŒ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ์ฝ”๋“œ์ด๋‹ค. 

socket ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„์˜ 3000๋ฒˆ ํฌํŠธ์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๊ฒƒ์ด๋‹ค. 

io.connect๋Š” ์„œ๋ฒ„์™€์˜ ์—ฐ๊ฒฐ์„ ํ•˜๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ์ด๋‹ค. 


tcpServer.js

const bodyParser = require('body-parser');
const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

const port = 3000;


const user = {
  id: 'test',
  password: '1234',
}; // ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋ฅผ ๋Œ€์‹  ํ•ด์ค„ user ์ •๋ณด
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/client.html');
});

app.get('/login', (req, res) => {
  res.sendFile(__dirname + '/login.html');
});

app.post('/login', (req, res) => {
  console.log(req.body);
  const id = req.body.user_id;
  const password = req.body.user_pwd;
  console.log(id);
  if (id === user.id && password === user.password) res.redirect('/');
  // ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์„ ํ•˜๊ฒŒ ๋˜๋ฉด ์ฟผ๋ฆฌ๋ฌธ์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋จ
  else res.send('์•„์ด๋””๋‚˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ํ‹€๋ ธ์Šต๋‹ˆ๋‹ค. ');
});

http.listen(port, () => {
  console.log(`Listening on ${port}`);
});

io.on('connection', (socket) => {
  console.log(socket.id, 'Connected');

  socket.emit('msg', `${socket.id}๊ฐ€ ์—ฐ๊ฒฐ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. `);

  socket.on('msg', (data) => {
    console.log(socket.id, data);
    var result = '';
    for (let i = 0; i < data.length; i++) {
      if (data[i] === data[i].toUpperCase()) {
        result += data[i].toLowerCase();
      } else {
        result += data[i].toUpperCase();
      }
    }
    socket.emit('msg', `Server: ${result}๋ฅผ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. `);
  });
});

NodeJS์—์„œ express๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ app๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  http ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ ๋‹ค. 

๋˜ํ•œ socket.io ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•œ๋‹ค. 

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/client.html');
});

์—ฌ๊ธฐ์„œ localhost:3000/์œผ๋กœ ์ ‘๊ทผํ•˜๋ฉด client.html ํŒŒ์ผ์„ ๋ Œ๋”๋ง ํ•ด์ค€๋‹ค. 

์†Œ์ผ“์„ ์—ฐ๊ฒฐํ•˜๊ธฐ ์ „์— socket ๋ชจ๋“ˆ์˜ ์ฃผ์š” ๋ฉ”์†Œ๋“œ๋ฅผ ์•Œ์•„๋ณด์ž.

๋ฉ”์†Œ๋“œ๋ช… ์„ค๋ช…
socket.on('methodName', callback Function(data){}) ์†Œ์ผ“์— ์—ฐ๊ฒฐ๋œ ๋ธŒ๋ผ์šฐ์ €๋‚˜ ์„œ๋ฒ„์—์„œ ๋ฉ”์†Œ๋“œ๋ช…์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ฐ–๋Š” emit์„ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด ์ดํ›„ ์ฝœ๋ฐฑํ•จ์ˆ˜๊ฐ€ ๋™์ž‘ํ•˜๊ฒŒ ๋œ๋‹ค. emit ๋ฉ”์†Œ๋“œ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ data๋กœ ๋ฐ›์•„์™€ ์ ์ ˆํ•œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. 
socket.on('connection', function(socket)) ์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ์œ„ํ•ด ํ•„์ˆ˜์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์•ผ ํ•˜๋Š” ํ•จ์ˆ˜.
function์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์†Œ์ผ“ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. 
socket.emit('methodName', data) ์†Œ์ผ“ ์—ฐ๊ฒฐ๋œ ๋ธŒ๋ผ์šฐ์ €/์„œ๋ฒ„์—์„œ ๋ฉ”์†Œ๋“œ๋ช…์„ ๊ฐ–๋Š” on ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ ํ•œ๋‹ค. ์ด๋•Œ on ํ•จ์ˆ˜์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ธ๋ฅด data๋กœ ํ•จ๊ป˜ ์ „์†กํ•œ๋‹ค. 
socket.join('SpaceName') '๊ณต๊ฐ„๋ช…'์„ ํ‚ค๋กœ ํ•˜์—ฌ ์†Œ์ผ“๋“ค์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฉ”์†Œ๋“œ

socket.emit์„ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ์— socket id๋ฅผ ๋ณด๋‚ด์ฃผ์–ด ์–ด๋Š ์†Œ์ผ“๊ณผ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. 

๊ทธ๋ฆฌ๊ณ  Server์—์„œ Client์—์„œ ๋ณด๋‚ด์˜จ ๋ฐ์ดํ„ฐ๊ฐ€ ์†Œ๋ฌธ์ž๋ฉด ๋Œ€๋ฌธ์ž๋กœ ๋ฐ”๊พธ์–ด์ฃผ๊ณ  ๋Œ€๋ฌธ์ž๋ฉด ์†Œ๋ฌธ์ž๋กœ ๋ฐ”๊พธ์–ด์ค€๋‹ค. 

์ด๋Š” Client์—์„œ ๋ณด๋‚ด์˜จ ๋ฐ์ดํ„ฐ๊ฐ€ ์†Œ๋ฌธ์ž์ธ์ง€ ๋Œ€๋ฌธ์ž์ธ์ง€ ๊ตฌ๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ํ•˜๋‚˜์”ฉ ๊ฒ€์‚ฌ๋ฅผ ํ•ด์ฃผ๋„๋ก ํ•˜์˜€๋‹ค.

๊ธ€์ž๋ฅผ ๋Œ€๋ฌธ์ž๋กœ ๋ฐ”๊พธ์—ˆ์„ ๋•Œ ๊ธฐ์กด์˜ ๊ธ€์ž์™€ ๊ฐ™๋‹ค๋ฉด ๋Œ€๋ฌธ์ž์ด๋ฏ€๋กœ ์†Œ๋ฌธ์ž๋กœ ๋ฐ”๊พธ์–ด ์ฃผ๊ณ  ๊ทธ ์™ธ์˜ ๊ฒฝ์šฐ๋Š” ๋ชจ๋‘ ๋Œ€๋ฌธ์ž๋กœ ๋ฐ”๊พธ์–ด ์ค€๋‹ค. 

 

Server ์‹คํ–‰

nodemon์„ ์‚ฌ์šฉํ•˜์—ฌ tcpServer.js ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ค€๋‹ค. 

์„œ๋ฒ„๋ฅผ ํ‚ค๊ณ  localhost:3000์— ์ ‘์†ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜์˜ค๊ฒŒ ๋œ๋‹ค. 

Server-Client ์—ฐ๊ฒฐ

์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—ฐ๊ฒฐ๋˜์—ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. 

์•„๋ž˜์— ๋‚ด์šฉ์„ ์ž…๋ ฅํ•˜๋ฉด ๋Œ€๋ฌธ์ž๋Š” ์†Œ๋ฌธ์ž๋กœ, ์†Œ๋ฌธ์ž๋Š” ๋Œ€๋ฌธ์ž๋กœ ๋ฐ”๊ฟ”์ฃผ๊ฒŒ ๋œ๋‹ค. 

๋Œ€๋ฌธ์ž-์†Œ๋ฌธ์ž ๋ฐ”๊ฟ”์ฃผ๊ธฐ

[ํšŒ๊ณ ]

nodeJS๋ฅผ ์“ฐ๋ฉด์„œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ API๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์•˜์ง€๋งŒ Socket.IO๋Š” ์ฒ˜์Œ ์‚ฌ์šฉํ•ด ๋ณด์•˜๋‹ค. ๋„คํŠธ์›Œํฌ์—์„œ ๋ฐฐ์šด HTTP์™€ TCP ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜์˜€๋Š”๋ฐ ๋„คํŠธ์›Œํฌ์— ๋Œ€ํ•œ ์ดํ•ด๋„ ๋˜๊ณ  ์ฒ˜์Œ ํ•ด๋ณด๋Š” ์†Œ์ผ“ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด์–ด์„œ ์ฑ„ํŒ…์„ ๋” ์ž์„ธํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด๋ณด๊ณ  ์‹ถ์€ ๋งˆ์Œ์ด ์ƒ๊ฒผ๋‹ค. ํด๋ผ์ด์–ธํŠธ ์ชฝ์€ ์ž˜ ์•Œ์ง€ ๋ชปํ•ด์„œ ์ œ๋Œ€๋กœ ํ•˜์ง€ ๋ชปํ–ˆ๋Š”๋ฐ ์‹œ๊ฐ„์ด ๋œ๋‹ค๋ฉด ์ œ๋Œ€๋กœ ๋‹ค์‹œ ๊ตฌํ˜„ํ•ด๋ณด๊ณ  ์‹ถ๋‹ค.