[ 개발 ] React Native - Websocket 통신

장태규·2024년 10월 27일

[ WebSocket ]

목록 보기
5/8

웹소켓 연결 컴포넌트 샘플 코드

import React, { useState, useEffect, useRef } from 'react';
import { View, Text, Button, TextInput, ScrollView, StyleSheet } from 'react-native';

const WebSocketExample = () => {
  const [socket, setSocket] = useState(null);      // WebSocket 상태
  const [messages, setMessages] = useState([]);    // 수신된 메시지 리스트
  const [inputMessage, setInputMessage] = useState(''); // 서버에 보낼 메시지 입력값
  const [connected, setConnected] = useState(false);    // 연결 상태
  const wsRef = useRef(null);  // WebSocket 참조

  // 클라이언트 테스트 : chrome-extension://fgponpodhbmadfljofbimhhlengambbn/index.html
  
  // 웹소켓 연결을 시도하는 함수
  const connectWebSocket = () => 
  {
    const ws = new WebSocket('ws://웹소켓 서버 주소'); // 여기에 실제 WebSocket 주소 입력
    wsRef.current = ws;

    // 연결 시 호출되는 함수
    ws.onopen = () => {
      setConnected(true);
      console.log('WebSocket 연결 성공');
    };

    // 서버로부터 메시지를 받았을 때 호출되는 함수
    ws.onmessage = (e) => {
      console.log(e);
      /*
      서버로부터 메시지를 받을 때마다 메시지 리스트 업데이트
      ...prevMessages : prevMessages 리스트를 복사한다는 뜻 
      (즉, 리스트는 기존 prevMessages 리스트 + 새로 수신받은 receivedMessage로 업데이트 )
      */
      const receivedMessage = e.data;
      setMessages((prevMessages) => [...prevMessages, receivedMessage]);
    };

    // 에러 발생 시 호출되는 함수
    ws.onerror = (e) => {
      console.log(`WebSocket 에러: ${e.message}`);
    };

    // 연결이 끊기면 호출되는 함수
    ws.onclose = (e) => {
      setConnected(false);
      console.log('WebSocket 연결 종료');
    };

    setSocket(ws);
  };

  // WebSocket 연결 해제
  const disconnectWebSocket = () => 
  {
    if (wsRef.current) {
      wsRef.current.close();
    }
  };

  // 연결된 웹소켓으로 메시지를 보내는 함수
  const sendMessage = () => {
    if (socket && connected) {
      console.log(`send`);
      socket.send(inputMessage);
      setInputMessage(''); // 메시지 전송 후 입력값 초기화
    }
  };

  // 화면
  return (
    <View style={styles.container}>
    
    	/*
        	연결을 시도하는 버튼
            -터치 시 연결 시도 함수 호출
            -연결 상태를 텍스트로 표시
        */ 
      <Button title={connected ? "Disconnect" : "Connect"} onPress={connected ? disconnectWebSocket : connectWebSocket} />
        
        /*
        connected가 true인 경우 (웹소켓 서버와 연결된 경우)
        -서버로 보낼 메시지를 작성할 TextInput 컴포넌트를 보여줌 (inputMessage 저장)
        -서버로 메시지를 보내는 버튼 컴포넌트를 보여줌 (sendMessage 호출)
        */
      {connected && (
        <View style={styles.messageInputContainer}>
          <TextInput
            style={styles.textInput}
            placeholder="Enter message"
            value={inputMessage}
            onChangeText={setInputMessage}
          />
          <Button title="Send" onPress={sendMessage} />
        </View>
      )}
      
      /*
      서버로부터 받은 메시지를 표시하는 컴포넌트
      - message.map : message 리스트 내용물을 훑는 함수
      - message 리스트에 있는 String들을 Text로 표시
      */
      <ScrollView style={styles.messageContainer}>
        {messages.map((message, index) => (
          <Text key={index} style={styles.message}>{message}</Text>
        ))}
      </ScrollView>

    </View>
  );
};

// 스타일 코드
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#fff',
  },
  messageInputContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    marginVertical: 20,
  },
  textInput: {
    flex: 1,
    borderColor: '#ccc',
    borderWidth: 1,
    padding: 10,
    marginRight: 10,
  },
  messageContainer: {
    flex: 1,
  },
  message: {
    backgroundColor: '#f4f4f4',
    padding: 10,
    marginBottom: 10,
    borderRadius: 5,
  },
});

export default WebSocketExample;

현재 구현

-연결 후 "quiz:숫자"를 서버에 메시지로 보내면, 숫자에 해당하는 개수 만큼의 문제를 json 형태로 클라이언트에 다시 보내줌.
-서버 응답은 리스트 형태이며, 개별 요소의 키값은 기획서에 작성된 항목 이름을 사용

profile
무럭무럭 자라나는 중

0개의 댓글