无法连接到 Heroku 中的 websocket 服务器

Cannot connect to websocket server in Heroku

我在 Heroku 中有一个 Node.js 服务器 运行。它在其他方面运行良好,但客户端无法连接 websocket。

尝试连接到 websocket 时,第一个 http get 请求已完成,状态为 200 OK。服务器日志显示已发出路由“/”的请求,但之后没有任何内容。我不确定 websocket 服务器是不是 运行.

客户端代码(使用 React 构建):

this.ws = new WebSocket('wss://totentanz.herokuapp.com/');

服务器代码(使用 Express 和 Node.js 构建):

const express = require('express')
const app = express()
const port = process.env.PORT || 3002
const cors = require('cors')

app.use(express.json())
app.listen(port, () => {
  console.log(`Server started!`)
})

app.use(cors());

app.get('/', (req, res) => { res.send('Hello World') })

const { Server } = require('ws');
const wss = new Server({ server: app })
wss.on('connection', function connection(ws) {
 console.log("New connection")
...
})

错误信息:

WebSocket connection to 'wss://totentanz.herokuapp.com/' failed:
Event {isTrusted: true, type: "error", target: WebSocket, currentTarget: WebSocket, eventPhase: 2, …}
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: WebSocket {url: "wss://totentanz.herokuapp.com/", readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
defaultPrevented: false
eventPhase: 0
isTrusted: true
path: []
returnValue: true
srcElement: WebSocket {url: "wss://totentanz.herokuapp.com/", readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
target: WebSocket {url: "wss://totentanz.herokuapp.com/", readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
timeStamp: 1077.5999999940395
type: "error"
[[Prototype]]: Event

如果我尝试使用端口创建 WebSocket 服务器,它当然会失败,因为那时 http 和 ws 服务器都使用相同的端口。在 Heroku 中,不可能使用多个端口。

有没有办法确认ws服务器是运行?这可能是什么问题?

编辑: 我发现了问题,但我还不明白为什么会这样。这有效:

const server = express()
.use(cors)
.use(express.json())
.listen(PORT, () => console.log(`Listening on ${PORT}`))

这不是:

const server = express()
server.use(cors)
server.use(express.json())
server.listen(PORT, () => console.log(`Listening on ${PORT}`))

我找到了一个名为 express-ws 的模块。它解决了这个问题。现在工作代码如下所示:

const express = require('express');
const PORT = process.env.PORT || 3000;
const cors = require('cors')
const app = express()
const expressWs = require('express-ws')(app);

app
  .use(express.json())
  .listen(PORT, () => console.log(`Listening on ${PORT}`));
app.use(cors())
app.get('/', (req, res) => { res.send('Hello World') })
...
app.ws('/', function (ws, req) {
  ws.on('message', function (rawdata) {
...
expressWs.getWss().clients.forEach(function each(client) {
...
})
}})