webSocket将无法连接到IISNode

时间:2017-05-30 00:13:42

标签: node.js express iis websocket socket.io

我正在使用Express在Node.js中开发一个Web服务器,我想特别使用Socket.io作为WebSockets。但是,托管我的应用程序的服务器环境是IIS,并且无法更改。 IIS版本足够高,启用了WebSockets,并安装了iisnode v0.2.21。 Express正常工作,提供我的页面和内容,但WebSockets没有。相反,websocket连接以HTTP 200状态而不是预期的HTTP 101重复终止,从而阻止WebSockets工作。我已经为我想到的IIS_IUSRS组设置了权限。

有时我会收到一个错误页面,其中包含以下文字:

HRESULT: 0x6d
HTTP status: 500
HTTP subStatus: 1013
HTTP reason: Internal Server Error

我还没有尝试使用SSL或Secure WebSockets,因此我在StackOverflow上找到的其他解决方案似乎不适用。

我在客户端遇到这样的错误:

polling-xhr.js:264 POST http://my-website/socket.io/?EIO=3&transport=polling&t=LnMfjZr&sid=LQjLpiGwsN3K-gNPAAAA 500 (Internal Server Error)
polling-xhr.js:264 POST http://my-website/socket.io/?EIO=3&transport=polling&t=LnMfjaC&sid=LQjLpiGwsN3K-gNPAAAA 500 (Internal Server Error)
websocket.js:112 WebSocket connection to 'ws://my-website/socket.io/?EIO=3&transport=websocket&sid=P8q_HoyfgJb0F75rAAAA' failed: Error during WebSocket handshake: Unexpected response code: 200
polling-xhr.js:264 POST http://my-website/socket.io/?EIO=3&transport=polling&t=LnMfkAb&sid=P8q_HoyfgJb0F75rAAAA 500 (Internal Server Error)

我按照了web.config找到的所有说明:

<system.webServer>
    <!--so that IIS websockets don't interfere with Node websockets-->
    <webSocket enabled="false" />

    <!-- indicates that the hello.js file is a node.js application
      to be handled by the iisnode module -->
    <httpErrors existingReponse="PassThrough"></httpErrors>

    <handlers>
      <add name="iisnode" path="app.js" verb="*" modules="iisnode" />
    </handlers>

    <modules runAllManagedModulesForAllRequests="false"/>

    <rewrite>
      <rules>
        <!-- Don't interfere with requests for node-inspector debugging -->
        <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
          <match url=".+\.js\/debug[\/]?"/>
        </rule>

        <!-- All other URLs are mapped to the Node.js application entry point -->
        <rule name="DynamicContent">
          <match url="/*"/>
          <action type="Rewrite" url="app.js"/>
        </rule>
      </rules>
    </rewrite>
    <directoryBrowse enabled="false"/>

    <!-- exclude node_modules directory and subdirectories from serving
           by IIS since these are implementation details of node.js applications -->

    <security>
      <requestFiltering>
        <hiddenSegments>
          <!--<add segment="bin" />-->
        </hiddenSegments>
      </requestFiltering>
    </security>
  </system.webServer>
</configuration>

这是app.js

'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);
});

api.js,它实际上设置了Socket.IO服务器:

module.exports = function (server)
{
    var socketio = sio(server);
    var router = express.Router();

    var game = new model.Game();

    socketio.on("connection", (socket) =>
    {
        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) =>
            {
                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
    });
}

当我使用调试器逐步执行此代码时,似乎执行使其到达连接处理程序的末尾,然后服务器立即重新启动。 我做错了什么,为什么套接字被发送200响应?

我知道错误页面被编码为200个响应,但由于它们被发送到WebSocket连接,因此Chrome不允许我检查它们,而只是向我显示“(操作码-1)”。使用Fiddler检查WebSocket连接的尝试表明它确实是上面描述的错误页面,HRESULT为0x6d。

0 个答案:

没有答案