NextJS,Express,WebSocket 握手期间出错:意外响应代码:200
Posted
技术标签:
【中文标题】NextJS,Express,WebSocket 握手期间出错:意外响应代码:200【英文标题】:NextJS, Express, Error during WebSocket handshake: Unexpected response code: 200 【发布时间】:2019-09-23 00:52:27 【问题描述】:基本问题可以总结如下:当使用ws在Node中创建Websocket服务器时,服务器选项由快递服务器填充(如this示例),同时使用相同的快递服务器来处理NextJS 的路由(如this 示例),升级标头似乎没有正确解析。
express 不会将请求路由到 Websocket 服务器,而是发回 HTTP 200 OK 响应。
我已经到处搜索了这个问题的答案,可能是我根本不明白这个问题。 NextJS 的 github 上的 issue 提出了一个可能相关的问题。他们建议在本地 next.config.js 中设置 WebsocketPort 和 WebsocketProxyPort 选项,但是我尝试过没有用。
可以在下面找到相关服务器代码的最小示例。你可以找到完整的例子here。
const express = require('express')
const next = require('next')
const SocketServer = require('ws').Server;
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next( dev )
const handle = app.getRequestHandler()
app.prepare().then(() =>
const server = express()
server.all('*', (req, res) =>
return handle(req, res)
)
server.listen(port, err =>
if (err) throw err
console.log(`> Ready on http://localhost:$port`)
)
const wss = new SocketServer( server );
wss.on('connection', function connection(ws, request)
console.log('Client connected');
ws.on('close', () => console.log('Client disconnected'));
);
wss.on('error', function (error)
console.log(error);
);
setInterval(() =>
wss.clients.forEach((client) =>
client.send(new Date().toTimeString());
);
, 1000);
).catch(ex =>
console.error(ex.stack);
process.exit(1);
);
当然,预期的结果是连接到 websocket 服务器。相反,我收到以下错误:
WebSocket connection to 'ws://localhost:3000/' failed: Error during WebSocket handshake: Unexpected response code: 200
谁能在这里为我解释一下?
【问题讨论】:
您与 WS 的实际连接在哪里? IE。wss.connect...
.
嘿。在客户端 index.js 上找到该连接。使用 Websocket Web API 构造函数,详细 here,如:var HOST = location.origin.replace(/^http/, 'ws');
var ws = new WebSocket(HOST);
请注意,正确解析的请求正在到达服务器,它只是未能发出正确的响应。
【参考方案1】:
好的,经过更多的挖掘,我已经解决了这个问题。很简单,我试图向其提供 server = express()
对象的 ws.Server
对象严格来说并不是一个 http 服务器对象。但是,server.listen()
返回这样一个 http 服务器对象。在这样的对象上,我们可以侦听“升级”调用,我们可以将其传递给ws.Server
对象的handleUpgrade()
事件侦听器,通过它我们可以连接。我将更新我在问题中链接的示例,但相关代码如下:
app.prepare().then(() =>
const server = express()
server.all('*', (req, res) =>
return handle(req, res)
)
const wss = new SocketServer( server );
wss.on('connection', function connection(ws, request)
console.log('Client connected');
ws.on('close', () => console.log('Client disconnected'));
);
wss.on('error', function (error)
console.log(error);
);
let srv = server.listen(port, err =>
if (err) throw err
console.log(`> Ready on http://localhost:$port`)
)
srv.on('upgrade', function(req, socket, head)
wss.handleUpgrade(req, socket, head, function connected(ws)
wss.emit('connection', ws, req);
)
);
【讨论】:
以上是关于NextJS,Express,WebSocket 握手期间出错:意外响应代码:200的主要内容,如果未能解决你的问题,请参考以下文章
使用 NextJS + Express 在本地主机上进行 HTTPS
Router.push 没有重定向我; Nextjs 与 Express 服务器
在server.js中获取301重定向数据(Express / NextJS)