WebSocket连接到'ws:// localhost:3000 /'失败:连接在收到握手响应之前closures

我参加了一个我的朋友制作的游戏,并希望通过在WebRTC和Websockets之间的对等点之间发送按键数据来跨浏览器进行游戏。 但是,我在控制台中得到这个错误:

WebSocket连接到'ws:// localhost:3000 /'失败:连接在收到握手响应之前closures

我的服务器文件有以下几行:

'use strict'; const express = require('express'); const SocketServer = require('ws').Server; const path = require('path'); const PORT = process.env.PORT || 3000; const INDEX = path.join(__dirname, 'index.html'); const server = express(); server.use(express.static(path.join(__dirname, 'lib'))); server.use('/assets', express.static(path.join(__dirname, 'assets'))); server.listen(PORT, () => console.log(`Listening on ${ PORT }`)); const wss = new SocketServer({ server }); var users = {}; let usernames = []; wss.on('connection', function(connection) { connection.on('message', function(message) { var data; try { data = JSON.parse(message); } catch (e) { console.log("Invalid JSON"); data = {}; } switch (data.type) { case "login": console.log("User logged", data.name); if(users[data.name]) { sendTo(connection, { type: "login", success: false }); } else { users[data.name] = connection; connection.name = data.name; usernames.push(data.name); sendTo(connection, { type: "login", success: true, users: usernames }); } break; case "offer": console.log("Sending offer to: ", data.name); var conn = users[data.name]; if(conn != null) { connection.otherName = data.name; sendTo(conn, { type: "offer", offer: data.offer, name: connection.name }); } break; case "answer": console.log("Sending answer to: ", data.name); var conn = users[data.name]; if(conn != null) { connection.otherName = data.name; sendTo(conn, { type: "answer", answer: data.answer }); } break; case "candidate": console.log("Sending candidate to:",data.name); var conn = users[data.name]; if(conn != null) { sendTo(conn, { type: "candidate", candidate: data.candidate }); } break; case "leave": console.log("Disconnecting from", data.name); var conn = users[data.name]; conn.otherName = null; if(conn != null) { sendTo(conn, { type: "leave" }); } break; default: sendTo(connection, { type: "error", message: "Command not found: " + data.type }); break; } }); 

而连接的客户端看起来如下所示:

 const Game = require("./game"); const GameView = require("./game_view"); var HOST = location.origin.replace(/^http/, 'ws'); console.log('host: ', HOST); console.log(process.env.PORT); document.addEventListener("DOMContentLoaded", function() { const connection = new WebSocket(HOST); ..... 

这是错误发生的地方,这是我得到的错误:

 bubbles : false cancelBubble : false cancelable : false composed : false currentTarget : WebSocket defaultPrevented : false eventPhase : 0 isTrusted : true path : Array(0) returnValue : true srcElement : WebSocket target : WebSocket timeStamp : 213.01500000000001 type : "error" __proto__ : Event 

我不太熟悉服务器端编程,并试图理解。 我试图查找这个问题,但似乎是各种不同的事情可以导致这一点。 如果你想看到你可以看到的版本库,并自己尝试(使用webpack): SlidingWarfare回购

混乱从这里开始:

 const server = express(); 

express函数并不真正返回一个服务器,它返回一个应用程序。 通常,用于此的variables是app ,但这当然不过是惯例(即不是要求)。

但是,将应用程序传递到WS服务器时会成为问题:

 const wss = new SocketServer({ server }); 

这是因为SocketServer需要一个HTTP服务器实例,哪个server不是。

这里有一个修复,不重命名你的variables:

 let httpServer = server.listen(PORT, () => console.log(`Listening on ${ PORT }`)); ... const wss = new SocketServer({ server : httpServer }); 

(因为当你在Express实例上调用.listen()时,它将返回一个HTTP服务器实例)

使用variables命名约定是这样的:

 const app = express(); app.use(express.static(path.join(__dirname, 'lib'))); app.use('/assets', express.static(path.join(__dirname, 'assets'))); let server = app.listen(PORT, () => console.log(`Listening on ${ PORT }`)); const wss = new SocketServer({ server });