从AWS SQS获取数据并等待呈现ReactJs

时间:2016-08-17 14:23:55

标签: amazon-web-services reactjs amazon-sqs

所以我们遇到的问题是我们向 SQS 发送请求,然后在接收消息上它没有返回任何数据。

为了尝试解决这个问题,我们投入了一个while循环来轮询一段时间;然而,这真的不起作用,因为我们不能在民意调查之间睡觉,似乎它们都是异步发生的。

我之所以这么说是因为如果值确实被返回(大约50%的时间发生),它会重新呈现下一个屏幕,因为剩余的上限和轮询永远不会设置为false。请有人帮助我们!

render() {
    return (
      <Navigator
          renderScene={this.renderScene.bind(this)}
          navigator={this.props.navigator}
          navigationBar={
            <Navigator.NavigationBar style={{backgroundColor: 'transparent'}}
               routeMapper={NavigationBarRouteMapper} />
          } />
    );
  }

renderScene() {
    return (
      <View style={styles.container}>
        <StatusBar barStyle="light-content" hidden={true}/>
        <View style={styles.topContainer}>
          <View style={styles.bannerContainer}>
            <View style={{flexDirection: 'column', flex: 1, justifyContent: 'center', alignItems: 'center'}}>
              <Image style={styles.mark} source={require('./yb.png')} />
            </View>
          </View>
          <View style={styles.credentialContainer}>
            <View style={styles.inputContainer}>
              <Icon style={styles.inputPassword} name="person" size={28} color="#FFCD00" />
                  <View style={{flexDirection: 'row', flex: 1, marginLeft: 2, marginRight: 2, borderBottomColor: '#e0e0e0', borderBottomWidth: 2}}>
                    <TextInput
                        style={styles.input}
                        placeholder="Username"
                        autoCorrect={false}
                        placeholderTextColor="#e0e0e0"
                        onChangeText={(text) => this.setState({username: text})}
                        value={this.state.username}>
                    </TextInput>
                  </View>
                </View>

                <View style={styles.inputContainer}>
                  <Icon style={styles.inputPassword} name="lock" size={28} color="#FFCD00" />
                    <View style={{flexDirection: 'row', flex: 1, marginLeft: 2, marginRight: 2, borderBottomColor: '#e0e0e0', borderBottomWidth: 2}}>
                    <TextInput
                        style={styles.input}
                        placeholder="Password"
                        autoCorrect={false}
                        secureTextEntry={true}
                        placeholderTextColor="#e0e0e0"
                        onChangeText={(text) => this.setState({password: text})}
                        value={this.state.password}>
                      </TextInput>
                    </View>
                </View>
                <TouchableOpacity style={styles.forgotContainer}>
                    <Text style={{color: '#e0e0e0'}}>Forgot Password</Text>
                </TouchableOpacity>
            </View>
        </View>

        <TouchableHighlight
          underlayColor="#D6AB00"
          onPress={this.login}
          style={styles.signInButtonContainer}>
          <Text style={styles.signInText}>Sign In</Text>
        </TouchableHighlight>    
      </View>
    );
  }

  login() {
   var polling = true;
    if(this.state.username.length == 0){
      Alert.alert("Error","No email entered");
    }
    else if(this.state.password.length == 0){
      Alert.alert("Error","No password entered");
    }
    else
    {    
    info.username = this.state.username;
    info.password = this.state.password;

    AWS.sendMessage('****',JSON.stringify(info), (error,result) =>{
      if(error != null) console.log("Error Occured Attempting to Send A Message")
      else {
        var cap=0;
        while(cap <= 30 && polling){
        cap = cap+1;

          AWS.receiveMessages('****'+info.username, (error, result) =>{
            if(error != null) console.log("Error");
            else{
              if(result){
                try{
                    polling = false;
                    if(result[0] == "[]")
                    {
                      console.log(result[0]);
                      console.log(typeof result[0]);
                      Alert.alert("Error","Username/Password Incorrect");
                    }
                    else
                    {
                      console.log(result[0]);
                      console.log(typeof result[0]);
                      var temp = JSON.parse(result[0]);
                      this.props.navigator.replace({
                        id: 'MapIOS',
                        data: {
                          username: info.username,
                          ofAge: temp[0].ofAge,
                          uid: temp[0].u_ID
                        },
                      });
                    }
                }
                catch(e){
                  console.log(e);
                }
              }
              AWS.deleteMessage('***'+info.username, result[1], (error) => {
               if(error != null) console.log("Error");
              });
            }
          });
        }
        return
      }
    });
  }
  } 
};

2 个答案:

答案 0 :(得分:1)

在使用SQS时需要牢记的一些重要事实:

  1. SQS不是“先进先出”。可能无法以与放入队列相同的顺序接收消息。因此,如果您添加消息“1”然后添加“2”,您可能会收到“2”然后“1”。
  2. 即使邮件在队列中,当您致电ReceiveMessage时,也可能无法收到消息。
  3. 您可能会多次收到相同的讯息。例如,如果您向队列添加了消息“1”,则稍后可能会再次返回“1”然后再返回“1”。因此,您需要确保消息处理是幂等的并且重复安全。
  4. 所有这些都是由于SQS是分布式和冗余的。它保证您将收到您的消息,但它不保证订单或消息的接收次数。

    <强>更新

    这是我原来的答案,但我不认为这是代码的主要问题。我将它留在这里,因为我认为它仍然是有价值的信息。

答案 1 :(得分:1)

问题是您在循环中调用AWS.ReceiveMessage

当您拨打AWS.ReceiveMessage时,该呼叫是异步的。意思是,它会立即返回。它不会等待你的回调被调用。因此,在调用任何回调之前,您的循环可能会耗尽。

尝试从回调函数中设置polling变量不是一种安全的方式来保护&#34;你的回调。

您需要对功能进行重组,以便在从第一个AWS.ReceiveMessage调用回调之后才会发生第二个AWS.ReceiveMessage

一般来说,不要循环。