我是 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 上运行。我在这里完全迷失了。任何帮助将不胜感激。预先感谢。
我已经为所有被困在我这里的人解决了这个问题。
我已将以下代码添加到我的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
})
上面的代码解决了我最初的问题。