๐Ÿ“ฑ Cross Platform/React Native

[React Native] ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…์•ฑ ๋งŒ๋“ค์–ด๋ณด๊ธฐ 2 - Websocket ์ด์šฉํ•˜์—ฌ ํ”„๋ก ํŠธ ๊ตฌํ˜„ํ•˜๊ธฐ (Build a real-time chatapp 1 - Implement frontend with websocket)

Fomagran ๐Ÿ’ป 2022. 7. 28. 07:47
728x90
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š” Foma ์ž…๋‹ˆ๋‹ค.

 

์ง€๋‚œ ๊ธ€์— Node.js๋กœ ์›น์†Œ์ผ“ ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ–ˆ๋Š”๋ฐ์š”.

 

์˜ค๋Š˜์€ React Native์—์„œ ํ•ด๋‹น ์„œ๋ฒ„๋ฅผ ์ด์šฉํ•˜์—ฌ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ฑ„ํŒ…์„ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ฒŒ์š”~

 

(ํ™˜๊ฒฝ์€ React Native CLI + Typescript ์ž…๋‹ˆ๋‹ค.)


Tutorial

 


Install

 

react-native-device-info

 

React Native์—์„œ ๋””๋ฐ”์ด์Šค ์•„์ด๋””๋ฅผ ์•Œ์•„๋‚ด๊ธฐ ์œ„ํ•œ ๋ชจ๋“ˆ

 

npm install react-native-device-info@8.4.5

Preview

 


Model

 

Message.ts

 

interface Message {
  user: string;
  message: string;
}

Set state

 

1. serverState 

 

์„œ๋ฒ„์˜ ์ƒํƒœ๋ฅผ ์ €์žฅ

 

2. messageText

 

์ธํ’‹์ฐฝ์— ์ž…๋ ฅ๋˜๋Š” ๋ฉ”์„ธ์ง€์˜ ์ƒํƒœ๋ฅผ ์ €์žฅ

 

3. serverMessages

 

์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜จ ๋ฉ”์‹œ์ง€๋“ค์˜ ์ƒํƒœ๋ฅผ ์ €์žฅ

 

const ChatScreen = () => {
  const [serverState, setServerState] = useState('Loading...');
  const [messageText, setMessageText] = useState('');
  const [serverMessages, setServerMessages] = useState([]);
  ...

Set variables

 

์œ„์—์„œ ์„ค์น˜ํ•œ react-native-device-info์—์„œ getUniqueId๋ฅผ import ํ•ฉ๋‹ˆ๋‹ค.

 

import {getUniqueId} from 'react-native-device-info';

 

๋””๋ฐ”์ด์Šค ์•„์ด๋””๋ฅผ userId๋กœ ์ €์žฅํ•ด ์ค๋‹ˆ๋‹ค.

 

  let userId = getUniqueId();

 

์„œ๋ฒ„์— ๋ฉ”์„ธ์ง€๋“ค์„ ๋ฐ›์•„์˜ฌ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

const serverMessagesList: Message[] = [];

Set websocket methods

 

webSocket์„ useRef๋กœ ์ €์žฅํ•ด ์ค๋‹ˆ๋‹ค.

 

  const webSocket = useRef(null);

 

useEffect๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›น์†Œ์ผ“ ์ธ์Šคํ„ด์Šค๋ฅผ ๋กœ์ปฌ ํ˜ธ์ŠคํŠธ ์•„์ดํ”ผ์™€ ํ•จ๊ป˜ ์ƒ์„ฑํ•ด ์ค๋‹ˆ๋‹ค.

 

  useEffect(() => {
    webSocket.current = new WebSocket(`ws://๋กœ์ปฌํ˜ธ์ŠคํŠธ์•„์ดํ”ผ`);
    ...

 

์„œ๋ฒ„๊ฐ€ ์—ฐ๊ฒฐ๋˜์—ˆ์„ ๋•Œ ์„œ๋ฒ„์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•ด ์ค๋‹ˆ๋‹ค.

 

    webSocket.current.onopen = () => {
      setServerState('Connected to the server');
    };

 

์„œ๋ฒ„์—์„œ ์–ด๋–ค ๋ฉ”์„ธ์ง€๊ฐ€ ์™”์„ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์‹ฑํ•˜๊ณ  severMessageList์— ๋„ฃ์€ ๋’ค ์„œ๋ฒ„ ๋ฉ”์„ธ์ง€์˜ ์ƒํƒœ์— ์ถ”๊ฐ€ํ•ด ๋ณ€๊ฒฝํ•ด ์ค๋‹ˆ๋‹ค.

 

    webSocket.current.onmessage = e => {
      let parse = JSON.parse(e.data);
      serverMessagesList.push(parse);
      setServerMessages([...serverMessagesList]);
    };

 

์„œ๋ฒ„์—์„œ ์–ด๋–ค ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์„œ๋ฒ„์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•ด ์ค๋‹ˆ๋‹ค.

 

    webSocket.current.onerror = e => {
      setServerState(e.message);
    };

 

์„œ๋ฒ„๊ฐ€ ๋‹ซํ˜”์„ ๋•Œ๋„ ์„œ๋ฒ„์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•ด ์ค๋‹ˆ๋‹ค.

 

    webSocket.current.onclose = e => {
      setServerState('Disconnected. Check internet or server.');
    };

 

๋งˆ์ง€๋ง‰์œผ๋กœ useEffect์— ์„œ๋ฒ„๋ฅผ ๋‹ซ๋Š” ๊ฒƒ์„ ๋ฆฌํ„ดํ•ด ์ค๋‹ˆ๋‹ค.

 

  return () => {
      webSocket.current.close();
    };
  }, []);

Send a message

 

์•„๋ž˜์™€ ๊ฐ™์ด JSON์œผ๋กœ ๋œ ๊ฐ์ฒด๋ฅผ ๋ฌธ์žํ™” ์‹œ์ผœ์„œ ์„œ๋ฒ„์— ๋ณด๋‚ด์ค๋‹ˆ๋‹ค.

 

  const sendMessage = () => {
    let str = JSON.stringify({user: userId, message: messageText});
    webSocket.current.send(str);
    setMessageText('');
  };

View

 

์•„๋ž˜์™€ ๊ฐ™์ด ๋ทฐ๋ฅผ ๋ ˆ์ด์•„์›ƒ ํ•ด์ค๋‹ˆ๋‹ค.

 

  return (
    <View>
      <Text>{serverState}</Text>
      <View
        style={{
          padding: 5,
          flexGrow: 1,
        }}>
        <FlatList
          style={styles.list}
          contentContainerStyle={{paddingBottom: 50}}
          data={serverMessages}
          keyExtractor={item => item.id}
          renderItem={({item}) =>
            item.user == userId ? (
              <Text style={styles.myChat}>{item.message}</Text>
            ) : (
              <Text style={styles.otherChat}>{item.message}</Text>
            )
          }
        />
      </View>
      <View style={styles.bottomContainer}>
        <TextInput
          style={styles.input}
          placeholder={'Add Message'}
          onChangeText={text => {
            setMessageText(text);
          }}
          value={messageText}></TextInput>
        <Pressable onPress={sendMessage} disabled={messageText == ''}>
          <Text style={styles.send}>Send</Text>
        </Pressable>
      </View>
    </View>
  );
};

Source Code

 

 

GitHub - fomagran/ChattingAppFullStack

Contribute to fomagran/ChattingAppFullStack development by creating an account on GitHub.

github.com

 

728x90
๋ฐ˜์‘ํ˜•