React Native + Pusher + PHPでチャット機能の実装時に1回送信する度に複数の受信が返ってくる
開発環境:React Native(Expo) / Mac
現在React Native + Pusher + PHPでチャット機能の実装をしております。
何となくリアルタイム更新は上手くいっているように見えるものの
チャット画面に入る度、メッセージを送信する度にchatChannel.bindへの
サーバーからの受信数が増えていっている事象が発生しています。
またPusherのコネクション総数もMAXにいっている状況です。
予想なんですが
const chatChannel = pusher.subscribe(filenm);
が何度も呼ばれているのもログ出力をして確認したので
1クライアントでも複数のコネクションが生成されてしまっており
1回のメッセージ送信で複数の受信をしてしまうのではないかなとも思っております。
サーバー側へはチャットの情報一式を送りJSONで吐き出させております。
そして受信時にはチャット情報全てが来てuseStateのsetMessageへ突っ込んでおります。
この1回送信する度に複数回受信してしまう事象を解消する術を教えて頂きたしです。
発生している問題・エラーメッセージ
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
該当のソースコード
import React, { useState, useCallback, useEffect } from 'react'; import { StyleSheet, View } from 'react-native'; import { Appbar } from 'react-native-paper'; import { LinearGradient } from 'expo-linear-gradient'; import { useNavigation } from '@react-navigation/native'; import { GiftedChat } from 'react-native-gifted-chat'; import Pusher from 'pusher-js/react-native'; import { load, itfUserInfo } from './model/PROFSTOREModel'; import { CommonSetting } from './common/commonVal'; import axios from 'axios'; import { commonStyles } from './common/TLCommonStyle'; interface pusherConfigType { appId: string, key: string, secret: string, cluster: string, useTLS: boolean, restServer: string } //ユーザー情報定義 interface User { _id: string, name: string, avatar: string, } //メッセージ情報定義 interface IMessage { _id: number, text: string, createdAt: Date, user: User, } //メッセージ export const GroupChatScreen = ({route}:{route:any}) => { const pusherConfig: pusherConfigType = { appId: "xxxxxx", key: "xxxxxxxx", secret: "xxxxxxxxx", cluster: "ap3", useTLS: true, restServer:"http://xxxxxxxxxx/sample" } const { filenm } = route.params; const navigation = useNavigation(); //プロフィールへ飛ぶ const onPressProf = (usr: User) => { // console.log(usr._id); console.log('****************************'); navigation.navigate('ProfView',{uid: usr._id, scid: 'TL301'}); } //メッセージを格納する const [messages , setMessages] = useState<IMessage[]>([]); //ユーザー情報 const [userInfo, setUserInfo] = useState<itfUserInfo>(); //性別情報 const [ sex, setSex ] = useState(''); const [count, setConst] = useState(0); //************************************** //======= pusher受信処理 ========= //Pusherインスタンス初期化 Pusher.log = function(msg) { console.log('接続情報'); console.log(msg); }; const pusher = new Pusher(pusherConfig.key, pusherConfig); // console.log('Cnannel登録'); const chatChannel = pusher.subscribe(filenm); chatChannel.bind('message', (data) => { setMessages(data.message); // }); //************************************** useEffect(() => { console.log('useEffect開始'); const payload = { msg: messages, filenm: filenm, } console.log('fetch'); fetch(`http://xs593936.xsrv.jp/sample/TL301PusherMsg.php`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }) const init = async () => { const objUserInfo:itfUserInfo = await load(); setUserInfo(objUserInfo); if (objUserInfo.sex == '1') { setSex('man'); } else { setSex('woman'); } }; const unsubscribe = navigation.addListener('focus', init); return unsubscribe; },[count]); const onSend = useCallback((messages = []) => { setMessages(previousMessages => GiftedChat.append(previousMessages, messages)) console.log('count:' + count); setConst(prev => prev + 1); }, []); //前の画面に戻る const onPressBack = () => { navigation.goBack(); //チャンネルを退出 pusher.unsubscribe(filenm); } return ( <LinearGradient colors={[CommonSetting.HEADERCOLOR.FROM_COLOR, CommonSetting.HEADERCOLOR.TO_COLOR]} start={{ x: 0, y: 0}} end={{ x: 1, y: 0 }} style={{ position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, }} > <Appbar.Header style={commonStyles.headerStyle}> <Appbar.BackAction onPress={onPressBack} /> <Appbar.Content titleStyle={commonStyles.headerFont} style={commonStyles.headerTitlePositionStyle} title='メッセージ' /> </Appbar.Header> <View style={commonStyles.mainViewStyle}> <GiftedChat messages={messages} onSend={messages => onSend(messages)} renderUsernameOnMessage={true} user={{ _id: userInfo?.uid||'', name: userInfo?.uname, avatar: CommonSetting.rootSrvPath+CommonSetting.mainForderNm+CommonSetting.imgDir+CommonSetting.materialDir+sex+'1.png' }} placeholder={'ここにメッセージを入力'} dateFormat={'YYYY/MM/DD'} timeFormat={'hh:mm'} onPressAvatar={ onPressProf} // onPressAvatar={ (usr) => console.log(usr._id)} /> </View> </LinearGradient> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', } });
確認した事
chatChannel.bindがチャットに入室する度、メッセージを送信する度に
サーバー側から受信される回数が増えていることが確認取れました。
なのでErrorに関しては複数回受信されているからだと思います。
以上となります。
よろしくお願い致します。
あなたの回答
tips
プレビュー