(react) soket.io를 이용한 메시지 기능 구현 (mysql을 이용한 기록남기기)

코딩하는 어린콩·2021년 10월 29일
0

React

목록 보기
2/2

저번에 socket.io를 구현한 메시지 기능을 구현했습니다. 하지만 데이터베이스 없이 기능 구현을 한다면 이때까지의 메시지의 기록이 다 사라지게 됩니다 ㅎㅎ

그래서 이번에는 mysql을 이용한 메시지 기록남기기를 해보겠습니다.

먼저 프런트는 이렇게 나오게됩니다. (주의 휴대폰 전용 프런트입니다! 지금 랜덤채팅 웹을 만들고 있어서요 ㅎㅎ)

그리고 2개의 클래스 컴포넌트가 있습니다.

제가 메시지를 보낸 컴포넌트

제가 받은 메시지 컴포넌트

먼저 코드를 봅시다.

Message.js

import React, { Component } from "react";
import ScrollToBottom from 'react-scroll-to-bottom';
import './message.css';
import Message_sendme from './message_sendme';
import Message_sendfrom from './message_sendfrom';
import io from 'socket.io-client';


const socket = io('http://localhost:3001');


export default class Message extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            premessages:[],
            userid:'jybin96',
            messages:[],
            message:''
        }
    }
    recievemessage=(messageobject)=>{
        this.setState({
            messages:[...this.state.messages,messageobject]
        })
    }
    componentWillMount(){
        const post = {
            userid:this.state.userid,
            touser:'snsk3779'
        }
        fetch('http://localhost:3001/messageshow',{
            method:"post",
            headers : {
                'content-type':'application/json'
            },
            body:JSON.stringify(post)
        }).then(res => res.json())
        .then(json =>{
            this.setState({
                premessages:json
            })
            console.log(this.state.premessages);
        })
        socket.on('send message',(messageobject)=>{
            this.recievemessage(messageobject);
        })
        console.log(this.state.messageobject);
    }
    
    onChange=(e)=>{
        this.setState({
            message:e.target.value
        })
        console.log(this.state.message);
    }
    onKeyDown=(e)=>{
        if(e.keyCode == 13){
            console.log("엔터키누름");
        }
    }
    onClick=()=>{
        this.setState({
            message:''
        })
        const messageobject = {
            body : this.state.message,
            userid:this.state.userid,
            touser:'snsk3779'
        }
        fetch('http://localhost:3001/message',{
            method:"post",
            headers : {
                'content-type':'application/json'
            },
            body:JSON.stringify(messageobject)
        }).then(socket.emit('message',messageobject))
        
       
    }
    render(){
        return(
            <div className="message_main">
                <div className="message_title">
                    <div className="message_title_name">
                        <p>채팅방</p>
                    </div>
                </div>
                <div className="message_scroll">
                <ScrollToBottom className="chat_scroll">
                    {this.state.premessages.map((message,index)=>{
                        if(this.state.userid === message.message_user){
                            return(
                                <Message_sendme message={message.message_body}/>
                            )
                        }else{
                            return(
                                <Message_sendfrom message={message.message_body}/>
                            )
                        }
                                       
                                    })
                        }
                    {this.state.messages.map((message,index)=>{
                        if(this.state.userid === message.userid){
                            return(
                                <Message_sendme message={message.body}/>
                            )
                        }else{
                            return(
                                <Message_sendfrom message={message.body}/>
                            )
                        }
                                       
                                    })
                        }
                </ScrollToBottom>
                </div>
                <div className="message_input">
                    <div className="message_inputbox">
                        <textarea onChange={this.onChange} value={this.state.message} onKeyDown={this.onKeyDown}/>
                    </div>
                    <div className="message_button">
                        <button onClick={this.onClick}>보내기</button>
                    </div>
                   
                </div>
            </div>
        )
    }
}

Message2.js

import React, { Component } from "react";
import ScrollToBottom from 'react-scroll-to-bottom';
import './message.css';
import Message_sendme from './message_sendme';
import Message_sendfrom from './message_sendfrom';
import io from 'socket.io-client';


const socket = io('http://localhost:3001');


export default class Message2 extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            premessages:[],
            userid:'snsk3779',
            messages:[],
            message:''
        }
    }
    recievemessage=(messageobject)=>{
        this.setState({
            messages:[...this.state.messages,messageobject]
        })
    }
    componentWillMount(){
        const post = {
            userid:this.state.userid,
            touser:'jybin96'
        }
        fetch('http://localhost:3001/messageshow',{
            method:"post",
            headers : {
                'content-type':'application/json'
            },
            body:JSON.stringify(post)
        }).then(res => res.json())
        .then(json =>{
            this.setState({
                premessages:json
            })
            console.log(this.state.premessages);
        })
        socket.on('send message',(messageobject)=>{
            this.recievemessage(messageobject);
        })
        console.log(this.state.messageobject);
    }
    
    onChange=(e)=>{
        this.setState({
            message:e.target.value
        })
        console.log(this.state.message);
    }
    onKeyDown=(e)=>{
        if(e.keyCode == 13){
            console.log("엔터키누름");
        }
    }
    onClick=()=>{
        this.setState({
            message:''
        })
        const messageobject = {
            body : this.state.message,
            userid:this.state.userid,
            touser:'jybin96'
        }
        fetch('http://localhost:3001/message',{
            method:"post",
            headers : {
                'content-type':'application/json'
            },
            body:JSON.stringify(messageobject)
        }).then(socket.emit('message',messageobject))
        
       
    }
    render(){
        return(
            <div className="message_main">
                <div className="message_title">
                    <div className="message_title_name">
                        <p>채팅방</p>
                    </div>
                </div>
                <div className="message_scroll">
                <ScrollToBottom className="chat_scroll">
                    {this.state.premessages.map((message,index)=>{
                            if(this.state.userid === message.message_user){
                                return(
                                    <Message_sendme message={message.message_body}/>
                                )
                            }else{
                                return(
                                    <Message_sendfrom message={message.message_body}/>
                                )
                            }
                                        
                                        })
                            }
                    {this.state.messages.map((message,index)=>{
                                        if(this.state.userid === message.userid){
                                            return(
                                                <Message_sendme message={message.body}/>
                                            )
                                        }else{
                                            return(
                                                <Message_sendfrom message={message.body}/>
                                            )
                                        }
                                    })
                        }
                </ScrollToBottom>
                </div>
                <div className="message_input">
                    <div className="message_inputbox">
                        <textarea onChange={this.onChange} value={this.state.message} onKeyDown={this.onKeyDown}/>
                    </div>
                    <div className="message_button">
                        <button onClick={this.onClick}>보내기</button>
                    </div>
                   
                </div>
            </div>
        )
    }
}

server.js

io.on('connection',function(socket){
  console.log("소켓 접속 성공");
  socket.on('message',(messageobject)=>{
    console.log(messageobject);
    io.emit('send message',messageobject)
  })
})


app.post("/message",(req,res)=>{
  console.log(req.body);
  const roomname = "room1" //여기서 룸정하기
  connection.query("insert into message_table (message_room,message_user,message_touser,message_body) values (?,?,?,?)"
  ,[roomname,req.body.userid,req.body.touser,req.body.body],function(err,rows,field){
    console.log("메세지 넣기 성공");
    res.send();
  })
})


app.post("/messageshow",(req,res)=>{
  console.log(req.body);
  connection.query("select * from message_table where message_user = ? or message_touser = ? order by message_time"
  ,[req.body.userid,req.body.userid],function(err,rows,field){
    res.send(rows);
  })
})

다소 복잡해 보이지만 굉장히 간단? 합니다 message.js 는 아이디가 jybin96입니다 그리고 소통하는 상대방 아이디는 sns k3779입니다. message2.js는 그와 반대겠죠?

만약 onclick함수가 발생하게되면 server.js의 /message에 messageobject를 보내 mysql의 message_table에 정보에 맞게 데이터를 저장시킵니다.

그러면 message_table 테이블에 우리가 메시지를 보낸 기록들이 차곡차곡 쌓이겠죠??

그렇게 소켓통신을하며 message_table에 기록이 쌓이는데

render 되기전의 생면 주기인 componentwillmount함수를 보시면

fetch('http://localhost:3001/messageshow',{
            method:"post",
            headers : {
                'content-type':'application/json'
            },
            body:JSON.stringify(post)
        }).then(res => res.json())
        .then(json =>{
            this.setState({
                premessages:json
            })
            console.log(this.state.premessages);
        })

나의 아이디와 상대방의 아이디를 담은 post 객체를 server.js의 /messageshow에 보냅니다.

그리하여 server.js의 /messageshow에서

req.body를 통하여 가져온 데이터를

connection.query("select * from message_table where message_user = ? or message_touser = ? order by message_time"
  ,[req.body.userid,req.body.userid],function(err,rows,field){
    res.send(rows);
  })

이 쿼리문에 넣어서 내가 이 room에서 대화를 나누었던 데이터들을 오래된 메시지 순서대로 뽑아냅니다.

그리고 다시 message.js에 뽑은 데이터를 주죠

그래서 이 뽑아 온 데이터들을 premessages라는 state에 저장하게 되고

render() 안의 return에서

{this.state.premessages.map((message,index)=>{
                            if(this.state.userid === message.message_user){
                                return(
                                    <Message_sendme message={message.message_body}/>
                                )
                            }else{
                                return(
                                    <Message_sendfrom message={message.message_body}/>
                                )
                            }
                                        
                                        })
                            }

이것을 실행시켜서 만약 나의 아이디가 뽑아온 데이터의 user아이디와 같다면 내가 보낸 컴포넌트의 Message_sendme를 랜더링 시키고 만약 상대방이 보낸 데이터면 Message_sendfrom 컴포넌트를 실행하게 됩니다.

  • 유저1

  • 유저2

    이렇게 나오게 됩니다. 자그러면 mysql에 데이터들이 잘 저장되었는지 보겠습니다.

    네 잘 저장되었네요 ㅎㅎ

그리고 다시 창을 다 닫고 두 개의 js파일을 다시 rendering 해보시면 그대로 저장되어있는 걸 확인할 수 있습니다!

0개의 댓글

관련 채용 정보