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. 오류 수정
안된다 ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ
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;
}
새해도 열코합시다 ! 새해복 많이 받으세요오옹 ~~
'React' 카테고리의 다른 글
[React] 절대경로 설정하기 (0) | 2022.01.06 |
---|---|
[React] react router (v6) (1) | 2021.12.16 |
React - mysql연동하기, 연결 (데이터불러오기) (0) | 2020.10.17 |
React - Mysql 연동하기, 연결(데이터 저장) (0) | 2020.10.17 |
React와 Express연동하기 2 (0) | 2020.10.15 |