title: Only works on one-to-one of which was to be many-to-many, webrtc
body: <p>I am developing a conference style application (many-to-many) for video calls <a href="http://spaceify.net/talk/" rel="nofollow">this</a> style. The code is available on GitHub but I do not have much node.js experience, hence I decided to create my own server using PHP.</p>
  
  <p>I created the server using WebSockets. It is simple - it receives messages and forwards them to all other connected clients (i.e., not the client that sent the message). Just that - nothing more; nothing less.</p>
  
  <p>But my problem is that this architecture does not allow clients to connect with more than one person, i.e., when a client tries to connect with the third person, the additional streams fail. Clients can only connect one-to-one.</p>
  
  <p>I do not know whether the error is in JavaScript or if I need to improve the server. What can I do to make it connect to all clients who join?</p>
  
  <p>See my code:</p>
  
  <p><strong>HTML</strong></p>
  
  <pre><code>&lt;script type="text/javascript" src="http://127.0.0.1/scr/js/jquery.js"&gt;&lt;/script&gt;
  </code></pre>
  
  <p><strong>JavaScript</strong></p>
  
  <pre><code>var Server = new WebSocket('ws://127.0.0.1:1805/'),
      myStream = null,
      peerConn = null,
      mediaConstraints = {
          'mandatory': {
              'OfferToReceiveAudio': true,
              'OfferToReceiveVideo': true
          }
      };
  
  
  navigator.webkitGetUserMedia({
      audio: true,
      video: true
  }, function(stream) {
      myStream = stream;
  
      $("body").append('&lt;video width="320" height="240" muted="muted" autoplay="true" src="' + window.URL.createObjectURL(stream) + '"&gt;&lt;/video&gt;');
  
      createPeerConnection();
  
      peerConn.addStream(myStream);
      peerConn.createOffer(function(sessionDescription) {
          peerConn.setLocalDescription(sessionDescription);
          console.log("Sending offer description");
          Server.send(JSON.stringify(sessionDescription));
      }, null, mediaConstraints);
  }, function() {
      console.error('Error in my stream');
  });
  
  function createPeerConnection() {
      console.log('Creating peer connection');
  
      peerConn = new webkitRTCPeerConnection({
          'iceServers': [{
              'url': 'stun:stun.l.google.com:19302'
          }, {
              'url': 'turn:107.150.19.220:3478',
              'credential': 'turnserver',
              'username': 'subrosa'
          }]
      }, {
          'optional': [{
              'DtlsSrtpKeyAgreement': 'true'
          }]
      });
  
      peerConn.onicecandidate = function(event) {
          if (event.candidate) {
              Server.send(JSON.stringify({
                  type: 'candidate',
                  label: event.candidate.sdpMLineIndex,
                  id: event.candidate.sdpMid,
                  candidate: event.candidate.candidate
              }));
          } else {
              console.error('Candidate denied');
          }
      };
      peerConn.onaddstream = function(event) {
          console.log("Adding remote strem");
          $("body").append('&lt;video width="320" height="240" autoplay="true" src="' + window.URL.createObjectURL(event.stream) + '"&gt;&lt;/video&gt;');
      };
      peerConn.onremovestream = function(event) {
          console.log("Removing remote stream");
      };
  }
  Server.addEventListener("message", function(message) {
      var msg = JSON.parse(message.data);
  
      if(!myStream) {
          console.error('Error in my stream');
      }
  
      if (msg.type === 'offer') {
          createPeerConnection();
  
          console.log('Adding local stream...');
  
          peerConn.addStream(myStream);
          peerConn.setRemoteDescription(new RTCSessionDescription(msg));
  
          console.log("Sending answer to peer.");
  
          peerConn.createAnswer(function(sessionDescription) {
              peerConn.setLocalDescription(sessionDescription);
              Server.send(JSON.stringify(sessionDescription));
          }, null, mediaConstraints);
      } else if (msg.type === 'answer') {
          peerConn.setRemoteDescription(new RTCSessionDescription(msg));
      } else if (msg.type === 'candidate') {
          var candidate = new RTCIceCandidate({
              sdpMLineIndex: msg.label,
              candidate: msg.candidate
          });
          peerConn.addIceCandidate(candidate);
      }
  }, false);
  </code></pre>