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 형태로 클라이언트에 다시 보내줌.
-서버 응답은 리스트 형태이며, 개별 요소의 키값은 기획서에 작성된 항목 이름을 사용

