title: webSocket won't connect to IISNode
body: <p>I am developing a web server in Node.js with Express, and I want to use Socket.io for WebSockets specifically. However, the server environment that my app is being hosted in is IIS, and that cannot be changed. The IIS version is high enough that WebSockets are enabled, and iisnode v0.2.21 is installed. Express works properly, serving my pages and content, but WebSockets do not. Instead, the websocket connection is repeatedly terminated with a HTTP 200 status instead of the HTTP 101 that it is expecting, preventing the WebSockets from working. I have set permissions for the IIS_IUSRS group everywhere I can think of.</p>
  
  <p>Sometimes I get an error page, with this text:</p>
  
  <pre><code>HRESULT: 0x6d
  HTTP status: 500
  HTTP subStatus: 1013
  HTTP reason: Internal Server Error
  </code></pre>
  
  <p>I am not attempting to use SSL or Secure WebSockets yet, so the other solutions that I've found on StackOverflow do not seem to apply. </p>
  
  <p>I get errors like this on the client side:</p>
  
  <pre><code>polling-xhr.js:264 POST http://my-website/socket.io/?EIO=3&amp;transport=polling&amp;t=LnMfjZr&amp;sid=LQjLpiGwsN3K-gNPAAAA 500 (Internal Server Error)
  polling-xhr.js:264 POST http://my-website/socket.io/?EIO=3&amp;transport=polling&amp;t=LnMfjaC&amp;sid=LQjLpiGwsN3K-gNPAAAA 500 (Internal Server Error)
  websocket.js:112 WebSocket connection to 'ws://my-website/socket.io/?EIO=3&amp;transport=websocket&amp;sid=P8q_HoyfgJb0F75rAAAA' failed: Error during WebSocket handshake: Unexpected response code: 200
  polling-xhr.js:264 POST http://my-website/socket.io/?EIO=3&amp;transport=polling&amp;t=LnMfkAb&amp;sid=P8q_HoyfgJb0F75rAAAA 500 (Internal Server Error)
  </code></pre>
  
  <p>I followed all the instructions I could find about <code>web.config</code>:</p>
  
  <pre><code>&lt;system.webServer&gt;
      &lt;!--so that IIS websockets don't interfere with Node websockets--&gt;
      &lt;webSocket enabled="false" /&gt;
  
      &lt;!-- indicates that the hello.js file is a node.js application
        to be handled by the iisnode module --&gt;
      &lt;httpErrors existingReponse="PassThrough"&gt;&lt;/httpErrors&gt;
  
      &lt;handlers&gt;
        &lt;add name="iisnode" path="app.js" verb="*" modules="iisnode" /&gt;
      &lt;/handlers&gt;
  
      &lt;modules runAllManagedModulesForAllRequests="false"/&gt;
  
      &lt;rewrite&gt;
        &lt;rules&gt;
          &lt;!-- Don't interfere with requests for node-inspector debugging --&gt;
          &lt;rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true"&gt;
            &lt;match url=".+\.js\/debug[\/]?"/&gt;
          &lt;/rule&gt;
  
          &lt;!-- All other URLs are mapped to the Node.js application entry point --&gt;
          &lt;rule name="DynamicContent"&gt;
            &lt;match url="/*"/&gt;
            &lt;action type="Rewrite" url="app.js"/&gt;
          &lt;/rule&gt;
        &lt;/rules&gt;
      &lt;/rewrite&gt;
      &lt;directoryBrowse enabled="false"/&gt;
  
      &lt;!-- exclude node_modules directory and subdirectories from serving
             by IIS since these are implementation details of node.js applications --&gt;
  
      &lt;security&gt;
        &lt;requestFiltering&gt;
          &lt;hiddenSegments&gt;
            &lt;!--&lt;add segment="bin" /&gt;--&gt;
          &lt;/hiddenSegments&gt;
        &lt;/requestFiltering&gt;
      &lt;/security&gt;
    &lt;/system.webServer&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>And here is <code>app.js</code>:</p>
  
  <pre><code>'use strict';
  var debug = require('debug');
  var express = require('express');
  var path = require('path');
  var favicon = require('serve-favicon');
  var logger = require('morgan');
  var cookieParser = require('cookie-parser');
  var bodyParser = require('body-parser');
  
  var app = express();
  var server = require('http').Server(app);
  
  var routes = require('./routes/index');
  var users = require('./routes/users');
  var api = require('./routes/api')(server);
  
  // view engine setup
  app.set('views', path.join(__dirname, 'views'));
  app.set('view engine', 'pug');
  
  // uncomment after placing your favicon in /public
  //app.use(favicon(__dirname + '/public/favicon.ico'));
  app.use(logger('dev'));
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: false }));
  app.use(cookieParser());
  app.use(express.static(path.join(__dirname, 'public')));
  
  app.use('/', routes);
  app.use('/users', users);
  app.use('/api', api);
  
  // catch 404 and forward to error handler
  app.use(function (req, res, next) {
      var err = new Error('Not Found');
      err.status = 404;
      next(err);
  });
  
  // error handlers
  
  // development error handler
  // will print stacktrace
  if (app.get('env') === 'development') {
      app.use(function (err, req, res, next) {
          res.status(err.status || 500);
          res.render('error', {
              message: err.message,
              error: err
          });
      });
  }
  
  // production error handler
  // no stacktraces leaked to user
  app.use(function (err, req, res, next) {
      res.status(err.status || 500);
      res.render('error', {
          message: err.message,
          error: {}
      });
  });
  
  app.set('port', process.env.PORT || 3000);
  
  server.listen(app.get('port'), function () {
      debug('Express server listening on port ' + server.address().port);
  });
  </code></pre>
  
  <p>And <code>api.js</code>, which actually sets up the Socket.IO server:</p>
  
  <pre><code>module.exports = function (server)
  {
      var socketio = sio(server);
      var router = express.Router();
  
      var game = new model.Game();
  
      socketio.on("connection", (socket) =&gt;
      {
          console.log(`houston we have socket ${socket.id}`);
  
          try 
          {
              socket.on('message', function (data)
              {
                  console.log(`message: ${JSON.stringify(data)}`);
  
                  // my code here
              });
  
              socket.on("disconnect", (socket) =&gt;
              {
                  socketio.send("player.disconnected", { id: player.id });
  
                  // my code here
              });
          }
          catch (err)
          {
              // I put a breakpoint here, we never end up here
          }
  
          // debugger always makes it to the end of this function
      });
  }
  </code></pre>
  
  <p>When I step through this code with the debugger, it appears that execution makes it to the end of the connection handler, and then the server immediately restarts. <strong>What am I doing wrong, why is the socket being sent a 200 response?</strong></p>
  
  <p>I know that the error pages are encoded as 200 responses, but since they are being sent into a WebSocket connection, Chrome does not allow me to inspect them, instead just showing me "(Opcode -1)". Inspecting the attempt at a WebSocket connection using Fiddler shows that it was indeed the same error page described above, with HRESULT 0x6d.</p>