React Native 实现chat 即时聊天(第1天)

本文介绍了一个简单的React应用,用于实现一个最多支持1000人在线的即时聊天功能。作者首先采用定时轮询HTTP请求的方式获取聊天数据,然后计划升级到WebSocket以实现更实时的通信。代码示例展示了如何创建聊天界面,包括输入框、消息列表和发送按钮。应用还包含了错误处理和数据加载逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

及时聊天功能渐渐的几乎成为每个APP的标配功能了,最近想给自己的APP增加即时聊天功能。本想调用一些云服务的聊天接口,看了下价格,接受不了。那就自己尝试写一个吧!我的应用场景比较简单,最多同时在线也就1000人左右。

实现思路 

  1. 前端react实现,数据发生变化界面自动变,做起来会比较简单。
  2. 第一版,定时刷新http的方式取数据即可,这种方式缺点比较多,但是目前用户量比较小的情况下,影响不大,后期换成websocket 实现。

第一版效果

代码分享

为了方便查看,服务器端请求的代码被我暂时注释,需要的自行打开注释。

/* eslint-disable prettier/prettier */
import React, {useState, useEffect} from 'react';
import {
    SafeAreaView,
    StyleSheet,
    ScrollView,
    View,
    Text,
    StatusBar,
    TextInput,
    Button,
} from 'react-native';


function MessageList(props) {
    const items = props.items;
    const receiver = props.receiver;
    const listItems = items.map((item, index) => {
            return (
                <View key={index} style={[styles.chatMessage, receiver == item.name ? styles.chatReceiver : null]}>
                    <Text style={styles.chatNameReceiver}>{item.name}</Text>
                    <Text style={styles.messageText}>{item.message}</Text>
                </View>
            );
        },
    );
    return (
        <>{listItems}</>
    );
}

const URL_SERVER = 'http://192.168.199.133:8080';

const App = () => {
    const [items, setItems] = useState([
        {name: 'boy', message: '今天晚上吃点啥?'},
        {name: 'girl', message: '我们去吃牛排吧!'},
        {name: 'boy', message: '好的,我去给小红打气。'},
        {name: 'boy', message: '你们在门口等我吧。'},
        {name: 'girl', message: '你人呢?我到门口啦'},
    ]);
    const [receiver, setReceiver] = useState('girl');
    const [value, onChangeText] = React.useState('');

    let timer;  //计时器
    useEffect(() => {
        //loadMessage();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);
    /**
     * 加载聊天信息
     */
    const loadMessage = () => {
        timer = setInterval(function () {
            //执行代码
            console.log('-----------获取数据------------');
            fetch(URL_SERVER + '/list')
                .then(function (response) {
                    return response.json();
                })
                .then(function (result) {
                    if (result.code == 0) {
                        setItems(result.data);
                    }
                });
        }, 1000);
    };

    const postMessage = () => {
        fetch(URL_SERVER+'/send', {
            method: 'POST',
            credentials: 'include',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: 'roomId=1&message=' + value + '&name=' + receiver,
        })
            .then(response => {
                if (response.ok) {
                    return response.text();
                }
                throw new Error('Network response was not ok.');
            })
            .then(responseText => {
                console.log(responseText);
            })
            .catch(e => {
                console.log(e.toString());
            });
    };

    //发送消息
    const sendMessage = (message) => {
        let newItems = JSON.parse(JSON.stringify(items));
        newItems.push({name: receiver, message: message});
        setItems(newItems);
    };
    const sendDo = () => {
        sendMessage(value);
        //postMessage();
        onChangeText('');
    };

    return (
        <>
            <StatusBar barStyle="dark-content"/>
            <SafeAreaView style={styles.mainContent}>
                <TextInput
                    style={{height: 40, borderColor: 'gray', borderWidth: 1}}
                    onChangeText={text => setReceiver(text)}
                    placeholder={'聊天人姓名'}
                    value={receiver}
                    onSubmitEditing={sendDo}
                />
                <ScrollView style={styles.chatBody}>
                    <View style={{height: 15}}></View>
                    <MessageList items={items} receiver={receiver}/>
                </ScrollView>

                <TextInput
                    style={{height: 40, borderColor: 'gray', borderWidth: 1}}
                    onChangeText={text => onChangeText(text)}
                    placeholder={'开始聊天吧'}
                    value={value}
                    onSubmitEditing={sendDo}
                />
                <Button
                    onPress={sendDo}
                    title="发送"
                    color="#841584"
                />
            </SafeAreaView>
        </>
    );
};

const styles = StyleSheet.create({
    mainContent: {
        flex: 1,
        backgroundColor: '#ededed',
    },
    chatBody: {
        flex: 1,
        padding: 10,
    },
    chatMessage: {
        position: 'relative',
        backgroundColor: '#ffffff',
        padding: 10,
        borderRadius: 10,
        alignSelf: 'flex-start',
        marginBottom: 25,
    },
    chatReceiver: {
        marginLeft: 'auto',
        backgroundColor: '#95ec69',
    },
    messageText: {
        fontSize: 16,
    },
    chatName: {
        fontSize: 12,
        position: 'absolute',
        top: -15,
        fontWeight: 'bold',
    },
    chatNameReceiver: {
        fontSize: 12,
        position: 'absolute',
        top: -18,
        fontWeight: 'bold',
        marginLeft: 'auto',
    },
    chatTimeStamp: {
        marginLeft: 10,
        fontSize: 12,
    },
});

export default App;

程序目前比较简陋,思路仅供参考。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值