본문 바로가기

React

[React] React -Socket을 이용한 채팅기능

반응형

 socket이란 뭘까 ?

 

우리(Client)는 여태 서버(Server)의 데이터가 필요할때 서버에게 요청하고 통신하여 사용하였다.

2020/10/15 - [React] - React와 Express연동하기 1

2020/10/15 - [React] - React와 Express연동하기 2

 위글처럼 말이다. 이것이 HTTP통신이다.

 

그러나, socket통신은 특정 포트를 통해 실시간으로 양방향 통신을 하는 방식이다.

 

둘의 아주 큰 차이는 요청할때만 켜지느냐(:HTTP) 항상 실시간으로 켜지느냐(:socket), client가 요청하고 server가 보내주는 단방향 통신(HTTP)냐, server와 client가 같이 서로 보내는 양방향 통신이냐(socket) 이다.

 

socket은 매우 유용하다. 오늘 해본 채팅기능 뿐만 아니라 요새 인기인 유튜브 같은 실시간 스트리밍 같은 것도 할 수 있단다.

 

 코드를 살피기 전에 socket의 기본개념 3가지가 있다. 

emit : 이벤트 발생

on : 발생한 이벤트 받기

join : 특정한 방(?)을 설정할 수 있게 해주는 함수

 

//frontend
socket.emit("send message", {
      name: this.state.name,
      msg: this.state.msg,
    });
    
//backend
  socket.on("send message", (item) => {
    const message = item.name + " : " + item.msg;
    console.log(message);
    io.emit("receive message", { name: item.name, msg: item.msg });
  });
  
"send message"라는 이름의 이벤트를 발생하고 받는 모습

 


당연히 리액트를 먼저 만들자.

1. CRA(create-react-app)

npm create-react-app [project name]

2. module 설치

npm install --save express

npm install --save http

npm install --save socket.io //backend

npm install --save socket.io-client //frontend

3. App.js

import React, { Component } from "react";
import "./App.css";
import io from "socket.io-client"; //모듈 가져오기

const socket = io.connect("http://localhost:3001");  //백엔드 서버 포트를3001와 socket연결 

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "",          //id
      msg: "",			 //메세지 내용
      messageList: [],	 //메세지 리스트
    };
  }
  sendMsg = (e) => {
    e.preventDefault();
    socket.emit("send message", {		//"send message"라는 이벤트 발생 (1)
      name: this.state.name,
      msg: this.state.msg,
    });
    this.setState({
      name: "",
      msg: "",
    });
  };
  componentWillMount() {
    socket.on("receive message", (message) => {   //"receive message"라는 이벤트 받음(2)
      this.setState({
        messageList: [...this.state.messageList, message],
      });
    });
  }
  onChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value,
    });
  };
  render() {
    return (
      <div>
        <section className="chat_list">
          {this.state.messageList.map((item) => (
            <div className="messagelist">
              <p className="username">{item.name}</p>
              <p className="msg_text">{item.msg}</p>
            </div>
          ))}
        </section>
        <form className="chat_con" onSubmit={this.sendMsg}>
          <div className="chat_inputs">
            <input
              type="text"
              onChange={this.onChange}
              value={this.state.name}
              name="name"
              id="id"
              placeholder="아이디"
            />
            <input
              type="text"
              onChange={this.onChange}
              value={this.state.msg}
              name="msg"
              id="msg"
              placeholder="메세지내용"
            />
          </div>
          <button className="chat_button" type="submit">
            보내기
          </button>
        </form>
      </div>
    );
  }
}

4. server.js

const express = require("express");
const app = express();
const port = 3001;  //포트 번호 3001
var http = require("http").createServer(app);
const io = require("socket.io")(http);

io.on("connection", (socket) => {
  socket.on("send message", (item) => {   //"send message"라는 이벤트 받음 (1)
    const message = "id : " + item.name + "//  message : " + item.msg;
    console.log(message);
    io.emit("receive message", { name: item.name, msg: item.msg });  //"receive message"라는 이벤트 발생
  });
  socket.on("disconnect", function () {
    console.log("user disconnected: ", socket.id);
  });
});
http.listen(port, () => {
  console.log(`app listening on port : ${port}`);
});

 

 

5. 오류 수정

Error

안된다 ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ

has been blocked by CORS policy : "No 'Access-Control-Allow-Origin' header is present on the requested resource."

어떤 이유 때문에 CORS를 정책에 위반이 된단다. proxy를 쓰면 된다 ! 그러나 오늘은 편법을 써보자(다음에 올리겠따!)

 

cmd를 켜서 크롬이 있는 폴더(C:\Program Files\Google\Chrome\Application)로 가서

chrome --disable-web-security --user-data-dir

이것을 실행시켜라.

 

6. 결과화면

입력창
입력 후

 

 

코드를 보면 파란 박스 위에는 아이디가, 파란박스 안에는 메세지 내용이 담겨있다!

 

 

 만들고 보니 css를 너무 대충 만든 것 같다...ㅎ 다음에 블로그 만들 때 이쁘게 만들어보겠다 

7. 귀찮은 사람들을 위한 App.css

.chat_con {
  display: flex;
  height: 60px;
  justify-content: space-evenly;
  align-items: center;
  padding: 10px;
  width: 100vw;
}
.chat_inputs {
  width: 70%;
  height: 100%;
}
.chat_inputs > input {
  height: 100%;
  width: 40%;
  border: 0.5px solid "lightgray";
  font-size: 18px;
  border-radius: 10px;
  margin-right: 25px;
  padding: 5px;
}
.chat_button {
  margin-left: 10px;
  border: 0px;
  background: #f05052;
  width: 100px;
  height: 100%;
  border-radius: 5px;
  color: white;
  font-size: 18px;
}
.chat_list {
  padding: 10px;
  width: 90vw;
}
.messagelist {
  min-height: 40px;
  margin: 5px 0;
}
.username {
  margin-left: 5px;
  margin-top: 5px;
  font-size: 20px;
}
.msg_text {
  margin: 0;
  font-size: 25px;
  color: white;
  width: 100%;
  display: flex;
  align-items: center;
  padding: 10px;
  background-color: skyblue;
  min-height: 40px;
  border-radius: 10px;
}

 

새해도 열코합시다 ! 새해복 많이 받으세요오옹 ~~ 

반응형