Node.js和React之间的Websocket握手错误

时间:2019-03-15 06:12:38

标签: node.js reactjs sockets websocket

我正在使用套接字编写应用程序,但似乎无法使初始握手工作。我在前端使用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开发者工具进行了检查,发现了这一点 enter image description here 在后端上,当记录请求接受键标头和响应标头时,我看到了以下内容: enter image description here

因此,除非我对这些标头有误,否则在从客户端到服务器的过程中,请求和响应接受键标头似乎会有所改变,反之亦然。这是怎么回事?还是我误会了正在发生的事情。为什么最初的握手确实不起作用?

2 个答案:

答案 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