【问题标题】:NodesJS SocketIO - How can I make sure websockets are being used?NodeJS SocketIO - 我如何确保正在使用 websocket?
【发布时间】:2017-08-21 17:04:46
【问题描述】:

背景

  • 我正在将 Unity 应用程序连接到 SocketIO 应用程序
  • Unity 正在使用 SocketIO 插件(仅使用 websockets,不使用 polling/xhr)

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

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

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

问题

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

代码

app.js

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']);

...

设置

  • Ubuntu@14.04
  • NodeJS@0.10.25
  • SocketI@O1.7.3
  • express@4.15.2

【问题讨论】:

  • 你为什么使用 ws 和 socket.io ?似乎你应该只需要一个,如果你只想要 websockets 使用 ws ?

标签: node.js websocket socket.io


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    您似乎同时使用了 WebSocket 和 Socket.io,这可能会导致冲突。你应该选择一个并坚持下去。如果您确定您的客户端将使用 WebSocket,那么根本不需要使用 Socket.io。只需使用 WebSocket 广告,您将不得不担心 AJAX、彗星、长轮询的变通方法。

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

    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');
    

    如您所见,这非常简单。

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

    【讨论】:

    • 不错的清单!我会同意,除非我过去的浏览器不接受 ws (iOs
    • 即使使用--harmony 标志,我在运行它时也遇到了问题。卡在 class 关键字 WebSocket.js:31 上 - 你在 es2015 中使用 babel-cli 吗?
    • @Jacksonkr 如果您的 Node 不支持 class 关键字,那么您必须使用非常过时且不受支持的 Node 版本,至少 0.12 或更早版本。见node.green/#ES2015-functions-class当前版本为7.x,8.0即将发布。
    • 为了获取和更新节点(当前为 7.7.4),我必须先 wget -qO- https://deb.nodesource.com/setup_7.x | sudo bash - 然后 sudo apt-get install nodejs
    猜你喜欢
    • 2013-12-03
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 2018-12-22
    相关资源
    最近更新 更多