是否可以将 UDP 与 socket.io 一起使用?

Posted

技术标签:

【中文标题】是否可以将 UDP 与 socket.io 一起使用?【英文标题】:Is it possible to use UDP with socket.io? 【发布时间】:2016-04-01 20:43:21 【问题描述】:

我正在开发一款游戏,我听说 UDP 更适合实时游戏。我知道 socket.io 使用 TCP,并且想知道是否有某种方法可以将其切换到 UDP。我尝试查找它,但只找到了 2012 年左右的帖子,其中说 UDP 仅在浏览器中处于试验阶段。

【问题讨论】:

【参考方案1】:

从标准浏览器,这是不可能的。

从浏览器客户端,socket.io 使用httpwebSocket 传输。 httpwebSocket 都是 TCP 连接,而不是 UDP 连接。所以浏览器客户端 socket.io 不使用 UDP - 它使用 TCP。

据我所知,可从常规 html 页面 javascript 访问的浏览器不支持标准 UDP,因此您甚至无法真正尝试构建自己的使用 UDP 的层。

关于该主题的其他参考资料:

Why Can't I Send UDP Packets From a Browser

Reading from udp port in browser

Chrome Supports TCP and UDP Sockets

Write a chrome extension to support UDP in browser

How to send a UDP Packet with Web RTC - Javascript?

How to talk to UDP sockets with HTML5?

Reading from udp port in browser

在某些情况下,当您希望数据包尽快交付时,UDP 可能是一种理想的传输方式,但如果不能立即交付,则丢弃它。这有时在游戏甚至视频流中很有用,其中下一个数据包将仅包含下一个更新,因此如果前一个数据包没有通过,那么没什么大不了的,您宁愿不让 TCP 尝试重新传输丢失的数据包。但是,浏览器不支持在网页 Javascript 中使用 UDP 协议。

如果您想从浏览器连接到 UDP 设备或服务器,则必须使用某种代理,以便您的浏览器代码可以通过 TCP(http 或 webSocket)与代理通信,然后代理可以处理与设备的实际 UDP 通信。


可以使用来自 node.js 或其他一些非浏览器平台的 socket.io 库,并为 socket.io 编写您自己的 UDP 传输插件,该插件基于您平台中的本机 UDP 支持构建。我相信 socket.io 有一些可插拔的传输,因此您可以尝试制作自己的传输,然后配置客户端和服务器以使用该传输。这在浏览器中是不可能的(没有在浏览器中安装本机代码插件),因为浏览器中没有可以构建传输的底层 UDP 支持,但在 node.js 等非浏览器环境中,您可以这样做。

【讨论】:

为什么还要投反对票?投反对票的,请解释一下。如果你有合法的牛肉,我会纠正我的答案。浏览器中的 Socket.io 不在 UDP 上运行。这根本不存在,因为浏览器不支持任何类型的 UDP 传输。如果您因为被斋月的回答误导而投反对票,那么请阅读该答案下方的 cmets,因为该答案非常具有误导性,并且没有提供该问题所要问的内容。【参考方案2】:

在这种情况下使用本质上是 UDP 的 webRTC 可能是个好主意。

【讨论】:

这个答案似乎没有直接回答问题。 虽然我同意当我写这篇文章时我正在考虑 socket.io,但我仍然感谢@TensorVortex 提到基于其他响应 socket.io 没有的替代方法(假设它有效)似乎完全支持UDP。【参考方案3】:

虽然已经回答了这个问题,但我想指出,有一些方法可以使用 UDP 实现 socket.io。例如,dgram 完全符合您的要求。

This is 使用 dgram 的 socket.io + UDP 教程。

更新

Alexandre Lacheze 开发了一个 node.js package 将 UDP 带入浏览器。它还支持socket.io。所以答案现在有点过时了。

更新 2: 原来它只是一个模拟的UDP。不是在浏览器上运行的实际 UDP 协议。

【讨论】:

我想你可能对这里描述的内容感到困惑。您的第一个参考完全在 node.js 上运行,而不是在浏览器中运行。这只是 node.js 中 UDP 支持的示例代码。因此,这与浏览器中的 UDP 无关。您的第二个参考是模拟类似 UDP 的接口,但通过 webSocket 或 socket.io 传输(它们都是 TCP 连接)运行它。所以这是一个在浏览器中工作的模拟 UDP 接口,但实际的传输是 TCP,而不是 UDP。因此,它们都没有在浏览器中运行实际的 UDP 协议。 第二个示例,当与基于服务器的代理一起使用时,将在 socket.io 上运行的模拟 UDP 转换为实际 UDP,可用于从浏览器与 UDP 服务通信,但不应该被愚弄认为这是在浏览器中使用 UDP,因为人们通常希望将 UDP 用于响应式、低延迟的游戏 - 但事实并非如此。它很聪明,可能有一些有趣的用途,但这不是这个问题所问的,即如何通过 UDP 运行 socket.io。仅供参考,第二个选项中的接口名称是SimUDP,模拟UDP。 所以,总结一下。您的答案中没有任何内容显示通过 UDP 运行的 socket.io 实现,因此您的部分答案完全不受支持。而且,您关于 Alexandre Lacheze 的包将 UDP 带入浏览器的断言也是错误的。它为浏览器带来了一个模拟的类似 UDP 的接口,该接口实际上是通过 TCP 运行的。

以上是关于是否可以将 UDP 与 socket.io 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以将 React Native 与 socket.io 结合使用

如何将 socket.io 与 graphql 订阅一起使用?

将 pm2 的集群模块与 socket.io 和 socket.io-redis 一起使用

Socket.io 是不是与 Heroku 一起工作?

将 Socket.io 与 Sequelize 一起使用

我可以将 Socket.io 与 Spring-boot 一起使用吗?