我正在使用套接字编写应用程序,但似乎无法使初始握手工作。我在前端使用WebSockets + React,在PORT 8080上运行,而Node.js套接字在后端在PORT 5000上运行。 前端握手是通过我的组件完成的,就像这样:
componentDidMount(){
this.socket = new WebSocket('ws://localhost:5000', ['json']);
this.socket.onerror = err => {
console.log(err)
}
this.socket.onmessage = e => {
let res = JSON.parse(e.data);
console.log(e, res);
let copyArr = [...this.state.message]
copyArr.push(res);
this.setState({
message: copyArr
});
}
}
在我的节点服务器上,做:
const server = http.createServer();
server.on('upgrade', (req, socket) => {
if(req.headers['upgrade'] !== "websocket"){
socket.end('HTTP/1.1 400 Bad Request');
return;
}
const acceptKey = req.headers['sec-websocket-key'];
const acceptHash = generateValue(acceptKey);
console.log('accepkey', acceptKey, 'hash', acceptHash);
const resHeaders = [ 'HTTP/1.1 101 Web Socket Protocol Handshake', 'Upgrade: WebSocket', 'Connection: Upgrade', `Sec-WebSocket-Accept: ${acceptHash}` ];
console.log(resHeaders);
let protocols = req.headers['sec-websocket-protocol'];
protocols = !protocols ? [] : protocols.split(',').map(name => name.trim());
if(protocols.includes('json')){
console.log('json here');
resHeaders.push(`Sec-WebSocket-Protocol: json`);
}
socket.write(resHeaders.join('\r\n') + '\r\n\r\n');
})
function generateValue(key){
return crypto
.createHash('sha1')
.update(key + '258EAFA5-E914–47DA-95CA-C5AB0DC85B11', 'binary')
.digest('base64');
}
当我的React组件挂载时,它尝试建立初始握手,但失败,并显示错误:WebSocket connection to 'ws://localhost:5000/' failed: Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value
。我已经使用Chrome开发者工具进行了检查,发现了这一点
在后端上,当记录请求接受键标头和响应标头时,我看到了以下内容:
因此,除非我对这些标头有误,否则在从客户端到服务器的过程中,请求和响应接受键标头似乎会有所改变,反之亦然。这是怎么回事?还是我误会了正在发生的事情。为什么最初的握手确实不起作用?
答案 0 :(得分:0)
我认为generateValue
函数是错误的,您根据docs传递了binary
作为inputData编码,它是latin1
的关键字。但是我相信它是UTF-8
字符串,而不是latin1
,所以结果哈希是错误的。因此,请尝试使用update(key + '258EAFA5-E914–47DA-95CA-C5AB0DC85B11', 'utf8')
甚至没有第二个utf8
参数,因为它是默认参数。
答案 1 :(得分:0)
在–
之后的-
中有一个破折号258EAFA5-E914–47DA-95CA-C5AB0DC85B11
而不是连字符E914
因此,将其替换为连字符-
参考https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-WebSocket-Accept