【问题标题】:URL generated by SocketIO in NodeJS running locally本地运行的 NodeJS 中 SocketIO 生成的 URL
【发布时间】:2021-02-28 03:51:48
【问题描述】:

我正在使用 Socket.IO 使用以下代码在 NodeJS 中本地运行 WebSocket 服务器:

import express = require('express');
const path = require('path');
import http = require('http');
import { Socket } from 'socket.io';


const app = express();
const server = http.createServer(app);
const socketio = require('socket.io')(server);

app.get('/', (req, res) => {
  res.send("Node Server is running");
});

server.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

socketio.on("connection", (socket: Socket) => {
  console.log(`connect ${socket.id}`);
  console.log(`connect ${socket.handshake.url}`);

  socket.on("disconnect", () => {
    console.log(`disconnect ${socket.id}`);
  });
});

使用Firecamp 之类的工具,我尝试在ws://localhost:3000 上建立连接,但无济于事。我最终使用 Socket.IO 客户端通过运行let socket = io() 从一个简单的网页进行连接。这似乎唯一的原因是因为该调用默认连接到为页面提供服务的主机,如here 所述。运行console.log(socket) 并查看输出,我最终发现engine 字段中的URL 是ws://localhost:3000/socket.io/?EIO=4&transport=websocket&sid=qerg3iHm3IKMOjdNAAAA。 我的问题是为什么 URL 如此复杂而不是简单的ws://localhost:3000?有没有更简单的方法来获取 URL 而不是通过开发工具访问它?

【问题讨论】:

标签: node.js websocket socket.io


【解决方案1】:

socket.io 服务器不接受通用 webSocket 连接。它只接受 socket.io 连接,因为 socket.io 在建立实际的 webSocket 连接之前会经过一层额外的准备工作(通过 http)。然后,它还在常规 webSocket 数据包格式之上添加了一层以支持其某些功能(例如消息名称)。

在默认配置下使用套接字客户端连接到 socket.io 服务器时,socket.io 首先向 socket.io 服务器发出一些常规的 http 请求,并通过这些 http 请求发送一些参数。在您的网址中:

 ws://localhost:3000/socket.io/?EIO=4&transport=websocket&sid=qerg3iHm3IKMOjdNAAAA

路径:

/socket.io/

是 socket.io 服务器寻找请求的路径,该请求以 socket.io 服务器为目的地。由于这是一个唯一的路径并且通常不被其他请求使用,这允许您在 socket.io 和其他 http 请求之间共享一个 http 服务器。事实上,这是部署 socket.io 服务器的常用方法(挂钩到您已经用于 http 请求的 http 服务器)。

事实上,/socket.io/socket.io.js 路径也由 socket.io 服务器提供服务,这将返回客户端的 socket.io.js 文件。因此,客户经常在他们的 HTML 文件中使用它:

<script src="/socket.io/socket.io.js"></script>

作为获取 socket.io 客户端代码的一种方式。您再次看到在所有与 socket.io 相关的 URL 上都使用了路径前缀 /socket.io

在您的原始网址中,您可以看到以下参数:

EIO=4                      // engine.io protocol version
transport=websocket        // desired transport once both sides agree
sid=qerg3iHm3IKMOjdNAAAA   // client identifier so the server knows which client this
                           // is before the actual webSocket connection is established

一旦双方同意连接看起来正常,那么客户端将与服务器建立 webSocket 连接。在 webSocket 连接被阻塞的情况下(被不支持它们的网络设备或阻塞它们),socket.io 将使用一种 http 轮询形式,它反复“轮询”服务器请求更多数据并尝试模拟连续连接。如果需要,客户端配置可以避免这种 http 轮询并直接转到 webSocket 连接,但如果连续的 webSocket 连接被阻止,您将放弃回退行为。

难道没有比通过开发工具访问更简单的方法来获取 URL 了吗?

不是真的。这个 URL 不是你必须知道的。 socket.io 客户端将为您构建此 URL。您只需指定 http://localhost:3000 作为您要连接的 URL,socket.io 客户端将向其中添加其他参数。

【讨论】:

  • @omarsharaki - 这回答了你的问题吗?如果是这样,您可以通过单击答案左侧的复选标记向社区表明这一点,这也将为您在此处获得一些声誉积分,以遵循正确的程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
  • 2020-03-27
  • 2013-03-09
  • 2014-07-19
  • 2013-10-11
  • 2018-03-19
相关资源
最近更新 更多