λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
⭐ Personal_Study/Javascript

μ›Ήμ†ŒμΌ“μ„ ν™œμš©ν•΄ μ‹€μ‹œκ°„ μ±„νŒ… κ΅¬ν˜„ν•˜κΈ° - React

by ν¬μŠ€νŠΈμ‰μ΄ν¬ 2023. 5. 6.

μ›Ήμ†ŒμΌ“μ„ ν™œμš©ν•΄ μ‹€μ‹œκ°„ μ±„νŒ… κ΅¬ν˜„ν•˜κΈ° - React

μ›Ήμ†ŒμΌ“μ„ ν™œμš©ν•΄ μ‹€μ‹œκ°„ μ±„νŒ… κ΅¬ν˜„ν•˜κΈ° - Springboot
μ›Ήμ†ŒμΌ“μ„ ν™œμš©ν•΄ μ‹€μ‹œκ°„ μ±„νŒ… κ΅¬ν˜„ν•˜κΈ° - React

React μ½”λ“œ

사싀 μ›Ήμ†ŒμΌ“μ—μ„œ λ°±μ—”λ“œλŠ” μ€‘κ°œμ—­ν• λ§Œ ν•˜κ³  λŒ€λΆ€λΆ„μ˜ μž‘μ—… (μ›Ήμ†ŒμΌ“ 객체 생성, μ—°κ²°, 데이터 μ†‘μˆ˜μ‹ )은 ν”„λ‘ νŠΈμ—μ„œ 이루어진닀.

μ•„λž˜ μ½”λ“œλŠ” μ›Ήμ†ŒμΌ“μ„ 기반으둜 κ°„λ‹¨ν•œ μ‹€μ‹œκ°„ μ±„νŒ…μ„ κ΅¬ν˜„ν•œ ν”„λ‘ νŠΈ μ½”λ“œμ΄λ‹€.

ν•΄λ‹Ή μ½”λ“œλŠ” 메세지λ₯Ό μ£Όκ³  λ°›μ§€λ§Œ κ²°κ΅­ 무엇이 됐든 μ›Ήμ†ŒμΌ“μœΌλ‘œ 데이터λ₯Ό μ£Όκ³  λ°›λŠ” μ›λ¦¬λŠ” λ˜‘κ°™μ•„μ„œ, μ½”λ“œλ₯Ό λ³€ν˜•ν•˜λ©΄ 훨씬 λ‹€μ–‘ν•œ κΈ°λŠ₯듀을 κ΅¬ν˜„ν•  수 μžˆλ‹€.

μ•„μ‰½κ²Œλ„ λ‚΄κ°€ ν”„λ‘ νŠΈκ°€ μ•„λ‹ˆλΌ λ”°λ‘œ λ””μžμΈμ€ 넣지 μ•Šμ•˜λ‹€.

μ‹€μ œ ν”„λ‘œμ νŠΈμ—μ„œ μ‚¬μš©ν–ˆλ˜ μ½”λ“œλ₯Ό κ°€μ Έμ˜¨ 거라 λ‹€λ₯Έ ν”„λ‘œμ νŠΈμ— μ μš©ν•  경우 적절히 λ³€ν˜•ν•΄μ„œ μ‚¬μš©ν•˜λ©΄ λœλ‹€.

μ½”λ“œ λŒ€λΆ€λΆ„μ— 주석이 λ‹¬λ €μžˆμ–΄μ„œ μžμ„Έν•œ μ„€λͺ…은 μƒλž΅.

import { React, useRef, useState, useEffect } from 'react'
import * as StompJs from '@stomp/stompjs'

const WebSocketChatTest = () => {
  const client = useRef({})

  const [chatList, setChatList] = useState([])
  const [message, setMessage] = useState('')

  // μž„μ‹œλ‘œ μ„€μ •ν•΄λ‘” 인자 λ³€μˆ˜ (λ‚˜μ€‘μ— ν”„λ‘ νŠΈμ—μ„œ λ„£μ–΄μ£Όμ„Έμš”)
  const chatRoomSeq = 1
  const senderSeq = 1
  const receiverSeq = 2

  useEffect(() => {
    connect()

    return () => disconnect()
  }, [])

  // connect: μ›Ήμ†ŒμΌ“(stomp) μ—°κ²° 
  const connect = () => {

    // stomp js client 객체 생성
    client.current = new StompJs.Client({

      brokerURL: 'ws://localhost:8080/ws-stomp', // μ—°κ²°ν•  url(이후에 localhostλŠ” 배포 λ„λ©”μΈμœΌλ‘œ λ°”κΏ”μ£Όμ„Έμš”)

      // μ—°κ²° ν™•μΈμš© 좜λ ₯ 문ꡬ
      debug: function (str) {
        console.log(str)
      },

      // μ—λŸ¬ λ°œμƒ μ‹œ μž¬μ—°κ²° μ‹œλ„ λ”œλ ˆμ΄
      reconnectDelay: 5000,
      heartbeatIncoming: 4000,
      heartbeatOutgoing: 4000,

      // μ—°κ²° μ‹œ
      onConnect: () => {
        console.log('success')
        subscribe() // 메세지(μ±„νŒ…)을 받을 μ£Όμ†Œλ₯Ό κ΅¬λ…ν•©λ‹ˆλ‹€.
      },

      // μ—λŸ¬ λ°œμƒ μ‹œ 둜그 좜λ ₯
      onStompError: (frame) => {
        console.log(frame)
      },
    })

    // client 객체 ν™œμ„±ν™”
    client.current.activate()
  }

  // subscribe: 메세지 받을 μ£Όμ†Œ ꡬ독
  const subscribe = () => {

    // κ΅¬λ…ν•œ μ£Όμ†Œλ‘œ 메세지 받을 μ‹œ 이벀트 λ°œμƒ
    // (/sub: μ›Ήμ†ŒμΌ“ 곡톡 ꡬ독 μ£Όμ†Œ), (/chat: κΈ°λŠ₯별(1:1, 3:3, 친ꡬ μΆ”κ°€ν›„) ꡬ독 μ£Όμ†Œ), (/chatRoomSeq: ν•˜μœ„ ꡬ독 μ£Όμ†Œ(μ±„νŒ…λ°©))    
    client.current.subscribe('/sub/chat/' + chatRoomSeq, (body) => {

      // λ°›μ•„μ˜¨ 제이슨 νŒŒμ‹±
      const json_body = JSON.parse(body.body) 

      console.log('메세지 λ°›μ•˜λ‹Ή') // ν™•μΈμš© 좜λ ₯ (이처럼 메세지 수령 μ‹œ νŠΉμ • 이벀트λ₯Ό λ°œμƒ μ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.)
      console.log(body.body)

      // λ°›μ•„μ˜¨ μ±„νŒ… μ±„νŒ… λ¦¬μŠ€νŠΈμ— λ„£κΈ° (이뢀뢄은 μž„μ‹œλ‘œ ν•œ κ±°κ³  이후 ν”„λ‘ νŠΈμ—μ„œ ν•„μš”μ— 따라 λ°›μ•„μ˜¨ λ©”μ„œμ§€λ₯Ό λ Œλ”λ§ ν•˜λ©΄ λ©λ‹ˆλ‹€.)
      setChatList((_chat_list) => [
        ..._chat_list,
        json_body.senderSeq,
        json_body.message,
        json_body.createdAt,
      ])
    })
  }


  // publish: 메세지 보내기
  const publish = (message) => {

    // 연결이 μ•ˆλ˜μ–΄μžˆμ„ 경우
    if (!client.current.connected) {
      alert('연결이 μ•ˆ λ˜μ–΄μžˆμ–΄')
      return
    }

    // μž…λ ₯된 메세지가 μ—†λŠ” 경우
    if (!message) {
      alert('메세지 μž…λ ₯ ν•΄')
      return
    }

    // 메세지λ₯Ό 보내기
    client.current.publish({

      // destination: 보낼 μ£Όμ†Œ
      // (/pub: μ›Ήμ†ŒμΌ“ 곡톡 λ°œμ‹ μš© μ£Όμ†Œ), (/send: κΈ°λŠ₯별 κ°œλ³„ λ°œμ‹ μš© μ£Όμ†Œ)
      destination: '/pub/send',

      // body: 보낼 메세지
      body: JSON.stringify({
        message: message,
        chatRoomSeq: chatRoomSeq,
        senderSeq: senderSeq,
        receiverSeq: receiverSeq,
      }),
    })

    // 보내고 메세지 μ΄ˆκΈ°ν™”
    setMessage('')
  }

  // disconnect: μ›Ήμ†ŒμΌ“ μ—°κ²° 끊기
  const disconnect = () => {
    console.log('연결이 λŠμ–΄μ‘ŒμŠ΅λ‹ˆλ‹€')
    client.current.deactivate()
  }


  // handleChage: μ±„νŒ… μž…λ ₯ μ‹œ state에 κ°’ μ„€μ •
  const handleChange = (event) => {
    setMessage(event.target.value)
  }


  // handleSubmit: 보내기 λ²„νŠΌ λˆŒλ €μ„ λ•Œ 보내기(publish μ‹€ν–‰)
  const handleSubmit = (event, message) => {
    event.preventDefault()

    publish(message)
  }

  // μ•„λž˜λŠ” ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•΄ μž„μ‹œλ‘œ μž‘μ„±ν•œ ν…œν”Œλ¦ΏμœΌλ‘œ 이후에 ν•„μš”μ— 따라 ν…œν”Œλ¦Ώμ„ μž‘μ„±ν•΄μ£Όμ„Έμš”
  return (
    <div>
      <div className={'chat-list'}>
        {chatList.map((item, index) => {
          return <div key={index}>{item}</div>
        })}
      </div>
      <form onSubmit={(event) => handleSubmit(event, message)}>
        <div>
          <input
            type={'text'}
            name={'chatInput'}
            onChange={handleChange}
            value={message}
          />
        </div>
        <input type={'submit'} value={'메세지 보내기'} />
      </form>
    </div>
  )
}

export default WebSocketChatTest

'⭐ Personal_Study > Javascript' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

AJAX  (0) 2022.11.05
Axios  (0) 2022.11.05
동기와 비동기  (0) 2022.11.04
Callback & Promise  (0) 2022.11.04
JavaScriptμ—μ„œμ˜ This  (0) 2022.11.03

λŒ“κΈ€