每秒更新一次来自api的消息

时间:2018-11-07 15:38:40

标签: reactjs react-native axios state

我在我的本地移动应用程序的聊天界面中使用react-native gifted-chat,在我的组件中将挂载我从api获取给用户的消息,并在有礼物的聊天界面中呈现该消息,资优聊天还会发送到api,该api将消息保存在数据库中。现在,我想每秒更新一次消息状态,以便当其他用户也向其更新的当前用户发送消息时,我尝试使用设置间隔,但模拟器始终挂起,请问哪种是最有效的更新消息的方法除了我所做的以外的其他数组

 constructor(props) {
    super(props);
    this.state = {
        messages: []
    };
    this.checker = this.checker.bind(this);
};
checker(){
    const {params} = this.props.navigation.state;
           this.setState({loading: true});
           var bodyParameters = {
               id: params.id,
               receiver_id: params.receiver_id
           }
          /*    var config = {
               headers: {'Authorization': "Bearer " + this.state.token}
          };*/
          axios.post(
              'http://10.0.2.2:8000/api/messages',
              bodyParameters,
          //      config
          ).then((response) => {
           this.setState({loading: false});
           console.log(response);   
           var len = response.data.success?response.data.success.length:null;
           for (let i = 0; i < len; i++) {
               let row = response.data.success[i];
               console.log(row.id, row.user1.id);console.log("chat")
               this.setState(prevState => ({
                   messages: [...prevState.messages, {_id: row.id, text: row.message, 
                       createdAt: row.created_at, user: {_id: row.user1.id,name: row.user1.first_name+' '+row.user1.last_name}}],
               }), console.log(this.state.messages));
               console.log("checker");
           };
          }).catch((error) => {
           this.setState({loading: false}); 
                   console.log(error); 
                  });      
}
componentDidMount(){
this.interval = setInterval(() => this.checker(), 1000);
}
componentWillUnmount() {
        clearInterval(this.interval);
      }
componentWillMount() {
    const {params} = this.props.navigation.state;
 /*   var pusher = new Pusher('1363556f717d953dcf86', {
        cluster: 'mt1',
        forceTLS: true
      });
      var channel = pusher.subscribe('private-messages.'+ params.id);
      channel.bind('MessageSent', function(data) {
        console.log(data);
      });*/
        this.setState({loading: true});
        var bodyParameters = {
            id: params.id,
            receiver_id: params.receiver_id
        }
    /*    var config = {
            headers: {'Authorization': "Bearer " + this.state.token}
       };*/
       axios.post(
           'http://10.0.2.2:8000/api/messages',
           bodyParameters,
     //      config
       ).then((response) => {
        this.setState({loading: false});
        console.log(response);   
        var len = response.data.success?response.data.success.length:null;
        for (let i = 0; i < len; i++) {
            let row = response.data.success[i];
            console.log(row.id, row.user1.id);console.log("chat")
            this.setState(prevState => ({
                messages: [...prevState.messages, {_id: row.id, text: row.message, 
                    createdAt: row.created_at, user: {_id: row.user1.id,name: row.user1.first_name+' '+row.user1.last_name}}],
            }), console.log(this.state.messages));
            console.log("contjii");
        };
       }).catch((error) => {
        this.setState({loading: false});
            Alert.alert(
                'Error',
                 'Internal Server Error, please try again later',
                [
                  {text: 'OK'},
                ],  );    
                console.log(error); 
               });    
 /*   this.setState({
      messages: [
        {
          _id: 1,
          text: 'Hello developer',
          createdAt: new Date(),
          user: {
            _id: 1,
            name: 'React Native',
            avatar: 'https://placeimg.com/140/140/any',
          },
      //    image: 'https://facebook.github.io/react/img/logo_og.png',
          // additional custom parameters
          sent : true,
          received : true,
        },
      ],
    })*/
  }

  onSend(messages = []) {
      console.log(messages);
      const {params} = this.props.navigation.state;
      messages[0].sent = true;
    var bodyParameters = {
        id: params.id,
        receiver_id: params.receiver_id,
        message: messages[0].text
    }
/*    var config = {
        headers: {'Authorization': "Bearer " + this.state.token}
   };*/
   axios.post(
       'http://10.0.2.2:8000/api/sendMessage',
       bodyParameters,
 //      config
   ).then((response) => {
    this.setState({loading: false});
    console.log(response);   

   }).catch((error) => {
    this.setState({loading: false});
        Alert.alert(
            'Error',
             'Internal Server Error, please try again later',
            [
              {text: 'OK'},
            ],  );    
            console.log(error); 
           }); 
      this.setState(previousState => ({
      messages: GiftedChat.append(previousState.messages, messages),
    }));  
  }
render() {
    const {params} = this.props.navigation.state;
    return (
<GiftedChat
        messages={this.state.messages}
       //  inverted={false}
        onSend={messages => this.onSend(messages)}
        user={{
          _id: params.id,
        }}
      />
 );
 }

2 个答案:

答案 0 :(得分:1)

处理此问题的最有效方法是使用Web套接字协议,该协议将从服务器向UI客户端发送通知。很难举一个例子,因为我们不知道您的服务器堆栈,但是在.Net world中像SignalR这样的东西会很完美。

这里的前提是,当新消息可用时,服务器将不通知服务器每秒发送新消息,而是通知客户端。这样,您将节省大量资源。

答案 1 :(得分:1)

代码的问题是setInterval不断发送API调用,而不关心先前的调用是否返回。 这使服务器上的许多请求立即排队。要解决此问题,您应该等待API响应之后再进行下一个API调用。