0

I'm intermittently seeing multiple copies of the same subscriber intermittently, but not the publisher and can't work out why...or, annoyingly, how to reproduce the problem.

I have an Laravel 5.4 api using https://github.com/tomcorbett/opentok-laravel to generate session and token, which seems to work fine (has same problem when using manual/static session and token). The Angular 4 client code is below - note that I have inserted some extra code to try to prevent multiple subscriptions to the same user/multiple publications (although not sue there's any evidence of the latter) but doesn't seem to be working - any thoughts on how to prevent multiple subscriptions to the same user gratefully received.

setupOpentok() {
        let sessionId: string = this.club.opentok_session_id; 
        //TODO - change rather inelegant way of getting token
        let token: string = this.user.pivot.opentok_token;

        this.openTokSession = OT.initSession(myGlobals.opentokApiKey, sessionId);

        this.openTokSession.on('streamCreated', (event: any) => {
                //Added code to only add stream to appropriate div if this user not already subscribed to
                let alreadySubscribed: boolean = false;
                for (let userId of this.subscribers) {
                    if (userId === event.stream.connection.data) {
                        alreadySubscribed = true;
                        break; //we have our token so leave loop
                    }  
                }
                if(!alreadySubscribed) {
                    var subscriberProperties = {
                        insertMode: 'append', 
                        width: '100%',
                        height: '100%'
                    };
                    //create a child of vidFeeds with unique id using userId from token
                    var subscriberDiv = document.createElement('div');
                    subscriberDiv.id = 'subscriberDiv_' + event.stream.connection.data;
                    var vidFeedsDiv = document.getElementById('vidFeeds');
                    vidFeedsDiv.appendChild(subscriberDiv);
                    var subscriber = this.openTokSession.subscribe(event.stream,
                        subscriberDiv.id,
                        subscriberProperties,
                        (error: any) => {
                            if (error) {
                                console.log(error);
                            } else {
                                this.subscribers.push(Number(event.stream.connection.data));
                            }
                        }
                    );

                    subscriber.element.style.display = 'inline-block';
                }
            });

        this.openTokSession.on("sessionDisconnected", (event:any) => {
            if(typeof(event.stream) !== 'undefined') {
                console.log("Stream disconnected - " + event.stream.connection.data);
                let counter: number = 0;
                let disconnectedId: number;
                for (let userId of this.subscribers) {
                    if (userId === event.stream.connection.data) {
                        disconnectedId = counter;
                        break; 
                    } 
                    counter++;
                }
                this.subscribers.splice(counter, 1); //clearing reference so we can reload when it reconnects
            }
        });

        this.openTokSession.on("streamDestroyed", (event:any) => {
            if(typeof(event.stream) !== 'undefined') {
                console.log("Stream destroyed - " + event.stream.connection.data);
                let counter: number = 0;
                let disconnectedId: number;
                for (let userId of this.subscribers) {
                    if (userId === event.stream.connection.data) {
                        disconnectedId = counter;
                        break; 
                    } 
                    counter++;
                }
                this.subscribers.splice(counter, 1); //clearing reference so we can reload when it reconnects
            }
        });

        let nickNameToShow = this.auth.userProfile.nickname;
        this.openTokSession.connect(token, (error: any) => {
                if(!this.publisher){  //trying to prevent multiple copies of video streams - there should only be one publisher per session
                    //create a child of vidFeeds with unique id using userId from token
                    var publisherDiv = document.createElement('div');
                    publisherDiv.id = 'publisherDiv';
                    var vidFeedsDiv = document.getElementById('vidFeeds');
                    vidFeedsDiv.appendChild(publisherDiv);
                    this.publisher = OT.initPublisher(publisherDiv.id, {
                        name: nickNameToShow,
                        insertMode: 'append',
                        width: '100%',
                        height: '100%'
                        }
                    );
                    //that.getUserDataForVideo(that.auth.userProfile.id, false); //it's a publisher
                    this.publisher.element.style.display = 'inline-block';
                    this.openTokSession.publish(this.publisher);    
                }
            });
    }
theotherdy
  • 715
  • 1
  • 7
  • 22

1 Answers1

0

Sorry for wasting anyone's time, but thought I'd post what finally worked for me to overcome this problem of ending up with multiple copies of of the same subscriber:

this.openTokSession.on('streamCreated', (event: any) => {
                //only add stream to appropriate div if this user not already subscribed to
                let alreadySubscribed: boolean = false;
                //before reconnecting check whether there's already a subscriber with same connection Id
                var subscribers = this.openTokSession.getSubscribersForStream(event.stream);
                for (let subscriber of subscribers) {
                    if(subscriber.stream.connection.connectionId === event.stream.connection.connectionId){
                        alreadySubscribed=true;    
                    }
                }
                if(!alreadySubscribed) {
                    var subscriberProperties = {
                        insertMode: 'append', 
                        width: '100%',
                        height: '100%'
                    };
                    //create a child of vidFeeds with unique id using userId from token
                    var subscriberDiv = document.createElement('div');
                    subscriberDiv.id = 'subscriberDiv_' + event.stream.connection.data;
                    var vidFeedsDiv = document.getElementById('vidFeeds');
                    vidFeedsDiv.appendChild(subscriberDiv);
                    var subscriber = this.openTokSession.subscribe(event.stream,
                        subscriberDiv.id,
                        subscriberProperties,
                        (error: any) => {
                            if (error) {
                                console.log(error);
                            } else {

                            }
                        }
                    );
                }
            });
theotherdy
  • 715
  • 1
  • 7
  • 22
  • I can't tell the difference between this code and the code in your original question. – Adam Ullman Jul 17 '17 at 06:43
  • But you shouldn't need to check if you have already subscribed. 'streamCreated' should only fire once for each stream. If you are subscribing multiple times then I would guess that this code is getting called multiple times for some reason. It's hard to tell without the rest of the context of your application but is it possible that setupOpentok() is getting called multiple times? – Adam Ullman Jul 17 '17 at 06:47
  • Thanks @AdamUllman. The key difference is in using this.openTokSession.getSubscribersForStream(event.stream); to get list of subscribers against which to check before (re-)subscribing. I don't *think* it's being called multiple times, the problem is when publishers refresh their page/navigate away from the page which publishes, I can't seem to force the subscription to disappear properly... – theotherdy Jul 17 '17 at 10:29
  • Hi @AdamUllman I am having issue could you help me [here](https://stackoverflow.com/questions/62607682/while-trying-to-have-group-video-chat-using-the-opentok-multiple-stream-with-nul) – Kamal Pandey Jun 28 '20 at 10:45