質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Webサーバー

Webサーバーとは、HTTPリクエストに応じて、クライアントに情報を提供するシステムです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

0回答

851閲覧

React Native + Pusher + PHPでチャット機能の実装時に1回送信する度に複数の受信が返ってくる

ckuma69c

総合スコア0

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Webサーバー

Webサーバーとは、HTTPリクエストに応じて、クライアントに情報を提供するシステムです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2021/01/05 20:26

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に関しては複数回受信されているからだと思います。

以上となります。
よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問