Ошибка WSS WebSockets во время рукопожатия WebSocket: Неожиданный код ответа: 200 - PullRequest
0 голосов
/ 24 апреля 2020

пытается развернуть мое приложение с помощью ws на Heroku. На моей локальной машине все работало хорошо, но после развертывания на 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 Ответ

1 голос
/ 25 апреля 2020

Конструктор ws Server не принимает параметр 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 c и по ошибке выдает ошибку. Он сообщает «статус 200», потому что сервер ответил с кодом состояния HTTP 200 - даже если это был несчастный случай.

Правильный способ присоединить ws Server к HTTP сервер может:

  1. Передать http.Server ( not express приложение) в ws.Server server параметр

    var app = express(),
        server = http.createServer(app),
        wss = new ws.Server({ server });
    
    server.listen(process.env.PORT);
    
  2. Или вручную подключите upgrade слушателя к вашему http.Server и позвоните wss.handleUpgrade.

...