WebSocket 握手期间的 WebSockets WS 错误:意外的响应代码:200

Posted

技术标签:

【中文标题】WebSocket 握手期间的 WebSockets WS 错误:意外的响应代码:200【英文标题】:WebSockets WS error during WebSocket handshake: Unexpected response code: 200 【发布时间】:2020-04-24 19:52:10 【问题描述】:

尝试在 Heroku 上使用 ws 部署我的应用程序。在我的本地机器上一切正常,但在 Heroku 上部署后,我收到握手错误,响应状态为 200

这是我的服务器代码:

const WebSocketServer = require('ws').Server;
const moment = require('moment');
const app = require('./app');

const wss = new WebSocketServer( app );

const connections = new Set();

wss.on('connection', (ws) => 
  connections.add(ws);

  ws.on('message', (message) => 
    const time = moment(new Date()).format('HH:mm');
    const messageData = 
      time,
      message,
    ;
    for (const connection of connections) 
      connection.send(JSON.stringify(messageData));
    
  );

  ws.on('close', () => 
    connections.delete(ws);
  );
 );

还有我的客户代码:

const HOST = location.origin.replace(/^http/, 'ws');
const ws = new WebSocket(HOST);

ws.onmessage = (e) => 
  //
;

messageForm.addEventListener('submit', (e) => 
  //
  ws.send(message);
  //
);

【问题讨论】:

【参考方案1】:

ws Server constructor 不接受app 选项,因此您的wss 实际上并没有在听任何东西。如果这个确切的代码确实在本地工作,那么很难看出如何。

由于您尝试连接到与您的页面共享相同路径的 WebSocket,因此 express 应用最终会处理 WebSocket 客户端请求并使用您的页面 html 进行响应。

你的 HTTP 交换最终看起来像这样——首先浏览器加载页面:

GET /page HTTP/1.1
Accept: text/html
…

HTTP/1.1 200 OK
Content-Type: text/html

<html> …

然后页面发出new WebSocket(…),产生WebSocket升级请求:

GET /page HTTP/1.1
Connection: Upgrade
Upgrade: websocket
…

HTTP/1.1 200 OK
Content-Type: text/html

<html> …

您应该明白为什么会失败:这不是 WebSocket 响应。 Express 认为该请求是一个常规的 HTTP GET 请求,并使用您页面的 HTML 进行响应。浏览器的 WebSocket 实现看到不符合 WebSocket 规范的响应并正确地抛出错误。它报告“状态 200”,因为服务器确实响应了 HTTP 200 状态代码——即使这是一个意外。

将 ws Server 附加到 HTTP 服务器的正确方法是:

    http.Server不是快递应用)传递给ws.Serverserver选项

    var app = express(),
        server = http.createServer(app),
        wss = new ws.Server( server );
    
    server.listen(process.env.PORT);
    

    或手动将upgrade 监听器附加到您的http.Server 并调用wss.handleUpgrade

【讨论】:

以上是关于WebSocket 握手期间的 WebSockets WS 错误:意外的响应代码:200的主要内容,如果未能解决你的问题,请参考以下文章

websocket失败:WebSocket握手期间出错:意外响应代码:400

使用 Maven,WebSocket 连接失败:WebSocket 握手期间出错:意外响应代码:404

Django:WebSocket 握手期间出错:意外的响应代码:500

WebSocket 握手期间出错:意外的响应代码:302

WebSocket 连接到“ws://localhost:8080/”失败:WebSocket 握手期间出错:意外响应代码:404

WebSocket 握手期间出错:意外的响应代码:500