websocket

hrj2233·2021년 11월 25일
0

websocket

목록 보기
1/1

http와 websocket은 프로토콜

http는 stateless, 즉 백엔드가 유저를 기억하지 못함.

websocket은 wss로 시작.ex) wss://홈페이지이름.
websocket 연결이 일어날때 마치 악수처럼 작동함.
브라우저가 서버로 websocket request를 보내면 서버가 받거나 거절해.
websocket은 브라우저와 서버는 연결되어 있기 때문에 서버는 네가 누구인지 기억함.
서버가 유저에게 메세지를 보내는것이 가능(http는 불가능)

htpp와 wss는 백엔드와 백엔드끼리도 통신 가능.
브라우저에는 내장된 websocket api가 있음.

ws 설치
ws는 클라이언트와 서버사이의 websocket실행

채팅방은 websocket의 protocol의 일부분이 아님.
채팅방은 그저 멋있는 feature일 뿐.
ws를 사용한 framework를 이용해서 채팅방 구현할 거임.
ws는 websocket의 core.(부가기능 x)

server.js

//http는 nodejs에 내장되어있음.
import http from 'http';
import WebSocket, { WebSocketServer } from 'ws';
import express from 'express';
import { SocketAddress } from 'net';

const app = express();

app.set('view engine', 'pug');
app.set('views', __dirname + '/views');
// static은 유저가 볼 수 있는 폴더를 지정하는거.
app.use('/public', express.static(__dirname + '/public'));

app.get('/', (_, res) => res.render('home'));
app.get('/*', (_, res) => res.redirect('/'));

const handleListen = () => console.log(`Listening on http://localhost:3000`);

//서버 생성.
//express는 ws를 지원안하므로 이렇게 작성하는 거임.
//아래 두개의 코드는 필수사항 아님. websocket만 만들어도 됨.
//http와 WebSocket이 같은 port에 있길 원하기 때문에 이렇게 작성.
//http를 설정한 이유는 views,static files, home, redirect를 원하기 때문에 만듬.
const server = http.createServer(app);
//웹소켓 서버 생성.
//이렇게 작성하면 같은 서버에서 http, webSocket 둘 다 작동
//express.js위에 http, http위에 websocket서버 만듬.
const wss = new WebSocketServer({ server });

//브라우저마다 소켓을 보내기 위한 데이터베이스 역할.
const sockets = [];

//socket이 frontend와 real-time으로 소통할 수 있음.
wss.on('connection', (socket) => {
  sockets.push(socket);
  socket['nickname'] = 'Anon';
  console.log('Connected to Browser ✅');
  socket.on('close', () => console.log('Disconnected from the Browser ❌'));
  socket.on('message', (msg) => {
    const message = JSON.parse(msg);
    switch (message.type) {
      case 'new_message':
        sockets.forEach((aSocket) =>
          aSocket.send(`${socket.nickname}: ${message.payload}`)
        );
        break;
      case 'nickname':
        // socket은 기본적으로 객체여서 아래와 정보를 넣을 수 있음.
        socket['nickname'] = message.payload;
        break;
    }
  });
});

server.listen(3000, handleListen);

app.js

const messageList = document.querySelector('ul');
const nickForm = document.querySelector('#nick');
const messageForm = document.querySelector('#message');

//프론트에는 백엔드를 연결해주는 websocket이 준비되어 있어서 따로 설치 안해됨
//즉 websocket을 이용해 백엔드와 연결하고 싶으면 프론트는 js가 해줌.
const socket = new WebSocket(`ws://${window.location.host}`);

function makeMessage(type, payload) {
  const msg = { type, payload };
  return JSON.stringify(msg);
}

socket.addEventListener('open', () => {
  console.log('Connected to Server ✅');
});

socket.addEventListener('message', (message) => {
  const li = document.createElement('li');
  li.innerText = message.data;
  messageList.appendChild(li);
  console.log('New message: ', message.data);
});

socket.addEventListener('close', () => {
  console.log('Disconnected from Server ❌');
});

function handleSubmit(event) {
  event.preventDefault();
  const input = messageForm.querySelector('input');
  socket.send(makeMessage('new_message', input.value));
  const li = document.createElement('li');
  li.innerText = `You: ${input.value}`;
  messageList.appendChild(li);
  input.value = '';
}

function handleNickSubmit(event) {
  event.preventDefault();
  const input = nickForm.querySelector('input');
  socket.send(makeMessage('nickname', input.value));
  input.value = '';
}

messageForm.addEventListener('submit', handleSubmit);
nickForm.addEventListener('submit', handleNickSubmit);

0개의 댓글