callstack/react-native-opentok

Subscriber doesn't re-connect to stream if subscriber connects, disconnects and reconnects.

Opened this issue · 5 comments

I have a pretty basic tokbox set up, and I'm having two issues with the Subscriber component:
screen shot 2018-04-12 at 11 35 43 am

Issue 1: I noticed that onSubscribeStop is never fired when the subscriber I'm testing with ends their connection to the stream. I can still detect the end of the subscriber feed by using this:

    OpenTok.on(OpenTok.events.ON_SESSION_STREAM_DESTROYED, () => {
      this.setState({ subscriberStarted: false });
    });

Issue 2: If the Subscriber disconnects from the sessions and then rejoins, onSubscribeStart isn't triggered and I never receive that subscribers video/audio feed again. I'm not seeing any console errors in my debugger. It's almost as if the Subscriber has become bricked/unable to be used after a disconnection event.

I solved this problem in an extremely hacky/ugly way by re-rendering a 'fresh' Subscriber component any time I received that ON_SESSION_STREM_DESTROYED event.

Is there something I am missing with how the Subscriber works?

Hey @jonathanwmaddison ! Did you solve this problem with that implementation? Because I tried but it doesn't work to me.

@mafranceschi I never found a clean way to do it, I'm currently using the official opentok sdk which didn't have this problem.

To re-render the subscriber, you can save a refreshed version to your local component state any time there is a disconnect. That way the next connection can connect to the stream on the new subscriber component.

@jonathanwmaddison could you share your code to demonstrate how to re-render subscriber component thanks

hi guys , here is my solution after researched

import React, { Component } from "react";
import { StyleSheet, Text, View, TouchableOpacity,Dimensions } from "react-native";
import OpenTok, { Subscriber } from 'react-native-opentok';
import TimerMixin from 'react-timer-mixin';
const sessionId = 'YOUR_SESSION_ID_HERE';
const token = 'YOUR_TOKEN_HERE';

export default class App extends Component<{}> {
  constructor(props){
    super(props);
    this.state = {
      isVisible: true,
    };
  }
  async componentWillMount() {
    await OpenTok.connect(sessionId, token);
    OpenTok.on(OpenTok.events.ON_SIGNAL_RECEIVED, e => console.log(e));
    
  }

  startTimer(){
    this.timer =  TimerMixin.setTimeout(() => {
      console.log('this is timeout this.setState({isVisible: true})')
      this.setState({isVisible: true});
    }, 1000);
  }
  
  ref: Ref<typeof Viewer>;
  

  render() {
    return (
      <View style={styles.container}>
      {
        this.state.isVisible && <Subscriber
        mute={true}
        sessionId={sessionId}
        onSubscribeStart={() => { 
          this.setState({isVisible: true});
          console.log('Watching started');
        }}
        onSubscribeStop={() => { 
          this.setState({isVisible: false});
          this.startTimer();
          console.log('onSubscribeStop');
        }}
        onSubscribeError={() => { 
          
          this.setState({isVisible: false});
          this.startTimer();
          console.log('onSubscribeError');
        }}
        style={{backgroundColor: 'black', flex:1  }}
        ref={ref => {
          this.ref = ref;
        }}
      />
      }
         
      </View>
    );
  }
  cancelAndBack(){
    OpenTok.disconnect(sessionId)
    this.props.navigation.goBack()
  }
};


const styles = StyleSheet.create({
  container: {
    flex: 1
  },

});

It seems to be a bug with native SDKs, I am using the official library and facing the same issue.