title: WebSocket connection to 'ws://localhost:3434/' failed: Connection closed before receiving a handshake response
body: <p>When using the cmd to run the node server.js and launch the localhost:3434 in the web browser I am getting the error:</p>
  
  <p>in Chrome:  </p>
  
  <blockquote>
    <p>Connection closed before receiving a handshake response.</p>
  </blockquote>
  
  <p>in firefox:</p>
  
  <blockquote>
    <p>Firefox can't establish a connection to the server at ws://localhost:3434/</p>
  </blockquote>
  
  <p>Could you pls help</p>
  
  <p>server.js</p>
  
  <pre><code>var http = require('http'),
  fs = require('fs');
  
  fs.readFile('../index.html', function (err, html) {
  if (err) {
     throw err;
  }
  http.createServer(function (request, response) {
      response.writeHeader(200, { "Content-Type": "text/html" });
      response.write(html);
      response.end();
  }).listen(3434);
  });
  </code></pre>
  
  <p>index.html</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
  &lt;!--&lt;script type="text/javascript" src="../../js/adapter.js"&gt;&lt;/script&gt;--&gt;
  &lt;!--&lt;script type="text/javascript" src="../../js/webrtc.js"&gt;&lt;/script&gt;--&gt;
  &lt;title&gt;Simple WebRTC video chat&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;header&gt;
  &lt;video id="localVideo" autoplay="autoplay" muted="muted"        style="width:40%;"&gt;&lt;/video&gt;
      &lt;video id="remoteVideo" autoplay="autoplay" style="width:40%;"&gt;&lt;/video&gt;
      &lt;input type="button" id="start" onclick="start(true)" value="Start  Video"; /&gt;
  &lt;/header&gt;
  &lt;script&gt;
      var RTCPeerConnection = null;
      var getUserMedia = null;
      var attachMediaStream = null;
      var reattachMediaStream = null;
      var webrtcDetectedBrowser = null;
      var webrtcDetectedVersion = null;
  
      function trace(text) {
          // This function is used for logging.
          if (text[text.length - 1] == '\n') {
              text = text.substring(0, text.length - 1);
          }
          console.log((performance.now() / 1000).toFixed(3) + ": " + text);
      }
  
      if (navigator.mozGetUserMedia) {
          console.log("This appears to be Firefox");
  
          webrtcDetectedBrowser = "firefox";
  
          webrtcDetectedVersion =
                          parseInt(navigator.userAgent.match(/Firefox\/([0- 9]+)\./)[1]);
  
          // The RTCPeerConnection object.
          RTCPeerConnection = mozRTCPeerConnection;
  
          // The RTCSessionDescription object.
          RTCSessionDescription = mozRTCSessionDescription;
  
          // The RTCIceCandidate object.
          RTCIceCandidate = mozRTCIceCandidate;
  
          // Get UserMedia (only difference is the prefix).
          getUserMedia = navigator.mozGetUserMedia.bind(navigator);
  
          // Creates iceServer from the url for FF.
          createIceServer = function (url, username, password) {
              var iceServer = null;
              var url_parts = url.split(':');
              if (url_parts[0].indexOf('stun') === 0) {
                  // Create iceServer with stun url.
                  iceServer = { 'url': url };
              } else if (url_parts[0].indexOf('turn') === 0 &amp;&amp;
                         (url.indexOf('transport=udp') !== -1 ||
                          url.indexOf('?transport') === -1)) {
                  // Create iceServer with turn url.
                  // Ignore the transport parameter from TURN url.
                  var turn_url_parts = url.split("?");
                  iceServer = {
                      'url': turn_url_parts[0],
                      'credential': password,
                      'username': username
                  };
              }
              return iceServer;
          };
  
          // Attach a media stream to an element.
          attachMediaStream = function (element, stream) {
              console.log("Attaching media stream");
              element.mozSrcObject = stream;
              element.play();
          };
  
          reattachMediaStream = function (to, from) {
              console.log("Reattaching media stream");
              to.mozSrcObject = from.mozSrcObject;
              to.play();
          };
  
          MediaStream.prototype.getVideoTracks = function () {
              return [];
          };
  
          MediaStream.prototype.getAudioTracks = function () {
              return [];
          };
      } else if (navigator.webkitGetUserMedia) {
          console.log("This appears to be Chrome");
  
          webrtcDetectedBrowser = "chrome";
          webrtcDetectedVersion =
                     parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]);
  
          // Creates iceServer from the url for Chrome.
          createIceServer = function (url, username, password) {
              var iceServer = null;
              var url_parts = url.split(':');
              if (url_parts[0].indexOf('stun') === 0) {
                  // Create iceServer with stun url.
                  iceServer = { 'url': url };
              } else if (url_parts[0].indexOf('turn') === 0) {
                  if (webrtcDetectedVersion &lt; 28) {
                      var url_turn_parts = url.split("turn:");
                      iceServer = {
                          'url': 'turn:' + username + '@' + url_turn_parts[1],
                          'credential': password
                      };
                  } else {
                      iceServer = {
                          'url': url,
                          'credential': password,
                          'username': username
                      };
                  }
              }
              return iceServer;
          };
  
          // The RTCPeerConnection object.
          RTCPeerConnection = webkitRTCPeerConnection;
  
          // Get UserMedia (only difference is the prefix).
          // Code from Adam Barth.
          getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
  
          // Attach a media stream to an element.
          attachMediaStream = function (element, stream) {
              if (typeof element.srcObject !== 'undefined') {
                  element.srcObject = stream;
              } else if (typeof element.mozSrcObject !== 'undefined') {
                  element.mozSrcObject = stream;
              } else if (typeof element.src !== 'undefined') {
                  element.src = URL.createObjectURL(stream);
              } else {
                  console.log('Error attaching stream to element.');
              }
          };
  
          reattachMediaStream = function (to, from) {
              to.src = from.src;
          };
  
          // The representation of tracks in a stream is changed in M26.
          // Unify them for earlier Chrome versions in the coexisting period.
          if (!webkitMediaStream.prototype.getVideoTracks) {
              webkitMediaStream.prototype.getVideoTracks = function () {
                  return this.videoTracks;
              };
              webkitMediaStream.prototype.getAudioTracks = function () {
                  return this.audioTracks;
              };
          }
  
          if (!webkitRTCPeerConnection.prototype.getLocalStreams) {
              webkitRTCPeerConnection.prototype.getLocalStreams = function ()              {
                  return this.localStreams;
              };
              webkitRTCPeerConnection.prototype.getRemoteStreams = function ()     {
                  return this.remoteStreams;
              };
          }
      } else {
          console.log("Browser does not appear to be WebRTC-capable");
      }
      var localVideo;
      var remoteVideo;
      var peerConnection;
      var localStream;
      var optional = { optional: [{ DtlsSrtpKeyAgreement: true }] }
      var peerConnectionConfig = { 'iceServers': [{ 'url':    'stun:stun.services.mozilla.com' }, { 'url': 'stun:stun.l.google.com:19302' }] };
  
      navigator.getUserMedia = navigator.getUserMedia ||  navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
      window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
      window.RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.webkitRTCIceCandidate;
      window.RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription;
  
      localVideo = document.getElementById("localVideo");
      remoteVideo = document.getElementById("remoteVideo");
      serverConnection = new WebSocket('ws://localhost:3434');
      serverConnection.onmessage = gotMessageFromServer;
  
      var constraints = {
          video: true,
          audio: true,
      };
  
      if (navigator.getUserMedia) {
          navigator.getUserMedia(constraints, getUserMediaSuccess,  getUserMediaError);
      } else {
          alert('Your browser does not support getUserMedia API');
      }
      function getUserMediaSuccess(stream) {
          localStream = stream;
          localVideo.src = window.URL.createObjectURL(stream);
      }
  
      function start(isCaller) {
          peerConnection = new RTCPeerConnection(peerConnectionConfig, optional);
          peerConnection.onicecandidate = gotIceCandidate;
          peerConnection.onaddstream = gotRemoteStream;
          peerConnection.addStream(localStream);
  
          if (isCaller) {
              peerConnection.createOffer(gotDescription, createOfferError);
          }
      }
  
      function gotMessageFromServer(message) {
          if (!peerConnection) start(false);
  
          var signal = JSON.parse(message.data);
          if (signal.sdp) {
              peerConnection.setRemoteDescription(new RTCSessionDescription(signal.sdp), function () {
                  peerConnection.createAnswer(gotDescription, createAnswerError);
              });
          } else if (signal.ice) {
              peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice));
          }
      }
  
      function gotIceCandidate(event) {
          if (event.candidate != null) {
              serverConnection.send(JSON.stringify({ 'ice': event.candidate }));
          }
      }
  
      function gotDescription(description) {
          console.log('got description');
          peerConnection.setLocalDescription(description, function () {
              serverConnection.send(JSON.stringify({ 'sdp': description }));
          }, function () { console.log('set description error') });
      }
  
      function gotRemoteStream(event) {
          console.log("got remote stream");
          remoteVideo.src = window.URL.createObjectURL(event.stream);
      }
  
      // Error functions....
  
      function getUserMediaError(error) {
          console.log(error);
      }
  
      function createOfferError(error) {
          console.log(error);
      }
  
      function createAnswerError(error) {
          console.log(error);
      }
   &lt;/script&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>