Ошибка подключения к веб-сокету: возвращает 101, но не обновляется - PullRequest
1 голос
/ 20 июня 2020

Я настраиваю несколько веб-сокетов, используя библиотеку ws. Я изо всех сил пытаюсь настроить авторизацию с помощью рукопожатия. Я добавил маршрут к нашему серверу для обновления до соединения через веб-сокет, например:

    .get(
      '/chat',
    authorisationFunction,
    upgradeConnection,
    ),

Сервер веб-сокета:

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 3030 }); 

Это функция upgradeConnection, которая запускается при авторизации успешно:

const upgradeConnection = (request, socket, head) => {
  return wss.handleUpgrade(request, request.socket, head, function done(ws) {
    return wss.emit('connection', ws, request);
  });
}

У меня также есть функция, которая прослушивает сообщения:

function webSocketsServer() {
  wss.on('connection', (ws, request, client) => {
    ws.on('message', message => {
      ws.send(message);
    });
  });
}

Создается соединение, и с моего сервера я получаю этот ответ:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: QyVvqadEcI1+ALka6j2pLKBkfNQ=

но тут же на моем клиенте я получаю сообщение об ошибке «Соединение WebSocket с 'ws: // localhost: 3000 / chat' не удалось: недопустимый заголовок кадра».

Но когда я обхожу рукопожатие и подключаюсь непосредственно на мой сервер websocket, я могу успешно отправлять сообщения. Ошибка только на клиенте, а не на серверной части. Что мне не хватает?

1 Ответ

1 голос
/ 21 июня 2020

Я не уверен на 100%, что это единственный способ, но он может помочь, поэтому я публикую его. Основываясь на этом ответе , я бы выбрал go для сервера, который использует один и тот же порт для соединений http и websocket. Вы можете добиться этого следующим образом:

const { createServer } = require('http')
const ws = require('ws')
const express = require('express')

const app = express()

const server = createServer(app)

app.get('/', (req, res) => {
  res.send('I am a normal http server response')
})

const wsServer = new ws.Server({
  server,
  path: '/websocket-path',
})

wsServer.on('connection', (connection) => {
  connection.send('I am a websocket response')
})

server.listen(3030, () => {
  console.log(`Server is now running on http://localhost:3030`)
  console.log(`Websocket is now running on ws://localhost:3030/<websocket-path>`)
})

Итак, ваш сервер прослушивает порт 3030 для обычных HTTP-запросов. Если он получает запрос на подключение к веб-сокету по пути '/ websocket-path', он передается обработчику подключения ws, и оттуда вы можете перейти к go.

...