如何通过 Socket.io 连接到 Nodejs 上的 http 服务器来处理升级请求。抛出错误 - “连接”标头丢失

问题描述 投票:0回答:1

我是 websockets 和 socket.io 的新手,我创建了一个在 HTTP 服务器上运行的 Web 应用程序。我使用了express.js作为中间件和node_modules提供的http模块。我的主机提供商 (a2hosting) 为我提供了 SSL 证书和密钥,从而允许我在 HTTPS 上运行我的网站。 问题是当socket.io请求升级时,连接被拒绝并抛出错误:“WebSocket握手期间出错:‘连接’标头丢失”

我的server.js看起来像这样:

const express = require('express')

const app = express()

const server = require('http').createServer(app)

const io = require('socket.io')(server)

const parser = require('body-parser')

const compression = require('compression')

const handlebars = require('express-handlebars')

const hbs = handlebars.create({ extname: 'hbs' })

app.use(compression())

app.use(parser.urlencoded({ extended: true }))

app.use(parser.json())

app.engine('hbs', hbs.engine)

app.set('view engine', 'hbs')

app.use(express.static('res'))

// some app.get() and app.post() routings goes here

io.on('connect',socket => { socket related events handlers code goes here })

// a2hosting provides dynamic ports to hosted apps so there is no port number inside app.listen()

app.listen()

我的client.hbs有基本的html代码和包含socket.io的脚本标签

<script src="/socket.io/socket.io.js"></script>

我的client.js看起来像

const socket = io()

socket.on('someEvent',someData=>{doSomething})

socket.on('otherEvent',otherData=>{doSomethingElse})

socket.emit('eventName',dataToBeSent)

// other JS functions

我尝试添加以下代码,按照https://nodejs.org/api/http.html#http_event_upgrade

的建议
server.on('upgrade', (req, socket, head) => {
  socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
               'Upgrade: WebSocket\r\n' +
               'Connection: Upgrade\r\n' +
               '\r\n')

  socket.pipe(socket); // echo back
})

添加此代码引发了另一个错误WebSocket 握手:缺少“Sec-WebSocket-Accept”标头

a2hosting 可在 cloudlinux 提供的 phusion guest 上运行。我在这里完全迷失了。任何帮助将不胜感激。预先感谢。

node.js express websocket socket.io
1个回答
0
投票

我已经为所有被困在我这里的人解决了这个问题。

我已将以下代码添加到我的server.js

// After const app = express()

const cors = require('cors')

app.use(cors())

并编辑了我的“升级”事件侦听器,如下所示:

// After const server = require('http').createServer(app)

server.on('upgrade', (req, socket, head) => {

    let key = req.header('Sec-WebSocket-Key')
    let conc = key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'

    let hash = crypto.createHash('sha1')

    hash.update(conc)

    let encoded_data = hash.digest('base64')

    socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
        'Upgrade: websocket\r\n' +
        'Connection: Upgrade\r\n' +
        `Sec-WebSocket-Accept: ${encoded_data}\r\n` +
        '\r\n')

    socket.pipe(socket) // echo back
})

上面的代码解决了我最初的问题。

© www.soinside.com 2019 - 2024. All rights reserved.