关于node.js:Node JS Socket IO-如何确保正在使用websocket?

NodesJS SocketIO - How can I make sure websockets are being used?

背景

  • 我正在努力将Unity应用程序连接到SocketIO应用程序
  • Unity使用的是SocketIO插件(仅使用websocket,不轮询/ xhr)

要从Unity连接到我的websocket,我正在使用ws://localhost:3000/socket.io/?EIO=4&transport=websocket。 如果我通过浏览器点击该链接,则会看到以下内容:

1
{"code":3,"message":"Bad request"}

此时,我用io.set('transports', ['websocket']);强制了NodeJS应用程序的websockets,但随后我的应用程序停止了工作。

我如何确保websocket可用于NodeJS + SocketIO?

app.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res){
        res.sendFile(__dirname + '/index.html');
});

var server = app.listen(3000, function () {
   var host = server.address().address
   var port = server.address().port
});
var io = require('socket.io').listen(server);
//io.set('transports', ['websocket']);

...

设定


您似乎同时使用了WebSocket和Socket.io,这可能会导致冲突。您应该选择一个并坚持下去。如果您确定您的客户端将使用WebSocket,则完全不需要使用Socket.io。只需使用WebSocket广告,您就不必担心AJAX,彗星,长时间轮询的解决方法。

这是使用WebSocket的示例服务器端代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var path = require('path');
var app = require('express')();
var ws = require('express-ws')(app);
app.get('/', (req, res) => {
  console.error('express connection');
  res.sendFile(path.join(__dirname, 'ws.html'));
});
app.ws('/', (s, req) => {
  console.error('websocket connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => s.send('message from server', ()=>{}), 1000*t);
});
app.listen(3001, () => console.error('listening on http://localhost:3001/'));
console.error('websocket example');

如您所见,这非常简单。

有关更多信息,请参见这些答案中的代码示例:

  • socket.io和websockets之间的区别
  • Socket.io 1.x:仅使用WebSockets?
  • NodeJS Websocket(ws)回调


默认情况下,socket.io客户端以http轮询开始,然后在几次轮询事务后切换到webSocket。据我所知,服务器上的任何操作都不会改变客户端的行为,因此,如果您不支持服务器上的轮询并且不更改客户端的配置方式,则初始的socket.io客户端连接将不起作用。但是,您可以在客户端和服务器上都进行相应的更改,以强制socket.io仅使用webSocket,即使从一开始就如此。如果您正在查看网络跟踪,则仍会看到一个初始HTTP连接,因为所有的webSocket连接都以HTTP连接开头,但随后该HTTP连接被"升级"为webSocket协议。

您可以在此处查看有关如何配置客户端和服务器以仅使用webSocket的所有详细信息:Socket.io 1.x:仅使用WebSockets?简而言之,您将需要在客户端中进行连接:

1
var socket = io({transports: ['websocket'], upgrade: false});