在IIS 8.5之后使用Express-WS关闭WebSocket时是否停止ECONNRESET?

问题描述

我正在使用express-ws将Websocket端点添加到我的Web应用程序中,并正在从浏览器编码测试回显客户端。当我直接连接到节点服务器时,连接将完全关闭。但是,当应用程序部署在IIS反向代理之后时,客户端启动的close()会在节点服务器中导致ECONNRESET。

我必须将WebSocket模块添加到IIS,因为没有它,ARR无法将协议传递到服务器,并且我最终遇到以下错误Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value

这是我的代码

服务器

app.ws(conf.routeNames.main,function (ws,req) {
  ws.on('message',function (msg) {
    wslog.info(msg);
    ws.send(msg);
  });
  ws.on('close',function(reason,desc) {
    wslog.info(`${reason} closed connection (${desc})`);
    ws.close();
  })
  ws.on('error',(err)=>{
    wslog.info(`ws-error ${err}`);
  });
});

也在服务器上:

  function onConnection (socket) {
    reqsPerSocket.set(socket,0)
    socket.once('close',() => reqsPerSocket.delete(socket))
    socket.on('error',function(e){
      wslog.error(`Inbound connection error: ${e.message} from ${socket.remoteAddress}`);
    })
  }

客户

/*
 * ws-client.js
 *
 * Provides a barebones websocket client.
 * 
 */

wsClient = (function ($) {

  var ws; 
  var clientID;
  var tripCounter = 0;
  var clientLog;
  var mint;

  var wsURL = 'wss://{envHost}/wsecho/';

  function wsClient(h,a,c) {

    clientLog = c;
    clientID = a;

    wURL = wsURL.replace(/{envHost}/,h);
    ws = new WebSocket(wURL);

    ws.onopen = onopen;
    ws.onmessage = onMessage;
    ws.onclose = onClose;
    ws.onerror = onError;

    window.addEventListener('beforeunload',imDoneWitdisGuy);
  }

  function onError(err) {
    clientLog.log(clientID +': '+err.message);
  }

  function onMessage(event) {
    clientLog.log(event.data);
    tripCounter++;
  }

  function onopen() {
    clientLog.log('Onopen - sending '+tripCounter);
    ws.send(clientID + ' ' + tripCounter );

    // This is where we ping server.
    mint = setInterval( function () {
      if( ws.readyState == 1 ) {
        clientLog.log('Sending '+tripCounter );
        ws.send(clientID +' '+tripCounter);
      }
    },60000);
  }

  function imDoneWitdisGuy() {
    clientLog.log('Window closing.');
    clearInterval(mint);
    if( ws.readyState == 1 ) {
      ws.close(1000,clientID + ' Window closing.');
    }
  }

  function onClose(event) {
    clientLog.log('Closing socket after ' + tripCounter + ' messages ' + (event.reason?'reason = '+event.reason:''));
    clearInterval(mint);
  }
  
  return wsClient; 
  
})(jQuery);

IIS反向代理规则:

        <rule name="WSe" enabled="true" stopProcessing="true">
          <match url="wsecho/(.*)" />
          <action type="Rewrite" url="https://localhost:9081/{R:1}" />
        </rule>

这是我在两面都得到的输出

客户端日志:

2020-11-11T10:44:05.655 -05:00: Onopen - sending 0
2020-11-11T10:44:05.854 -05:00: 88771 0
2020-11-11T10:44:26.829 -05:00: Window closing.
2020-11-11T10:44:26.871 -05:00: Closing socket after 1 messages reason = 88771 Window closing.

服务器日志:

2020-11-11T10:44:05-05:00 info: 88771 0
2020-11-11T10:44:26-05:00 error: Inbound connection error: read ECONNRESET from undefined
2020-11-11T10:44:26-05:00 error: Inbound connection error: read ECONNRESET from undefined
2020-11-11T10:44:26-05:00 info: 1000 closed connection (88771 Window closing.)

如果我在没有IIS反向代理的情况下运行,则除了没有发生ECONNRESET之外,其他都一样。如此看来,IIS既传递了close消息又终止了套接字? (尚不确定为什么会有2。)

如何配置IIS以允许干净的close()

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)