WebSocket连接失败:在WebSocket握手期间出错:意外的响应代码:400

我正在尝试将Socket.io与Angular集成在一起,并且在从客户端到服务器端进行连接时遇到困难。 我已经看过其他相关的问题,但我的问题是本地发生的,所以没有中间的Web服务器。

这是我的服务器代码的样子:

const app = express(); const server = http.createServer(app); const io = require('socket.io').listen(server); io.on('connection', function(socket) { socket.emit('greet', { hello: 'Hey, Mr.Client!' }); socket.on('respond', function(data) { console.log(data); }); socket.on('disconnect', function() { console.log('Socket disconnected'); }); }); 

我使用Grunt按以下顺序加载客户端JavaScript文件:

 dist: { src: [ public/bower_components/angular/angular.min.js, ... public/bower_components/socket.io-client/dist/socket.io.min.js, public/bower_components/angular-socket-io/socket.min.js, ... ] } 

然后在我的控制器中:

 function MyController($scope) { let socket = io.connect(window.location.href); socket.connect('http://localhost:3000'); socket.on('greet', function(data) { console.log(data); socket.emit('respond', { message: 'Hello to you too, Mr.Server!' }); }); ... } 

在实际使用btford/angular-socket-io库之前,我想确保能够正确连接,但是在控制台中出现以下错误:

套接字io连接错误消息

有趣的是,如果我重新启动Node.js服务器进程,它确实设法发送消息,但使用轮询而不是websocket。

重启后

轮询消息

我尝试了socket.connect调用各种不同的选项,但没有任何工作。

任何帮助,将不胜感激。


更新(30/12/2016):

我只是意识到websockets正在部分工作。 我在Chrome开发人员控制台中看到了一个101交换协议请求。 但是我看到的唯一帧是engine.io协议包(ping,pong)。 但是,我的应用程序套接字消息仍然回落到投票出于某种原因…

engine.io包

问题解决了! 我只是想出了如何解决这个问题,但我仍然想知道这是否是正常的行为。

看起来,即使Websocket连接build立正确(由101交换协议请求指示),它仍然默认为长轮询。 修复如同将此选项添加到Socket.io连接函数一样简单:

 {transports: ['websocket']} 

所以代码最终看起来像这样:

 const app = express(); const server = http.createServer(app); var io = require('socket.io')(server); io.on('connection', function(socket) { console.log('connected socket!'); socket.on('greet', function(data) { console.log(data); socket.emit('respond', { hello: 'Hey, Mr.Client!' }); }); socket.on('disconnect', function() { console.log('Socket disconnected'); }); }); 

并在客户端:

 var socket = io('ws://localhost:3000', {transports: ['websocket']}); socket.on('connect', function () { console.log('connected!'); socket.emit('greet', { message: 'Hello Mr.Server!' }); }); socket.on('respond', function (data) { console.log(data); }); 

消息现在显示为帧:

工作的websockets

这个Github问题指出了我正确的方向。 感谢所有帮助过的人!

从通过Socket.IO发送的消息来判断socket.emit('greet', { hello: 'Hey, Mr.Client!' }); ,似乎你正在使用hackathon-starter样板。 如果是这样,问题可能是express-status-monitor模块正在创build自己的socket.io实例,如下所示: https : //github.com/RafalWilinski/express-status-monitor#using-module-with-socketio-在项目

你可以:

  1. 删除该模块
  2. 当你创build像以下这样的expressStatusMonitor实例时, expressStatusMonitor你的socket.io实例和端口作为websocket

     const server = require('http').Server(app); const io = require('socket.io')(server); ... app.use(expressStatusMonitor({ websocket: io, port: app.get('port') })); 

在你的控制器中,你使用的是httpscheme,但是我认为你应该使用wsscheme,就像你使用websocket一样。 尝试在连接function中使用ws://localhost:3000

我认为你应该把客户端的origins定义如下:

 //server.js const socket = require('socket.io'); const app = require('express')(); const server = app.listen('port'); const io = socket().attach(server); io.origins("your_domain:port www.your_domain:port your_IP:port your_domain:*") io.on('connection', (socket) => { console.log('connected a new client'); }); //client.js var socket = io('ws://:port');