Search code examples
javascriptphpwebrtcopentok

openTok - publishing to one session - and subscribing to another


JS and PHP

every user publishes - and can subscribe to different users streams it is a one way subscription - the subscriber sees the publisher and not other members of the group. The publisher does not see those who subscribed to him.

my logic: 1. everyone is publishing - session.on - is not called 2. when subscribing - i change the sessionId and the token - to the channel the user subscribed to (can i do that?) that part does not seem to work - i get: "session is undefined"

can i change sessionId and token midway like i have done?

(each user gets his own token for each session through the PHP SDK)


Solution

  • There's actually no need to have more than one session. The problem can be boiled down to the fact that each client should publish a stream, and each client should be able to select and subscribe to any one stream from other clients. Logically, a session is already like a group of streams, so there's no need to create more than one.

    I have an example solution for you. In this solution, the PHP SDK just needs to create one token for each client in the session and there's no special logic on the server side. For now, I've hard-coded one token into the script, and it will work fine, just open the same page in several windows/tabs. Each stream can be selected using its streamId. In your application you may want to add unique token data for each client using the PHP SDK and then read that token data using the stream.connection.data property to present a more user friendly identifier of each stream (I've marked where this would go in the code with a TODO comment).

    Example:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>JS Bin</title>
      <script src='//static.opentok.com/webrtc/v2.2/js/opentok.min.js'></script>
      <script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
    </head>
    <body>
    
      <!-- Publisher placeholder -->
      <div id="publisher"></div>
    
      <!-- Stream selector interface -->
      <div id="streams"></div>
    
      <!-- Subscriber (only one) -->
      <div id="subscriber"></div>
    
      <script>
        // This data is generated by the server
        var sessionId = '2_MX44NTQ1MTF-fjE0MTU4ODc5NTE4ODV-SEN3dXBPYkFTbkFkZ3cwN3BDckJ1VDJNfn4',
            apiKey = '854511',
            token = 'T1==cGFydG5lcl9pZD04NTQ1MTEmc2lnPWE1YzBiOTA0ODcyZDQxNjRjNTc4YTI4MGUwZjI4ODNiYjU4N2Q3YmM6cm9sZT1wdWJsaXNoZXImc2Vzc2lvbl9pZD0yX01YNDROVFExTVRGLWZqRTBNVFU0T0RjNU5URTRPRFYtU0VOM2RYQlBZa0ZUYmtGa1ozY3dOM0JEY2tKMVZESk5mbjQmY3JlYXRlX3RpbWU9MTQxNTg4ODY4MSZub25jZT0wLjMwMTMwMjMxMzY2ODA4NzkmZXhwaXJlX3RpbWU9MTQxODQ3OTk0MA==';
      </script>
      <script>
        var session = OT.initSession(apiKey, sessionId),
            puslisher = OT.initPublisher('publisher'),
            streams = {},
            subscriber;
    
        session.on({
          'sessionConnected': function(event) {
            // each client publishes
            session.publish(publisher);
          },
          'streamCreated': function(event) {
            // create a button to select the stream
            // TODO: use connection data from token for a friendlier description of the stream
            $('<button class="stream stream-'+event.stream.streamId+'">Stream'+event.stream.streamId+'</button>').appendTo('#streams');
    
            // store the stream object for later use
            streams[event.stream.streamId] = event.stream;
          },
          'streamDestroyed': function(event) {
            // remove the button for the stream that was destroyed
            $('#streams .stream-'+event.stream.streamId).remove();
    
            // remove the stream object from the storage
            delete streams[event.stream.streamId];
          }
        });
    
        var streamSelected = function(event) {
          // subscribe to the selected stream
          var streamId = extractStreamId(event.target);
          if (subscriber) {
            session.unsubscribe(subscriber);
          }
          subscriber = session.subscribe(streams[streamId], 'subscriber');
          subscriber.on('destroyed', function() { subscriber = false; });
    
          // disable the button and enable all others
          $('#streams button').prop('disabled', false);
          $(event.target).prop('disabled', true);
        };
    
        var extractStreamId = function (element) {
          var classes = element.className.split(' '),
              streamId;
          classes.forEach(function(classStr) {
            if (classStr.indexOf('stream-') === 0) {
              streamId = classStr.slice(7);
            }
          });
          return streamId;
        };
    
        $(document).ready(function() {
          $('#streams').on('click', '.stream', streamSelected);
          session.connect(token);
        });
    
      </script>
    </body>
    </html>
    

    A live page for this example is available on JSBin: http://jsbin.com/duxowa/10/edit

    Note: The token may be expired if you are viewing this much later than my post. Use your own apiKey, sessionId, and token from the Dashboard or using a Server SDK if that is the case.